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.
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"
18 // -----------------------------------------------------------------------------
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;
37 std::ostream& operator<<(std::ostream& os, const SharedOperator& fop) {
38 return os << IrOpcode::Mnemonic(fop.opcode);
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) \
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 \
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)
62 class CommonSharedOperatorTest
63 : public TestWithZone,
64 public ::testing::WithParamInterface<SharedOperator> {};
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)());
77 TEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
78 CommonOperatorBuilder common(zone());
79 const SharedOperator& sop = GetParam();
80 const Operator* op = (common.*sop.constructor)();
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());
86 sop.value_input_count + sop.effect_input_count + sop.control_input_count,
87 OperatorProperties::GetTotalInputCount(op));
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());
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());
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());
111 INSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
112 ::testing::ValuesIn(kSharedOperators));
115 // -----------------------------------------------------------------------------
121 class CommonOperatorTest : public TestWithZone {
123 CommonOperatorTest() : common_(zone()) {}
124 ~CommonOperatorTest() OVERRIDE {}
126 CommonOperatorBuilder* common() { return &common_; }
129 CommonOperatorBuilder common_;
133 const int kArguments[] = {1, 5, 6, 42, 100, 10000, 65000};
136 const size_t kCases[] = {3, 4, 100, 255, 1024, 65000};
139 const float kFloatValues[] = {-std::numeric_limits<float>::infinity(),
140 std::numeric_limits<float>::min(),
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()};
151 const double kDoubleValues[] = {-std::numeric_limits<double>::infinity(),
152 std::numeric_limits<double>::min(),
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()};
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()};
177 const BranchHint kHints[] = {BranchHint::kNone, BranchHint::kTrue,
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());
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());
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());
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());
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());
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),
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());
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),
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());
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),
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());
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());
344 } // namespace compiler
345 } // namespace internal