V8 Project
machine-operator-unittest.cc
Go to the documentation of this file.
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 
7 #include "testing/gtest-support.h"
8 
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12 
13 #if GTEST_HAS_COMBINE
14 
15 // TODO(bmeurer): Find a new home for these.
16 inline std::ostream& operator<<(std::ostream& os, const MachineType& type) {
17  OStringStream ost;
18  ost << type;
19  return os << ost.c_str();
20 }
21 inline std::ostream& operator<<(std::ostream& os,
22  const WriteBarrierKind& write_barrier_kind) {
23  OStringStream ost;
24  ost << write_barrier_kind;
25  return os << ost.c_str();
26 }
27 
28 
29 template <typename T>
30 class MachineOperatorTestWithParam
31  : public ::testing::TestWithParam< ::testing::tuple<MachineType, T> > {
32  protected:
33  MachineType type() const { return ::testing::get<0>(B::GetParam()); }
34  const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
35 
36  private:
37  typedef ::testing::TestWithParam< ::testing::tuple<MachineType, T> > B;
38 };
39 
40 
41 namespace {
42 
43 const MachineType kMachineReps[] = {kRepWord32, kRepWord64};
44 
45 
46 const MachineType kMachineTypes[] = {
51 
52 } // namespace
53 
54 
55 // -----------------------------------------------------------------------------
56 // Load operator.
57 
58 
59 typedef MachineOperatorTestWithParam<LoadRepresentation>
60  MachineLoadOperatorTest;
61 
62 
63 TEST_P(MachineLoadOperatorTest, InstancesAreGloballyShared) {
64  MachineOperatorBuilder machine1(type());
65  MachineOperatorBuilder machine2(type());
66  EXPECT_EQ(machine1.Load(GetParam()), machine2.Load(GetParam()));
67 }
68 
69 
70 TEST_P(MachineLoadOperatorTest, NumberOfInputsAndOutputs) {
71  MachineOperatorBuilder machine(type());
72  const Operator* op = machine.Load(GetParam());
73 
78 
82 }
83 
84 
85 TEST_P(MachineLoadOperatorTest, OpcodeIsCorrect) {
86  MachineOperatorBuilder machine(type());
87  EXPECT_EQ(IrOpcode::kLoad, machine.Load(GetParam())->opcode());
88 }
89 
90 
91 TEST_P(MachineLoadOperatorTest, ParameterIsCorrect) {
92  MachineOperatorBuilder machine(type());
93  EXPECT_EQ(GetParam(),
94  OpParameter<LoadRepresentation>(machine.Load(GetParam())));
95 }
96 
97 
98 INSTANTIATE_TEST_CASE_P(MachineOperatorTest, MachineLoadOperatorTest,
99  ::testing::Combine(::testing::ValuesIn(kMachineReps),
100  ::testing::ValuesIn(kMachineTypes)));
101 
102 
103 // -----------------------------------------------------------------------------
104 // Store operator.
105 
106 
107 class MachineStoreOperatorTest
108  : public MachineOperatorTestWithParam<
109  ::testing::tuple<MachineType, WriteBarrierKind> > {
110  protected:
111  StoreRepresentation GetParam() const {
112  return StoreRepresentation(
113  ::testing::get<0>(MachineOperatorTestWithParam<
114  ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()),
115  ::testing::get<1>(MachineOperatorTestWithParam<
116  ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()));
117  }
118 };
119 
120 
121 TEST_P(MachineStoreOperatorTest, InstancesAreGloballyShared) {
122  MachineOperatorBuilder machine1(type());
123  MachineOperatorBuilder machine2(type());
124  EXPECT_EQ(machine1.Store(GetParam()), machine2.Store(GetParam()));
125 }
126 
127 
128 TEST_P(MachineStoreOperatorTest, NumberOfInputsAndOutputs) {
129  MachineOperatorBuilder machine(type());
130  const Operator* op = machine.Store(GetParam());
131 
132  EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
133  EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
135  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
136 
137  EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
140 }
141 
142 
143 TEST_P(MachineStoreOperatorTest, OpcodeIsCorrect) {
144  MachineOperatorBuilder machine(type());
145  EXPECT_EQ(IrOpcode::kStore, machine.Store(GetParam())->opcode());
146 }
147 
148 
149 TEST_P(MachineStoreOperatorTest, ParameterIsCorrect) {
150  MachineOperatorBuilder machine(type());
151  EXPECT_EQ(GetParam(),
152  OpParameter<StoreRepresentation>(machine.Store(GetParam())));
153 }
154 
155 
157  MachineOperatorTest, MachineStoreOperatorTest,
159  ::testing::ValuesIn(kMachineReps),
160  ::testing::Combine(::testing::ValuesIn(kMachineTypes),
161  ::testing::Values(kNoWriteBarrier,
162  kFullWriteBarrier))));
163 
164 
165 // -----------------------------------------------------------------------------
166 // Pure operators.
167 
168 
169 namespace {
170 
171 struct PureOperator {
172  const Operator* (MachineOperatorBuilder::*constructor)();
173  IrOpcode::Value opcode;
174  int value_input_count;
175  int value_output_count;
176 };
177 
178 
179 std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
180  return os << IrOpcode::Mnemonic(pop.opcode);
181 }
182 
183 
184 const PureOperator kPureOperators[] = {
185 #define PURE(Name, input_count, output_count) \
186  { \
187  &MachineOperatorBuilder::Name, IrOpcode::k##Name, input_count, \
188  output_count \
189  }
190  PURE(Word32And, 2, 1), PURE(Word32Or, 2, 1),
191  PURE(Word32Xor, 2, 1), PURE(Word32Shl, 2, 1),
192  PURE(Word32Shr, 2, 1), PURE(Word32Sar, 2, 1),
193  PURE(Word32Ror, 2, 1), PURE(Word32Equal, 2, 1),
194  PURE(Word64And, 2, 1), PURE(Word64Or, 2, 1),
195  PURE(Word64Xor, 2, 1), PURE(Word64Shl, 2, 1),
196  PURE(Word64Shr, 2, 1), PURE(Word64Sar, 2, 1),
197  PURE(Word64Ror, 2, 1), PURE(Word64Equal, 2, 1),
198  PURE(Int32Add, 2, 1), PURE(Int32AddWithOverflow, 2, 2),
199  PURE(Int32Sub, 2, 1), PURE(Int32SubWithOverflow, 2, 2),
200  PURE(Int32Mul, 2, 1), PURE(Int32Div, 2, 1),
201  PURE(Int32UDiv, 2, 1), PURE(Int32Mod, 2, 1),
202  PURE(Int32UMod, 2, 1), PURE(Int32LessThan, 2, 1),
203  PURE(Int32LessThanOrEqual, 2, 1), PURE(Uint32LessThan, 2, 1),
204  PURE(Uint32LessThanOrEqual, 2, 1), PURE(Int64Add, 2, 1),
205  PURE(Int64Sub, 2, 1), PURE(Int64Mul, 2, 1),
206  PURE(Int64Div, 2, 1), PURE(Int64UDiv, 2, 1),
207  PURE(Int64Mod, 2, 1), PURE(Int64UMod, 2, 1),
208  PURE(Int64LessThan, 2, 1), PURE(Int64LessThanOrEqual, 2, 1),
209  PURE(ChangeFloat32ToFloat64, 1, 1), PURE(ChangeFloat64ToInt32, 1, 1),
210  PURE(ChangeFloat64ToUint32, 1, 1), PURE(ChangeInt32ToInt64, 1, 1),
211  PURE(ChangeUint32ToFloat64, 1, 1), PURE(ChangeUint32ToUint64, 1, 1),
212  PURE(TruncateFloat64ToFloat32, 1, 1), PURE(TruncateFloat64ToInt32, 1, 1),
213  PURE(TruncateInt64ToInt32, 1, 1), PURE(Float64Add, 2, 1),
214  PURE(Float64Sub, 2, 1), PURE(Float64Mul, 2, 1),
215  PURE(Float64Div, 2, 1), PURE(Float64Mod, 2, 1),
216  PURE(Float64Sqrt, 1, 1), PURE(Float64Equal, 2, 1),
217  PURE(Float64LessThan, 2, 1), PURE(Float64LessThanOrEqual, 2, 1)
218 #undef PURE
219 };
220 
221 
222 typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
223 
224 } // namespace
225 
226 
227 TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
228  const PureOperator& pop = GetParam();
229  MachineOperatorBuilder machine1(type());
230  MachineOperatorBuilder machine2(type());
231  EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
232 }
233 
234 
235 TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
236  MachineOperatorBuilder machine(type());
237  const PureOperator& pop = GetParam();
238  const Operator* op = (machine.*pop.constructor)();
239 
240  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetValueInputCount(op));
241  EXPECT_EQ(0, OperatorProperties::GetEffectInputCount(op));
243  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
244 
245  EXPECT_EQ(pop.value_output_count,
249 }
250 
251 
252 TEST_P(MachinePureOperatorTest, MarkedAsPure) {
253  MachineOperatorBuilder machine(type());
254  const PureOperator& pop = GetParam();
255  const Operator* op = (machine.*pop.constructor)();
256  EXPECT_TRUE(op->HasProperty(Operator::kPure));
257 }
258 
259 
260 TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
261  MachineOperatorBuilder machine(type());
262  const PureOperator& pop = GetParam();
263  const Operator* op = (machine.*pop.constructor)();
264  EXPECT_EQ(pop.opcode, op->opcode());
265 }
266 
267 
269  MachineOperatorTest, MachinePureOperatorTest,
270  ::testing::Combine(::testing::ValuesIn(kMachineReps),
271  ::testing::ValuesIn(kPureOperators)));
272 
273 #endif // GTEST_HAS_COMBINE
274 
275 
276 // -----------------------------------------------------------------------------
277 // Pseudo operators.
278 
279 
280 TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
281  MachineOperatorBuilder machine(kRepWord32);
282  EXPECT_EQ(machine.Word32And(), machine.WordAnd());
283  EXPECT_EQ(machine.Word32Or(), machine.WordOr());
284  EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
285  EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
286  EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
287  EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
288  EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
289  EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
290  EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
291  EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
292  EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
293  EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
294  EXPECT_EQ(machine.Int32UDiv(), machine.IntUDiv());
295  EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
296  EXPECT_EQ(machine.Int32UMod(), machine.IntUMod());
297  EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
298  EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
299 }
300 
301 
302 TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
303  MachineOperatorBuilder machine(kRepWord64);
304  EXPECT_EQ(machine.Word64And(), machine.WordAnd());
305  EXPECT_EQ(machine.Word64Or(), machine.WordOr());
306  EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
307  EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
308  EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
309  EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
310  EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
311  EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
312  EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
313  EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
314  EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
315  EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
316  EXPECT_EQ(machine.Int64UDiv(), machine.IntUDiv());
317  EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
318  EXPECT_EQ(machine.Int64UMod(), machine.IntUMod());
319  EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
320  EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
321 }
322 
323 } // namespace compiler
324 } // namespace internal
325 } // namespace v8
static const char * Mnemonic(Value val)
Definition: opcodes.h:256
static int GetTotalInputCount(const Operator *op)
static int GetEffectInputCount(const Operator *op)
static int GetEffectOutputCount(const Operator *op)
static int GetValueInputCount(const Operator *op)
static int GetControlOutputCount(const Operator *op)
static int GetValueOutputCount(const Operator *op)
static int GetControlInputCount(const Operator *op)
#define PURE(Name, properties, input_count, output_count)
std::ostream & operator<<(std::ostream &os, const MachineType &type)
TEST_P(InstructionSelectorDPITest, Parameters)
TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit)
INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest, ::testing::ValuesIn(kDPIs))
ContainedInLattice Combine(ContainedInLattice a, ContainedInLattice b)
Definition: jsregexp.h:1238
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25