6e60cfd12ae228884390d8a388bc4b21c4a00155
[platform/upstream/nodejs.git] / deps / v8 / test / unittests / compiler / common-operator-unittest.cc
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 <limits>
6
7 #include "src/compiler/common-operator.h"
8 #include "src/compiler/opcodes.h"
9 #include "src/compiler/operator.h"
10 #include "src/compiler/operator-properties.h"
11 #include "test/unittests/test-utils.h"
12
13 namespace v8 {
14 namespace internal {
15 namespace compiler {
16
17
18 // -----------------------------------------------------------------------------
19 // Shared operators.
20
21
22 namespace {
23
24 struct SharedOperator {
25   const Operator* (CommonOperatorBuilder::*constructor)();
26   IrOpcode::Value opcode;
27   Operator::Properties properties;
28   int value_input_count;
29   int effect_input_count;
30   int control_input_count;
31   int value_output_count;
32   int effect_output_count;
33   int control_output_count;
34 };
35
36
37 std::ostream& operator<<(std::ostream& os, const SharedOperator& fop) {
38   return os << IrOpcode::Mnemonic(fop.opcode);
39 }
40
41
42 const SharedOperator kSharedOperators[] = {
43 #define SHARED(Name, properties, value_input_count, effect_input_count,      \
44                control_input_count, value_output_count, effect_output_count, \
45                control_output_count)                                         \
46   {                                                                          \
47     &CommonOperatorBuilder::Name, IrOpcode::k##Name, properties,             \
48         value_input_count, effect_input_count, control_input_count,          \
49         value_output_count, effect_output_count, control_output_count        \
50   }
51     SHARED(Always, Operator::kPure, 0, 0, 0, 1, 0, 0),
52     SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 0, 1),
53     SHARED(End, Operator::kKontrol, 0, 0, 1, 0, 0, 0),
54     SHARED(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
55     SHARED(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
56     SHARED(Throw, Operator::kFoldable, 1, 1, 1, 0, 0, 1),
57     SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1)
58 #undef SHARED
59 };
60
61
62 class CommonSharedOperatorTest
63     : public TestWithZone,
64       public ::testing::WithParamInterface<SharedOperator> {};
65
66 }  // namespace
67
68
69 TEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) {
70   const SharedOperator& sop = GetParam();
71   CommonOperatorBuilder common1(zone());
72   CommonOperatorBuilder common2(zone());
73   EXPECT_EQ((common1.*sop.constructor)(), (common2.*sop.constructor)());
74 }
75
76
77 TEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
78   CommonOperatorBuilder common(zone());
79   const SharedOperator& sop = GetParam();
80   const Operator* op = (common.*sop.constructor)();
81
82   EXPECT_EQ(sop.value_input_count, op->ValueInputCount());
83   EXPECT_EQ(sop.effect_input_count, op->EffectInputCount());
84   EXPECT_EQ(sop.control_input_count, op->ControlInputCount());
85   EXPECT_EQ(
86       sop.value_input_count + sop.effect_input_count + sop.control_input_count,
87       OperatorProperties::GetTotalInputCount(op));
88
89   EXPECT_EQ(sop.value_output_count, op->ValueOutputCount());
90   EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount());
91   EXPECT_EQ(sop.control_output_count, op->ControlOutputCount());
92 }
93
94
95 TEST_P(CommonSharedOperatorTest, OpcodeIsCorrect) {
96   CommonOperatorBuilder common(zone());
97   const SharedOperator& sop = GetParam();
98   const Operator* op = (common.*sop.constructor)();
99   EXPECT_EQ(sop.opcode, op->opcode());
100 }
101
102
103 TEST_P(CommonSharedOperatorTest, Properties) {
104   CommonOperatorBuilder common(zone());
105   const SharedOperator& sop = GetParam();
106   const Operator* op = (common.*sop.constructor)();
107   EXPECT_EQ(sop.properties, op->properties());
108 }
109
110
111 INSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
112                         ::testing::ValuesIn(kSharedOperators));
113
114
115 // -----------------------------------------------------------------------------
116 // Other operators.
117
118
119 namespace {
120
121 class CommonOperatorTest : public TestWithZone {
122  public:
123   CommonOperatorTest() : common_(zone()) {}
124   ~CommonOperatorTest() OVERRIDE {}
125
126   CommonOperatorBuilder* common() { return &common_; }
127
128  private:
129   CommonOperatorBuilder common_;
130 };
131
132
133 const int kArguments[] = {1, 5, 6, 42, 100, 10000, 65000};
134
135
136 const size_t kCases[] = {3, 4, 100, 255, 1024, 65000};
137
138
139 const float kFloatValues[] = {-std::numeric_limits<float>::infinity(),
140                               std::numeric_limits<float>::min(),
141                               -1.0f,
142                               -0.0f,
143                               0.0f,
144                               1.0f,
145                               std::numeric_limits<float>::max(),
146                               std::numeric_limits<float>::infinity(),
147                               std::numeric_limits<float>::quiet_NaN(),
148                               std::numeric_limits<float>::signaling_NaN()};
149
150
151 const double kDoubleValues[] = {-std::numeric_limits<double>::infinity(),
152                                 std::numeric_limits<double>::min(),
153                                 -1.0,
154                                 -0.0,
155                                 0.0,
156                                 1.0,
157                                 std::numeric_limits<double>::max(),
158                                 std::numeric_limits<double>::infinity(),
159                                 std::numeric_limits<double>::quiet_NaN(),
160                                 std::numeric_limits<double>::signaling_NaN()};
161
162
163 const int32_t kInt32Values[] = {
164     std::numeric_limits<int32_t>::min(), -1914954528, -1698749618, -1578693386,
165     -1577976073, -1573998034, -1529085059, -1499540537, -1299205097,
166     -1090814845, -938186388, -806828902, -750927650, -520676892, -513661538,
167     -453036354, -433622833, -282638793, -28375, -27788, -22770, -18806, -14173,
168     -11956, -11200, -10212, -8160, -3751, -2758, -1522, -121, -120, -118, -117,
169     -106, -84, -80, -74, -59, -52, -48, -39, -35, -17, -11, -10, -9, -7, -5, 0,
170     9, 12, 17, 23, 29, 31, 33, 35, 40, 47, 55, 56, 62, 64, 67, 68, 69, 74, 79,
171     84, 89, 90, 97, 104, 118, 124, 126, 127, 7278, 17787, 24136, 24202, 25570,
172     26680, 30242, 32399, 420886487, 642166225, 821912648, 822577803, 851385718,
173     1212241078, 1411419304, 1589626102, 1596437184, 1876245816, 1954730266,
174     2008792749, 2045320228, std::numeric_limits<int32_t>::max()};
175
176
177 const BranchHint kHints[] = {BranchHint::kNone, BranchHint::kTrue,
178                              BranchHint::kFalse};
179
180 }  // namespace
181
182
183 TEST_F(CommonOperatorTest, Branch) {
184   TRACED_FOREACH(BranchHint, hint, kHints) {
185     const Operator* const op = common()->Branch(hint);
186     EXPECT_EQ(IrOpcode::kBranch, op->opcode());
187     EXPECT_EQ(Operator::kKontrol, op->properties());
188     EXPECT_EQ(hint, BranchHintOf(op));
189     EXPECT_EQ(1, op->ValueInputCount());
190     EXPECT_EQ(0, op->EffectInputCount());
191     EXPECT_EQ(1, op->ControlInputCount());
192     EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
193     EXPECT_EQ(0, op->ValueOutputCount());
194     EXPECT_EQ(0, op->EffectOutputCount());
195     EXPECT_EQ(2, op->ControlOutputCount());
196   }
197 }
198
199
200 TEST_F(CommonOperatorTest, Switch) {
201   TRACED_FOREACH(size_t, cases, kCases) {
202     const Operator* const op = common()->Switch(cases);
203     EXPECT_EQ(IrOpcode::kSwitch, op->opcode());
204     EXPECT_EQ(Operator::kKontrol, op->properties());
205     EXPECT_EQ(1, op->ValueInputCount());
206     EXPECT_EQ(0, op->EffectInputCount());
207     EXPECT_EQ(1, op->ControlInputCount());
208     EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
209     EXPECT_EQ(0, op->ValueOutputCount());
210     EXPECT_EQ(0, op->EffectOutputCount());
211     EXPECT_EQ(static_cast<int>(cases), op->ControlOutputCount());
212   }
213 }
214
215
216 TEST_F(CommonOperatorTest, IfValue) {
217   TRACED_FOREACH(int32_t, value, kInt32Values) {
218     const Operator* const op = common()->IfValue(value);
219     EXPECT_EQ(IrOpcode::kIfValue, op->opcode());
220     EXPECT_EQ(Operator::kKontrol, op->properties());
221     EXPECT_EQ(value, OpParameter<int32_t>(op));
222     EXPECT_EQ(0, op->ValueInputCount());
223     EXPECT_EQ(0, op->EffectInputCount());
224     EXPECT_EQ(1, op->ControlInputCount());
225     EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
226     EXPECT_EQ(0, op->ValueOutputCount());
227     EXPECT_EQ(0, op->EffectOutputCount());
228     EXPECT_EQ(1, op->ControlOutputCount());
229   }
230 }
231
232
233 TEST_F(CommonOperatorTest, Select) {
234   static const MachineType kTypes[] = {
235       kMachInt8,    kMachUint8,   kMachInt16,    kMachUint16,
236       kMachInt32,   kMachUint32,  kMachInt64,    kMachUint64,
237       kMachFloat32, kMachFloat64, kMachAnyTagged};
238   TRACED_FOREACH(MachineType, type, kTypes) {
239     TRACED_FOREACH(BranchHint, hint, kHints) {
240       const Operator* const op = common()->Select(type, hint);
241       EXPECT_EQ(IrOpcode::kSelect, op->opcode());
242       EXPECT_EQ(Operator::kPure, op->properties());
243       EXPECT_EQ(type, SelectParametersOf(op).type());
244       EXPECT_EQ(hint, SelectParametersOf(op).hint());
245       EXPECT_EQ(3, op->ValueInputCount());
246       EXPECT_EQ(0, op->EffectInputCount());
247       EXPECT_EQ(0, op->ControlInputCount());
248       EXPECT_EQ(3, OperatorProperties::GetTotalInputCount(op));
249       EXPECT_EQ(1, op->ValueOutputCount());
250       EXPECT_EQ(0, op->EffectOutputCount());
251       EXPECT_EQ(0, op->ControlOutputCount());
252     }
253   }
254 }
255
256
257 TEST_F(CommonOperatorTest, Float32Constant) {
258   TRACED_FOREACH(float, value, kFloatValues) {
259     const Operator* op = common()->Float32Constant(value);
260     EXPECT_PRED2(base::bit_equal_to<float>(), value, OpParameter<float>(op));
261     EXPECT_EQ(0, op->ValueInputCount());
262     EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
263     EXPECT_EQ(0, op->ControlOutputCount());
264     EXPECT_EQ(0, op->EffectOutputCount());
265     EXPECT_EQ(1, op->ValueOutputCount());
266   }
267   TRACED_FOREACH(float, v1, kFloatValues) {
268     TRACED_FOREACH(float, v2, kFloatValues) {
269       const Operator* op1 = common()->Float32Constant(v1);
270       const Operator* op2 = common()->Float32Constant(v2);
271       EXPECT_EQ(bit_cast<uint32_t>(v1) == bit_cast<uint32_t>(v2),
272                 op1->Equals(op2));
273     }
274   }
275 }
276
277
278 TEST_F(CommonOperatorTest, Float64Constant) {
279   TRACED_FOREACH(double, value, kFloatValues) {
280     const Operator* op = common()->Float64Constant(value);
281     EXPECT_PRED2(base::bit_equal_to<double>(), value, OpParameter<double>(op));
282     EXPECT_EQ(0, op->ValueInputCount());
283     EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
284     EXPECT_EQ(0, op->ControlOutputCount());
285     EXPECT_EQ(0, op->EffectOutputCount());
286     EXPECT_EQ(1, op->ValueOutputCount());
287   }
288   TRACED_FOREACH(double, v1, kFloatValues) {
289     TRACED_FOREACH(double, v2, kFloatValues) {
290       const Operator* op1 = common()->Float64Constant(v1);
291       const Operator* op2 = common()->Float64Constant(v2);
292       EXPECT_EQ(bit_cast<uint64_t>(v1) == bit_cast<uint64_t>(v2),
293                 op1->Equals(op2));
294     }
295   }
296 }
297
298
299 TEST_F(CommonOperatorTest, NumberConstant) {
300   TRACED_FOREACH(double, value, kFloatValues) {
301     const Operator* op = common()->NumberConstant(value);
302     EXPECT_PRED2(base::bit_equal_to<double>(), value, OpParameter<double>(op));
303     EXPECT_EQ(0, op->ValueInputCount());
304     EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
305     EXPECT_EQ(0, op->ControlOutputCount());
306     EXPECT_EQ(0, op->EffectOutputCount());
307     EXPECT_EQ(1, op->ValueOutputCount());
308   }
309   TRACED_FOREACH(double, v1, kFloatValues) {
310     TRACED_FOREACH(double, v2, kFloatValues) {
311       const Operator* op1 = common()->NumberConstant(v1);
312       const Operator* op2 = common()->NumberConstant(v2);
313       EXPECT_EQ(bit_cast<uint64_t>(v1) == bit_cast<uint64_t>(v2),
314                 op1->Equals(op2));
315     }
316   }
317 }
318
319
320 TEST_F(CommonOperatorTest, ValueEffect) {
321   TRACED_FOREACH(int, arguments, kArguments) {
322     const Operator* op = common()->ValueEffect(arguments);
323     EXPECT_EQ(arguments, op->ValueInputCount());
324     EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
325     EXPECT_EQ(0, op->ControlOutputCount());
326     EXPECT_EQ(1, op->EffectOutputCount());
327     EXPECT_EQ(0, op->ValueOutputCount());
328   }
329 }
330
331
332 TEST_F(CommonOperatorTest, Finish) {
333   TRACED_FOREACH(int, arguments, kArguments) {
334     const Operator* op = common()->Finish(arguments);
335     EXPECT_EQ(1, op->ValueInputCount());
336     EXPECT_EQ(arguments, op->EffectInputCount());
337     EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
338     EXPECT_EQ(0, op->ControlOutputCount());
339     EXPECT_EQ(0, op->EffectOutputCount());
340     EXPECT_EQ(1, op->ValueOutputCount());
341   }
342 }
343
344 }  // namespace compiler
345 }  // namespace internal
346 }  // namespace v8