LCOV - code coverage report
Current view: top level - test/unittests/compiler - machine-operator-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 131 133 98.5 %
Date: 2019-04-17 Functions: 39 53 73.6 %

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

Generated by: LCOV version 1.10