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

Generated by: LCOV version 1.10