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(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
57 SHARED(IfException, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
58 SHARED(Throw, Operator::kFoldable, 1, 1, 1, 0, 0, 1),
59 SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1)
64 class CommonSharedOperatorTest
65 : public TestWithZone,
66 public ::testing::WithParamInterface<SharedOperator> {};
71 TEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) {
72 const SharedOperator& sop = GetParam();
73 CommonOperatorBuilder common1(zone());
74 CommonOperatorBuilder common2(zone());
75 EXPECT_EQ((common1.*sop.constructor)(), (common2.*sop.constructor)());
79 TEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
80 CommonOperatorBuilder common(zone());
81 const SharedOperator& sop = GetParam();
82 const Operator* op = (common.*sop.constructor)();
84 EXPECT_EQ(sop.value_input_count, op->ValueInputCount());
85 EXPECT_EQ(sop.effect_input_count, op->EffectInputCount());
86 EXPECT_EQ(sop.control_input_count, op->ControlInputCount());
88 sop.value_input_count + sop.effect_input_count + sop.control_input_count,
89 OperatorProperties::GetTotalInputCount(op));
91 EXPECT_EQ(sop.value_output_count, op->ValueOutputCount());
92 EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount());
93 EXPECT_EQ(sop.control_output_count, op->ControlOutputCount());
97 TEST_P(CommonSharedOperatorTest, OpcodeIsCorrect) {
98 CommonOperatorBuilder common(zone());
99 const SharedOperator& sop = GetParam();
100 const Operator* op = (common.*sop.constructor)();
101 EXPECT_EQ(sop.opcode, op->opcode());
105 TEST_P(CommonSharedOperatorTest, Properties) {
106 CommonOperatorBuilder common(zone());
107 const SharedOperator& sop = GetParam();
108 const Operator* op = (common.*sop.constructor)();
109 EXPECT_EQ(sop.properties, op->properties());
113 INSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
114 ::testing::ValuesIn(kSharedOperators));
117 // -----------------------------------------------------------------------------
123 class CommonOperatorTest : public TestWithZone {
125 CommonOperatorTest() : common_(zone()) {}
126 ~CommonOperatorTest() OVERRIDE {}
128 CommonOperatorBuilder* common() { return &common_; }
131 CommonOperatorBuilder common_;
135 const int kArguments[] = {1, 5, 6, 42, 100, 10000, 65000};
138 const size_t kCases[] = {3, 4, 100, 255, 1024, 65000};
141 const float kFloatValues[] = {-std::numeric_limits<float>::infinity(),
142 std::numeric_limits<float>::min(),
147 std::numeric_limits<float>::max(),
148 std::numeric_limits<float>::infinity(),
149 std::numeric_limits<float>::quiet_NaN(),
150 std::numeric_limits<float>::signaling_NaN()};
153 const double kDoubleValues[] = {-std::numeric_limits<double>::infinity(),
154 std::numeric_limits<double>::min(),
159 std::numeric_limits<double>::max(),
160 std::numeric_limits<double>::infinity(),
161 std::numeric_limits<double>::quiet_NaN(),
162 std::numeric_limits<double>::signaling_NaN()};
165 const int32_t kInt32Values[] = {
166 std::numeric_limits<int32_t>::min(), -1914954528, -1698749618, -1578693386,
167 -1577976073, -1573998034, -1529085059, -1499540537, -1299205097,
168 -1090814845, -938186388, -806828902, -750927650, -520676892, -513661538,
169 -453036354, -433622833, -282638793, -28375, -27788, -22770, -18806, -14173,
170 -11956, -11200, -10212, -8160, -3751, -2758, -1522, -121, -120, -118, -117,
171 -106, -84, -80, -74, -59, -52, -48, -39, -35, -17, -11, -10, -9, -7, -5, 0,
172 9, 12, 17, 23, 29, 31, 33, 35, 40, 47, 55, 56, 62, 64, 67, 68, 69, 74, 79,
173 84, 89, 90, 97, 104, 118, 124, 126, 127, 7278, 17787, 24136, 24202, 25570,
174 26680, 30242, 32399, 420886487, 642166225, 821912648, 822577803, 851385718,
175 1212241078, 1411419304, 1589626102, 1596437184, 1876245816, 1954730266,
176 2008792749, 2045320228, std::numeric_limits<int32_t>::max()};
179 const BranchHint kHints[] = {BranchHint::kNone, BranchHint::kTrue,
185 TEST_F(CommonOperatorTest, Branch) {
186 TRACED_FOREACH(BranchHint, hint, kHints) {
187 const Operator* const op = common()->Branch(hint);
188 EXPECT_EQ(IrOpcode::kBranch, op->opcode());
189 EXPECT_EQ(Operator::kKontrol, op->properties());
190 EXPECT_EQ(hint, BranchHintOf(op));
191 EXPECT_EQ(1, op->ValueInputCount());
192 EXPECT_EQ(0, op->EffectInputCount());
193 EXPECT_EQ(1, op->ControlInputCount());
194 EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
195 EXPECT_EQ(0, op->ValueOutputCount());
196 EXPECT_EQ(0, op->EffectOutputCount());
197 EXPECT_EQ(2, op->ControlOutputCount());
202 TEST_F(CommonOperatorTest, Switch) {
203 TRACED_FOREACH(size_t, cases, kCases) {
204 const Operator* const op = common()->Switch(cases);
205 EXPECT_EQ(IrOpcode::kSwitch, op->opcode());
206 EXPECT_EQ(Operator::kKontrol, op->properties());
207 EXPECT_EQ(1, op->ValueInputCount());
208 EXPECT_EQ(0, op->EffectInputCount());
209 EXPECT_EQ(1, op->ControlInputCount());
210 EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
211 EXPECT_EQ(0, op->ValueOutputCount());
212 EXPECT_EQ(0, op->EffectOutputCount());
213 EXPECT_EQ(static_cast<int>(cases), op->ControlOutputCount());
218 TEST_F(CommonOperatorTest, IfValue) {
219 TRACED_FOREACH(int32_t, value, kInt32Values) {
220 const Operator* const op = common()->IfValue(value);
221 EXPECT_EQ(IrOpcode::kIfValue, op->opcode());
222 EXPECT_EQ(Operator::kKontrol, op->properties());
223 EXPECT_EQ(value, OpParameter<int32_t>(op));
224 EXPECT_EQ(0, op->ValueInputCount());
225 EXPECT_EQ(0, op->EffectInputCount());
226 EXPECT_EQ(1, op->ControlInputCount());
227 EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
228 EXPECT_EQ(0, op->ValueOutputCount());
229 EXPECT_EQ(0, op->EffectOutputCount());
230 EXPECT_EQ(1, op->ControlOutputCount());
235 TEST_F(CommonOperatorTest, Select) {
236 static const MachineType kTypes[] = {
237 kMachInt8, kMachUint8, kMachInt16, kMachUint16,
238 kMachInt32, kMachUint32, kMachInt64, kMachUint64,
239 kMachFloat32, kMachFloat64, kMachAnyTagged};
240 TRACED_FOREACH(MachineType, type, kTypes) {
241 TRACED_FOREACH(BranchHint, hint, kHints) {
242 const Operator* const op = common()->Select(type, hint);
243 EXPECT_EQ(IrOpcode::kSelect, op->opcode());
244 EXPECT_EQ(Operator::kPure, op->properties());
245 EXPECT_EQ(type, SelectParametersOf(op).type());
246 EXPECT_EQ(hint, SelectParametersOf(op).hint());
247 EXPECT_EQ(3, op->ValueInputCount());
248 EXPECT_EQ(0, op->EffectInputCount());
249 EXPECT_EQ(0, op->ControlInputCount());
250 EXPECT_EQ(3, OperatorProperties::GetTotalInputCount(op));
251 EXPECT_EQ(1, op->ValueOutputCount());
252 EXPECT_EQ(0, op->EffectOutputCount());
253 EXPECT_EQ(0, op->ControlOutputCount());
259 TEST_F(CommonOperatorTest, Float32Constant) {
260 TRACED_FOREACH(float, value, kFloatValues) {
261 const Operator* op = common()->Float32Constant(value);
262 EXPECT_PRED2(base::bit_equal_to<float>(), value, OpParameter<float>(op));
263 EXPECT_EQ(0, op->ValueInputCount());
264 EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
265 EXPECT_EQ(0, op->ControlOutputCount());
266 EXPECT_EQ(0, op->EffectOutputCount());
267 EXPECT_EQ(1, op->ValueOutputCount());
269 TRACED_FOREACH(float, v1, kFloatValues) {
270 TRACED_FOREACH(float, v2, kFloatValues) {
271 const Operator* op1 = common()->Float32Constant(v1);
272 const Operator* op2 = common()->Float32Constant(v2);
273 EXPECT_EQ(bit_cast<uint32_t>(v1) == bit_cast<uint32_t>(v2),
280 TEST_F(CommonOperatorTest, Float64Constant) {
281 TRACED_FOREACH(double, value, kFloatValues) {
282 const Operator* op = common()->Float64Constant(value);
283 EXPECT_PRED2(base::bit_equal_to<double>(), value, OpParameter<double>(op));
284 EXPECT_EQ(0, op->ValueInputCount());
285 EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
286 EXPECT_EQ(0, op->ControlOutputCount());
287 EXPECT_EQ(0, op->EffectOutputCount());
288 EXPECT_EQ(1, op->ValueOutputCount());
290 TRACED_FOREACH(double, v1, kFloatValues) {
291 TRACED_FOREACH(double, v2, kFloatValues) {
292 const Operator* op1 = common()->Float64Constant(v1);
293 const Operator* op2 = common()->Float64Constant(v2);
294 EXPECT_EQ(bit_cast<uint64_t>(v1) == bit_cast<uint64_t>(v2),
301 TEST_F(CommonOperatorTest, NumberConstant) {
302 TRACED_FOREACH(double, value, kFloatValues) {
303 const Operator* op = common()->NumberConstant(value);
304 EXPECT_PRED2(base::bit_equal_to<double>(), value, OpParameter<double>(op));
305 EXPECT_EQ(0, op->ValueInputCount());
306 EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
307 EXPECT_EQ(0, op->ControlOutputCount());
308 EXPECT_EQ(0, op->EffectOutputCount());
309 EXPECT_EQ(1, op->ValueOutputCount());
311 TRACED_FOREACH(double, v1, kFloatValues) {
312 TRACED_FOREACH(double, v2, kFloatValues) {
313 const Operator* op1 = common()->NumberConstant(v1);
314 const Operator* op2 = common()->NumberConstant(v2);
315 EXPECT_EQ(bit_cast<uint64_t>(v1) == bit_cast<uint64_t>(v2),
322 TEST_F(CommonOperatorTest, ValueEffect) {
323 TRACED_FOREACH(int, arguments, kArguments) {
324 const Operator* op = common()->ValueEffect(arguments);
325 EXPECT_EQ(arguments, op->ValueInputCount());
326 EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
327 EXPECT_EQ(0, op->ControlOutputCount());
328 EXPECT_EQ(1, op->EffectOutputCount());
329 EXPECT_EQ(0, op->ValueOutputCount());
334 TEST_F(CommonOperatorTest, Finish) {
335 TRACED_FOREACH(int, arguments, kArguments) {
336 const Operator* op = common()->Finish(arguments);
337 EXPECT_EQ(1, op->ValueInputCount());
338 EXPECT_EQ(arguments, op->EffectInputCount());
339 EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
340 EXPECT_EQ(0, op->ControlOutputCount());
341 EXPECT_EQ(0, op->EffectOutputCount());
342 EXPECT_EQ(1, op->ValueOutputCount());
346 } // namespace compiler
347 } // namespace internal