LCOV - code coverage report
Current view: top level - test/unittests/compiler - machine-operator-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 136 140 97.1 %
Date: 2017-10-20 Functions: 73 85 85.9 %

          Line data    Source code
       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/machine-operator.h"
       6             : #include "src/compiler/opcodes.h"
       7             : #include "src/compiler/operator.h"
       8             : #include "src/compiler/operator-properties.h"
       9             : #include "test/unittests/test-utils.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : namespace compiler {
      14             : namespace machine_operator_unittest {
      15             : 
      16             : #if GTEST_HAS_COMBINE
      17             : 
      18             : template <typename T>
      19         800 : class MachineOperatorTestWithParam
      20             :     : public TestWithZone,
      21             :       public ::testing::WithParamInterface<
      22             :           ::testing::tuple<MachineRepresentation, T> > {
      23             :  protected:
      24             :   MachineRepresentation representation() const {
      25         250 :     return ::testing::get<0>(B::GetParam());
      26             :   }
      27         468 :   const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
      28             : 
      29             :  private:
      30             :   typedef ::testing::WithParamInterface<
      31             :       ::testing::tuple<MachineRepresentation, T> > B;
      32             : };
      33             : 
      34             : 
      35             : const MachineRepresentation kMachineReps[] = {MachineRepresentation::kWord32,
      36             :                                               MachineRepresentation::kWord64};
      37             : 
      38             : 
      39             : const MachineType kMachineTypesForAccess[] = {
      40             :     MachineType::Float32(), MachineType::Float64(),  MachineType::Int8(),
      41             :     MachineType::Uint8(),   MachineType::Int16(),    MachineType::Uint16(),
      42             :     MachineType::Int32(),   MachineType::Uint32(),   MachineType::Int64(),
      43             :     MachineType::Uint64(),  MachineType::AnyTagged()};
      44             : 
      45             : 
      46             : const MachineRepresentation kRepresentationsForStore[] = {
      47             :     MachineRepresentation::kFloat32, MachineRepresentation::kFloat64,
      48             :     MachineRepresentation::kWord8,   MachineRepresentation::kWord16,
      49             :     MachineRepresentation::kWord32,  MachineRepresentation::kWord64,
      50             :     MachineRepresentation::kTagged};
      51             : 
      52             : 
      53             : // -----------------------------------------------------------------------------
      54             : // Load operator.
      55             : 
      56             : 
      57             : typedef MachineOperatorTestWithParam<LoadRepresentation>
      58             :     MachineLoadOperatorTest;
      59             : 
      60             : 
      61       15874 : TEST_P(MachineLoadOperatorTest, InstancesAreGloballyShared) {
      62          22 :   MachineOperatorBuilder machine1(zone(), representation());
      63          22 :   MachineOperatorBuilder machine2(zone(), representation());
      64          66 :   EXPECT_EQ(machine1.Load(GetParam()), machine2.Load(GetParam()));
      65          22 : }
      66             : 
      67             : 
      68       15874 : TEST_P(MachineLoadOperatorTest, NumberOfInputsAndOutputs) {
      69          22 :   MachineOperatorBuilder machine(zone(), representation());
      70         132 :   const Operator* op = machine.Load(GetParam());
      71             : 
      72          44 :   EXPECT_EQ(2, op->ValueInputCount());
      73          44 :   EXPECT_EQ(1, op->EffectInputCount());
      74          44 :   EXPECT_EQ(1, op->ControlInputCount());
      75          44 :   EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
      76             : 
      77          44 :   EXPECT_EQ(1, op->ValueOutputCount());
      78          44 :   EXPECT_EQ(1, op->EffectOutputCount());
      79          44 :   EXPECT_EQ(0, op->ControlOutputCount());
      80          22 : }
      81             : 
      82             : 
      83       15874 : TEST_P(MachineLoadOperatorTest, OpcodeIsCorrect) {
      84          22 :   MachineOperatorBuilder machine(zone(), representation());
      85          44 :   EXPECT_EQ(IrOpcode::kLoad, machine.Load(GetParam())->opcode());
      86          22 : }
      87             : 
      88             : 
      89       15874 : TEST_P(MachineLoadOperatorTest, ParameterIsCorrect) {
      90          22 :   MachineOperatorBuilder machine(zone(), representation());
      91          66 :   EXPECT_EQ(GetParam(),
      92           0 :             OpParameter<LoadRepresentation>(machine.Load(GetParam())));
      93          22 : }
      94             : 
      95             : 
      96      297303 : INSTANTIATE_TEST_CASE_P(
      97             :     MachineOperatorTest, MachineLoadOperatorTest,
      98             :     ::testing::Combine(::testing::ValuesIn(kMachineReps),
      99             :                        ::testing::ValuesIn(kMachineTypesForAccess)));
     100             : 
     101             : 
     102             : // -----------------------------------------------------------------------------
     103             : // Store operator.
     104             : 
     105             : 
     106         224 : class MachineStoreOperatorTest
     107             :     : public MachineOperatorTestWithParam<
     108             :           ::testing::tuple<MachineRepresentation, WriteBarrierKind> > {
     109             :  protected:
     110         168 :   StoreRepresentation GetParam() const {
     111             :     return StoreRepresentation(
     112             :         ::testing::get<0>(
     113             :             MachineOperatorTestWithParam< ::testing::tuple<
     114             :                 MachineRepresentation, WriteBarrierKind> >::GetParam()),
     115             :         ::testing::get<1>(
     116             :             MachineOperatorTestWithParam< ::testing::tuple<
     117         336 :                 MachineRepresentation, WriteBarrierKind> >::GetParam()));
     118             :   }
     119             : };
     120             : 
     121             : 
     122       15898 : TEST_P(MachineStoreOperatorTest, InstancesAreGloballyShared) {
     123          28 :   MachineOperatorBuilder machine1(zone(), representation());
     124          28 :   MachineOperatorBuilder machine2(zone(), representation());
     125          56 :   EXPECT_EQ(machine1.Store(GetParam()), machine2.Store(GetParam()));
     126          28 : }
     127             : 
     128             : 
     129       15898 : TEST_P(MachineStoreOperatorTest, NumberOfInputsAndOutputs) {
     130          28 :   MachineOperatorBuilder machine(zone(), representation());
     131         168 :   const Operator* op = machine.Store(GetParam());
     132             : 
     133          56 :   EXPECT_EQ(3, op->ValueInputCount());
     134          56 :   EXPECT_EQ(1, op->EffectInputCount());
     135          56 :   EXPECT_EQ(1, op->ControlInputCount());
     136          56 :   EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
     137             : 
     138          56 :   EXPECT_EQ(0, op->ValueOutputCount());
     139          56 :   EXPECT_EQ(1, op->EffectOutputCount());
     140          56 :   EXPECT_EQ(0, op->ControlOutputCount());
     141          28 : }
     142             : 
     143             : 
     144       15898 : TEST_P(MachineStoreOperatorTest, OpcodeIsCorrect) {
     145          28 :   MachineOperatorBuilder machine(zone(), representation());
     146          56 :   EXPECT_EQ(IrOpcode::kStore, machine.Store(GetParam())->opcode());
     147          28 : }
     148             : 
     149             : 
     150       15898 : TEST_P(MachineStoreOperatorTest, ParameterIsCorrect) {
     151          28 :   MachineOperatorBuilder machine(zone(), representation());
     152          56 :   EXPECT_EQ(GetParam(),
     153           0 :             OpParameter<StoreRepresentation>(machine.Store(GetParam())));
     154          28 : }
     155             : 
     156             : 
     157      370971 : INSTANTIATE_TEST_CASE_P(
     158             :     MachineOperatorTest, MachineStoreOperatorTest,
     159             :     ::testing::Combine(
     160             :         ::testing::ValuesIn(kMachineReps),
     161             :         ::testing::Combine(::testing::ValuesIn(kRepresentationsForStore),
     162             :                            ::testing::Values(kNoWriteBarrier,
     163             :                                              kFullWriteBarrier))));
     164             : #endif
     165             : 
     166             : // -----------------------------------------------------------------------------
     167             : // Pure operators.
     168             : 
     169             : struct PureOperator {
     170             :   const Operator* (MachineOperatorBuilder::*constructor)();
     171             :   char const* const constructor_name;
     172             :   int value_input_count;
     173             :   int control_input_count;
     174             :   int value_output_count;
     175             : };
     176             : 
     177             : 
     178           0 : std::ostream& operator<<(std::ostream& os, PureOperator const& pop) {
     179         304 :   return os << pop.constructor_name;
     180             : }
     181             : 
     182             : const PureOperator kPureOperators[] = {
     183             : #define PURE(Name, value_input_count, control_input_count, value_output_count) \
     184             :   {                                                                            \
     185             :     &MachineOperatorBuilder::Name, #Name, value_input_count,                   \
     186             :         control_input_count, value_output_count                                \
     187             :   }
     188             :     PURE(Word32And, 2, 0, 1),                 // --
     189             :     PURE(Word32Or, 2, 0, 1),                  // --
     190             :     PURE(Word32Xor, 2, 0, 1),                 // --
     191             :     PURE(Word32Shl, 2, 0, 1),                 // --
     192             :     PURE(Word32Shr, 2, 0, 1),                 // --
     193             :     PURE(Word32Sar, 2, 0, 1),                 // --
     194             :     PURE(Word32Ror, 2, 0, 1),                 // --
     195             :     PURE(Word32Equal, 2, 0, 1),               // --
     196             :     PURE(Word32Clz, 1, 0, 1),                 // --
     197             :     PURE(Word64And, 2, 0, 1),                 // --
     198             :     PURE(Word64Or, 2, 0, 1),                  // --
     199             :     PURE(Word64Xor, 2, 0, 1),                 // --
     200             :     PURE(Word64Shl, 2, 0, 1),                 // --
     201             :     PURE(Word64Shr, 2, 0, 1),                 // --
     202             :     PURE(Word64Sar, 2, 0, 1),                 // --
     203             :     PURE(Word64Ror, 2, 0, 1),                 // --
     204             :     PURE(Word64Equal, 2, 0, 1),               // --
     205             :     PURE(Int32Add, 2, 0, 1),                  // --
     206             :     PURE(Int32Sub, 2, 0, 1),                  // --
     207             :     PURE(Int32Mul, 2, 0, 1),                  // --
     208             :     PURE(Int32MulHigh, 2, 0, 1),              // --
     209             :     PURE(Int32Div, 2, 1, 1),                  // --
     210             :     PURE(Uint32Div, 2, 1, 1),                 // --
     211             :     PURE(Int32Mod, 2, 1, 1),                  // --
     212             :     PURE(Uint32Mod, 2, 1, 1),                 // --
     213             :     PURE(Int32LessThan, 2, 0, 1),             // --
     214             :     PURE(Int32LessThanOrEqual, 2, 0, 1),      // --
     215             :     PURE(Uint32LessThan, 2, 0, 1),            // --
     216             :     PURE(Uint32LessThanOrEqual, 2, 0, 1),     // --
     217             :     PURE(Int64Add, 2, 0, 1),                  // --
     218             :     PURE(Int64Sub, 2, 0, 1),                  // --
     219             :     PURE(Int64Mul, 2, 0, 1),                  // --
     220             :     PURE(Int64Div, 2, 1, 1),                  // --
     221             :     PURE(Uint64Div, 2, 1, 1),                 // --
     222             :     PURE(Int64Mod, 2, 1, 1),                  // --
     223             :     PURE(Uint64Mod, 2, 1, 1),                 // --
     224             :     PURE(Int64LessThan, 2, 0, 1),             // --
     225             :     PURE(Int64LessThanOrEqual, 2, 0, 1),      // --
     226             :     PURE(Uint64LessThan, 2, 0, 1),            // --
     227             :     PURE(Uint64LessThanOrEqual, 2, 0, 1),     // --
     228             :     PURE(ChangeFloat32ToFloat64, 1, 0, 1),    // --
     229             :     PURE(ChangeFloat64ToInt32, 1, 0, 1),      // --
     230             :     PURE(ChangeFloat64ToUint32, 1, 0, 1),     // --
     231             :     PURE(ChangeInt32ToInt64, 1, 0, 1),        // --
     232             :     PURE(ChangeUint32ToFloat64, 1, 0, 1),     // --
     233             :     PURE(ChangeUint32ToUint64, 1, 0, 1),      // --
     234             :     PURE(TruncateFloat64ToFloat32, 1, 0, 1),  // --
     235             :     PURE(TruncateInt64ToInt32, 1, 0, 1),      // --
     236             :     PURE(Float32Abs, 1, 0, 1),                // --
     237             :     PURE(Float32Add, 2, 0, 1),                // --
     238             :     PURE(Float32Sub, 2, 0, 1),                // --
     239             :     PURE(Float32Mul, 2, 0, 1),                // --
     240             :     PURE(Float32Div, 2, 0, 1),                // --
     241             :     PURE(Float32Sqrt, 1, 0, 1),               // --
     242             :     PURE(Float32Equal, 2, 0, 1),              // --
     243             :     PURE(Float32LessThan, 2, 0, 1),           // --
     244             :     PURE(Float32LessThanOrEqual, 2, 0, 1),    // --
     245             :     PURE(Float32Neg, 1, 0, 1),                // --
     246             :     PURE(Float64Abs, 1, 0, 1),                // --
     247             :     PURE(Float64Add, 2, 0, 1),                // --
     248             :     PURE(Float64Sub, 2, 0, 1),                // --
     249             :     PURE(Float64Mul, 2, 0, 1),                // --
     250             :     PURE(Float64Div, 2, 0, 1),                // --
     251             :     PURE(Float64Mod, 2, 0, 1),                // --
     252             :     PURE(Float64Sqrt, 1, 0, 1),               // --
     253             :     PURE(Float64Max, 2, 0, 1),                // --
     254             :     PURE(Float64Min, 2, 0, 1),                // --
     255             :     PURE(Float64Equal, 2, 0, 1),              // --
     256             :     PURE(Float64LessThan, 2, 0, 1),           // --
     257             :     PURE(Float64LessThanOrEqual, 2, 0, 1),    // --
     258             :     PURE(LoadStackPointer, 0, 0, 1),          // --
     259             :     PURE(Float64ExtractLowWord32, 1, 0, 1),   // --
     260             :     PURE(Float64ExtractHighWord32, 1, 0, 1),  // --
     261             :     PURE(Float64InsertLowWord32, 2, 0, 1),    // --
     262             :     PURE(Float64InsertHighWord32, 2, 0, 1),   // --
     263             :     PURE(Float64Neg, 1, 0, 1),                // --
     264             : #undef PURE
     265             : };
     266             : 
     267             : 
     268           2 : class MachinePureOperatorTest : public TestWithZone {
     269             :  protected:
     270             :   MachineRepresentation word_type() {
     271             :     return MachineType::PointerRepresentation();
     272             :   }
     273             : };
     274             : 
     275             : 
     276       13159 : TEST_F(MachinePureOperatorTest, PureOperators) {
     277          17 :   TRACED_FOREACH(MachineRepresentation, machine_rep1, kMachineReps) {
     278           2 :     MachineOperatorBuilder machine1(zone(), machine_rep1);
     279          34 :     TRACED_FOREACH(MachineRepresentation, machine_rep2, kMachineReps) {
     280           4 :       MachineOperatorBuilder machine2(zone(), machine_rep2);
     281        2740 :       TRACED_FOREACH(PureOperator, pop, kPureOperators) {
     282         304 :         const Operator* op1 = (machine1.*pop.constructor)();
     283         304 :         const Operator* op2 = (machine2.*pop.constructor)();
     284         304 :         EXPECT_EQ(op1, op2);
     285        1520 :         EXPECT_EQ(pop.value_input_count, op1->ValueInputCount());
     286         912 :         EXPECT_EQ(pop.control_input_count, op1->ControlInputCount());
     287         912 :         EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount());
     288         304 :       }
     289           4 :     }
     290           2 :   }
     291           1 : }
     292             : 
     293             : 
     294             : // Optional operators.
     295             : 
     296             : struct OptionalOperatorEntry {
     297             :   const OptionalOperator (MachineOperatorBuilder::*constructor)();
     298             :   MachineOperatorBuilder::Flag enabling_flag;
     299             :   char const* const constructor_name;
     300             :   int value_input_count;
     301             :   int control_input_count;
     302             :   int value_output_count;
     303             : };
     304             : 
     305             : 
     306           0 : std::ostream& operator<<(std::ostream& os, OptionalOperatorEntry const& pop) {
     307           3 :   return os << pop.constructor_name;
     308             : }
     309             : 
     310             : const OptionalOperatorEntry kOptionalOperators[] = {
     311             : #define OPTIONAL_ENTRY(Name, value_input_count, control_input_count,       \
     312             :                        value_output_count)                                 \
     313             :   {                                                                        \
     314             :     &MachineOperatorBuilder::Name, MachineOperatorBuilder::k##Name, #Name, \
     315             :         value_input_count, control_input_count, value_output_count         \
     316             :   }
     317             :     OPTIONAL_ENTRY(Float64RoundDown, 1, 0, 1),      // --
     318             :     OPTIONAL_ENTRY(Float64RoundTruncate, 1, 0, 1),  // --
     319             :     OPTIONAL_ENTRY(Float64RoundTiesAway, 1, 0, 1),  // --
     320             : #undef OPTIONAL_ENTRY
     321             : };
     322             : 
     323             : 
     324           2 : class MachineOptionalOperatorTest : public TestWithZone {
     325             :  protected:
     326             :   MachineRepresentation word_rep() {
     327             :     return MachineType::PointerRepresentation();
     328             :   }
     329             : };
     330             : 
     331             : 
     332       13159 : TEST_F(MachineOptionalOperatorTest, OptionalOperators) {
     333          28 :   TRACED_FOREACH(OptionalOperatorEntry, pop, kOptionalOperators) {
     334          54 :     TRACED_FOREACH(MachineRepresentation, machine_rep1, kMachineReps) {
     335          12 :       MachineOperatorBuilder machine1(zone(), machine_rep1, pop.enabling_flag);
     336         102 :       TRACED_FOREACH(MachineRepresentation, machine_rep2, kMachineReps) {
     337             :         MachineOperatorBuilder machine2(zone(), machine_rep2,
     338          24 :                                         pop.enabling_flag);
     339          12 :         const Operator* op1 = (machine1.*pop.constructor)().op();
     340          12 :         const Operator* op2 = (machine2.*pop.constructor)().op();
     341          12 :         EXPECT_EQ(op1, op2);
     342          60 :         EXPECT_EQ(pop.value_input_count, op1->ValueInputCount());
     343          36 :         EXPECT_EQ(pop.control_input_count, op1->ControlInputCount());
     344          36 :         EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount());
     345             : 
     346          12 :         MachineOperatorBuilder machine3(zone(), word_rep());
     347          24 :         EXPECT_TRUE((machine1.*pop.constructor)().IsSupported());
     348          24 :         EXPECT_FALSE((machine3.*pop.constructor)().IsSupported());
     349          12 :       }
     350           6 :     }
     351           3 :   }
     352           1 : }
     353             : 
     354             : 
     355             : // -----------------------------------------------------------------------------
     356             : // Pseudo operators.
     357             : 
     358             : 
     359             : typedef TestWithZone MachineOperatorTest;
     360             : 
     361             : 
     362       13159 : TEST_F(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
     363           1 :   MachineOperatorBuilder machine(zone(), MachineRepresentation::kWord32);
     364           2 :   EXPECT_EQ(machine.Word32And(), machine.WordAnd());
     365           2 :   EXPECT_EQ(machine.Word32Or(), machine.WordOr());
     366           2 :   EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
     367           2 :   EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
     368           2 :   EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
     369           2 :   EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
     370           2 :   EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
     371           2 :   EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
     372           2 :   EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
     373           2 :   EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
     374           2 :   EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
     375           2 :   EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
     376           2 :   EXPECT_EQ(machine.Uint32Div(), machine.UintDiv());
     377           2 :   EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
     378           2 :   EXPECT_EQ(machine.Uint32Mod(), machine.UintMod());
     379           2 :   EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
     380           2 :   EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
     381           1 : }
     382             : 
     383             : 
     384       13159 : TEST_F(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
     385           1 :   MachineOperatorBuilder machine(zone(), MachineRepresentation::kWord64);
     386           2 :   EXPECT_EQ(machine.Word64And(), machine.WordAnd());
     387           2 :   EXPECT_EQ(machine.Word64Or(), machine.WordOr());
     388           2 :   EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
     389           2 :   EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
     390           2 :   EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
     391           2 :   EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
     392           2 :   EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
     393           2 :   EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
     394           2 :   EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
     395           2 :   EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
     396           2 :   EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
     397           2 :   EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
     398           2 :   EXPECT_EQ(machine.Uint64Div(), machine.UintDiv());
     399           2 :   EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
     400           2 :   EXPECT_EQ(machine.Uint64Mod(), machine.UintMod());
     401           2 :   EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
     402           2 :   EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
     403           1 : }
     404             : 
     405             : }  // namespace machine_operator_unittest
     406             : }  // namespace compiler
     407             : }  // namespace internal
     408        7893 : }  // namespace v8

Generated by: LCOV version 1.10