Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/compiler/common-operator.h"
      6 
      7 #include <limits>
      8 
      9 #include "src/compiler/operator-properties-inl.h"
     10 #include "src/test/test-utils.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 namespace compiler {
     15 
     16 
     17 // -----------------------------------------------------------------------------
     18 // Shared operators.
     19 
     20 
     21 namespace {
     22 
     23 struct SharedOperator {
     24   const Operator* (CommonOperatorBuilder::*constructor)();
     25   IrOpcode::Value opcode;
     26   Operator::Properties properties;
     27   int value_input_count;
     28   int effect_input_count;
     29   int control_input_count;
     30   int effect_output_count;
     31   int control_output_count;
     32 };
     33 
     34 
     35 std::ostream& operator<<(std::ostream& os, const SharedOperator& fop) {
     36   return os << IrOpcode::Mnemonic(fop.opcode);
     37 }
     38 
     39 
     40 const SharedOperator kSharedOperators[] = {
     41 #define SHARED(Name, properties, value_input_count, effect_input_count,        \
     42                control_input_count, effect_output_count, control_output_count) \
     43   {                                                                            \
     44     &CommonOperatorBuilder::Name, IrOpcode::k##Name, properties,               \
     45         value_input_count, effect_input_count, control_input_count,            \
     46         effect_output_count, control_output_count                              \
     47   }
     48     SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 1),
     49     SHARED(End, Operator::kFoldable, 0, 0, 1, 0, 0),
     50     SHARED(Branch, Operator::kFoldable, 1, 0, 1, 0, 2),
     51     SHARED(IfTrue, Operator::kFoldable, 0, 0, 1, 0, 1),
     52     SHARED(IfFalse, Operator::kFoldable, 0, 0, 1, 0, 1),
     53     SHARED(Throw, Operator::kFoldable, 1, 0, 1, 0, 1),
     54     SHARED(Return, Operator::kNoProperties, 1, 1, 1, 1, 1),
     55     SHARED(ControlEffect, Operator::kPure, 0, 0, 1, 1, 0)
     56 #undef SHARED
     57 };
     58 
     59 
     60 class CommonSharedOperatorTest
     61     : public TestWithZone,
     62       public ::testing::WithParamInterface<SharedOperator> {};
     63 
     64 }  // namespace
     65 
     66 
     67 TEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) {
     68   const SharedOperator& sop = GetParam();
     69   CommonOperatorBuilder common1(zone());
     70   CommonOperatorBuilder common2(zone());
     71   EXPECT_EQ((common1.*sop.constructor)(), (common2.*sop.constructor)());
     72 }
     73 
     74 
     75 TEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
     76   CommonOperatorBuilder common(zone());
     77   const SharedOperator& sop = GetParam();
     78   const Operator* op = (common.*sop.constructor)();
     79 
     80   EXPECT_EQ(sop.value_input_count, OperatorProperties::GetValueInputCount(op));
     81   EXPECT_EQ(sop.effect_input_count,
     82             OperatorProperties::GetEffectInputCount(op));
     83   EXPECT_EQ(sop.control_input_count,
     84             OperatorProperties::GetControlInputCount(op));
     85   EXPECT_EQ(
     86       sop.value_input_count + sop.effect_input_count + sop.control_input_count,
     87       OperatorProperties::GetTotalInputCount(op));
     88 
     89   EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
     90   EXPECT_EQ(sop.effect_output_count,
     91             OperatorProperties::GetEffectOutputCount(op));
     92   EXPECT_EQ(sop.control_output_count,
     93             OperatorProperties::GetControlOutputCount(op));
     94 }
     95 
     96 
     97 TEST_P(CommonSharedOperatorTest, OpcodeIsCorrect) {
     98   CommonOperatorBuilder common(zone());
     99   const SharedOperator& sop = GetParam();
    100   const Operator* op = (common.*sop.constructor)();
    101   EXPECT_EQ(sop.opcode, op->opcode());
    102 }
    103 
    104 
    105 TEST_P(CommonSharedOperatorTest, Properties) {
    106   CommonOperatorBuilder common(zone());
    107   const SharedOperator& sop = GetParam();
    108   const Operator* op = (common.*sop.constructor)();
    109   EXPECT_EQ(sop.properties, op->properties());
    110 }
    111 
    112 
    113 INSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
    114                         ::testing::ValuesIn(kSharedOperators));
    115 
    116 
    117 // -----------------------------------------------------------------------------
    118 // Other operators.
    119 
    120 
    121 namespace {
    122 
    123 class CommonOperatorTest : public TestWithZone {
    124  public:
    125   CommonOperatorTest() : common_(zone()) {}
    126   virtual ~CommonOperatorTest() {}
    127 
    128   CommonOperatorBuilder* common() { return &common_; }
    129 
    130  private:
    131   CommonOperatorBuilder common_;
    132 };
    133 
    134 
    135 const int kArguments[] = {1, 5, 6, 42, 100, 10000, kMaxInt};
    136 
    137 const float kFloat32Values[] = {
    138     std::numeric_limits<float>::min(), -1.0f, -0.0f, 0.0f, 1.0f,
    139     std::numeric_limits<float>::max()};
    140 
    141 }  // namespace
    142 
    143 
    144 TEST_F(CommonOperatorTest, Float32Constant) {
    145   TRACED_FOREACH(float, value, kFloat32Values) {
    146     const Operator* op = common()->Float32Constant(value);
    147     EXPECT_FLOAT_EQ(value, OpParameter<float>(op));
    148     EXPECT_EQ(0, OperatorProperties::GetValueInputCount(op));
    149     EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
    150     EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
    151     EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
    152     EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
    153   }
    154 }
    155 
    156 
    157 TEST_F(CommonOperatorTest, ValueEffect) {
    158   TRACED_FOREACH(int, arguments, kArguments) {
    159     const Operator* op = common()->ValueEffect(arguments);
    160     EXPECT_EQ(arguments, OperatorProperties::GetValueInputCount(op));
    161     EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
    162     EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
    163     EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
    164     EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
    165   }
    166 }
    167 
    168 
    169 TEST_F(CommonOperatorTest, Finish) {
    170   TRACED_FOREACH(int, arguments, kArguments) {
    171     const Operator* op = common()->Finish(arguments);
    172     EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
    173     EXPECT_EQ(arguments, OperatorProperties::GetEffectInputCount(op));
    174     EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
    175     EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
    176     EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
    177     EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
    178   }
    179 }
    180 
    181 }  // namespace compiler
    182 }  // namespace internal
    183 }  // namespace v8
    184