deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / test / unittests / compiler / simplified-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 "src/compiler/opcodes.h"
6 #include "src/compiler/operator.h"
7 #include "src/compiler/operator-properties.h"
8 #include "src/compiler/simplified-operator.h"
9 #include "src/types-inl.h"
10 #include "test/unittests/test-utils.h"
11
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15
16 // -----------------------------------------------------------------------------
17 // Pure operators.
18
19
20 namespace {
21
22 struct PureOperator {
23   const Operator* (SimplifiedOperatorBuilder::*constructor)();
24   IrOpcode::Value opcode;
25   Operator::Properties properties;
26   int value_input_count;
27 };
28
29
30 std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
31   return os << IrOpcode::Mnemonic(pop.opcode);
32 }
33
34
35 const PureOperator kPureOperators[] = {
36 #define PURE(Name, properties, input_count)              \
37   {                                                      \
38     &SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
39         Operator::kPure | properties, input_count        \
40   }
41     PURE(BooleanNot, Operator::kNoProperties, 1),
42     PURE(BooleanToNumber, Operator::kNoProperties, 1),
43     PURE(NumberEqual, Operator::kCommutative, 2),
44     PURE(NumberLessThan, Operator::kNoProperties, 2),
45     PURE(NumberLessThanOrEqual, Operator::kNoProperties, 2),
46     PURE(NumberAdd, Operator::kCommutative, 2),
47     PURE(NumberSubtract, Operator::kNoProperties, 2),
48     PURE(NumberMultiply, Operator::kCommutative, 2),
49     PURE(NumberDivide, Operator::kNoProperties, 2),
50     PURE(NumberModulus, Operator::kNoProperties, 2),
51     PURE(NumberToInt32, Operator::kNoProperties, 1),
52     PURE(NumberToUint32, Operator::kNoProperties, 1),
53     PURE(PlainPrimitiveToNumber, Operator::kNoProperties, 1),
54     PURE(StringEqual, Operator::kCommutative, 2),
55     PURE(StringLessThan, Operator::kNoProperties, 2),
56     PURE(StringLessThanOrEqual, Operator::kNoProperties, 2),
57     PURE(StringAdd, Operator::kNoProperties, 2),
58     PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
59     PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
60     PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
61     PURE(ChangeInt32ToTagged, Operator::kNoProperties, 1),
62     PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1),
63     PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1),
64     PURE(ChangeBoolToBit, Operator::kNoProperties, 1),
65     PURE(ChangeBitToBool, Operator::kNoProperties, 1),
66     PURE(ObjectIsSmi, Operator::kNoProperties, 1),
67     PURE(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)
68 #undef PURE
69 };
70
71 }  // namespace
72
73
74 class SimplifiedPureOperatorTest
75     : public TestWithZone,
76       public ::testing::WithParamInterface<PureOperator> {};
77
78
79 TEST_P(SimplifiedPureOperatorTest, InstancesAreGloballyShared) {
80   const PureOperator& pop = GetParam();
81   SimplifiedOperatorBuilder simplified1(zone());
82   SimplifiedOperatorBuilder simplified2(zone());
83   EXPECT_EQ((simplified1.*pop.constructor)(), (simplified2.*pop.constructor)());
84 }
85
86
87 TEST_P(SimplifiedPureOperatorTest, NumberOfInputsAndOutputs) {
88   SimplifiedOperatorBuilder simplified(zone());
89   const PureOperator& pop = GetParam();
90   const Operator* op = (simplified.*pop.constructor)();
91
92   EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
93   EXPECT_EQ(0, op->EffectInputCount());
94   EXPECT_EQ(0, op->ControlInputCount());
95   EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
96
97   EXPECT_EQ(1, op->ValueOutputCount());
98   EXPECT_EQ(0, op->EffectOutputCount());
99   EXPECT_EQ(0, op->ControlOutputCount());
100 }
101
102
103 TEST_P(SimplifiedPureOperatorTest, OpcodeIsCorrect) {
104   SimplifiedOperatorBuilder simplified(zone());
105   const PureOperator& pop = GetParam();
106   const Operator* op = (simplified.*pop.constructor)();
107   EXPECT_EQ(pop.opcode, op->opcode());
108 }
109
110
111 TEST_P(SimplifiedPureOperatorTest, Properties) {
112   SimplifiedOperatorBuilder simplified(zone());
113   const PureOperator& pop = GetParam();
114   const Operator* op = (simplified.*pop.constructor)();
115   EXPECT_EQ(pop.properties, op->properties() & pop.properties);
116 }
117
118 INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest, SimplifiedPureOperatorTest,
119                         ::testing::ValuesIn(kPureOperators));
120
121
122 // -----------------------------------------------------------------------------
123 // Buffer access operators.
124
125
126 namespace {
127
128 const ExternalArrayType kExternalArrayTypes[] = {
129     kExternalUint8Array,   kExternalInt8Array,   kExternalUint16Array,
130     kExternalInt16Array,   kExternalUint32Array, kExternalInt32Array,
131     kExternalFloat32Array, kExternalFloat64Array};
132
133 }  // namespace
134
135
136 class SimplifiedBufferAccessOperatorTest
137     : public TestWithZone,
138       public ::testing::WithParamInterface<ExternalArrayType> {};
139
140
141 TEST_P(SimplifiedBufferAccessOperatorTest, InstancesAreGloballyShared) {
142   BufferAccess const access(GetParam());
143   SimplifiedOperatorBuilder simplified1(zone());
144   SimplifiedOperatorBuilder simplified2(zone());
145   EXPECT_EQ(simplified1.LoadBuffer(access), simplified2.LoadBuffer(access));
146   EXPECT_EQ(simplified1.StoreBuffer(access), simplified2.StoreBuffer(access));
147 }
148
149
150 TEST_P(SimplifiedBufferAccessOperatorTest, LoadBuffer) {
151   SimplifiedOperatorBuilder simplified(zone());
152   BufferAccess const access(GetParam());
153   const Operator* op = simplified.LoadBuffer(access);
154
155   EXPECT_EQ(IrOpcode::kLoadBuffer, op->opcode());
156   EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
157   EXPECT_EQ(access, BufferAccessOf(op));
158
159   EXPECT_EQ(3, op->ValueInputCount());
160   EXPECT_EQ(1, op->EffectInputCount());
161   EXPECT_EQ(1, op->ControlInputCount());
162   EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
163
164   EXPECT_EQ(1, op->ValueOutputCount());
165   EXPECT_EQ(1, op->EffectOutputCount());
166   EXPECT_EQ(0, op->ControlOutputCount());
167 }
168
169
170 TEST_P(SimplifiedBufferAccessOperatorTest, StoreBuffer) {
171   SimplifiedOperatorBuilder simplified(zone());
172   BufferAccess const access(GetParam());
173   const Operator* op = simplified.StoreBuffer(access);
174
175   EXPECT_EQ(IrOpcode::kStoreBuffer, op->opcode());
176   EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
177   EXPECT_EQ(access, BufferAccessOf(op));
178
179   EXPECT_EQ(4, op->ValueInputCount());
180   EXPECT_EQ(1, op->EffectInputCount());
181   EXPECT_EQ(1, op->ControlInputCount());
182   EXPECT_EQ(6, OperatorProperties::GetTotalInputCount(op));
183
184   EXPECT_EQ(0, op->ValueOutputCount());
185   EXPECT_EQ(1, op->EffectOutputCount());
186   EXPECT_EQ(0, op->ControlOutputCount());
187 }
188
189
190 INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
191                         SimplifiedBufferAccessOperatorTest,
192                         ::testing::ValuesIn(kExternalArrayTypes));
193
194
195 // -----------------------------------------------------------------------------
196 // Element access operators.
197
198
199 namespace {
200
201 const ElementAccess kElementAccesses[] = {
202     {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), kMachAnyTagged},
203     {kUntaggedBase, 0, Type::Any(), kMachInt8},
204     {kUntaggedBase, 0, Type::Any(), kMachInt16},
205     {kUntaggedBase, 0, Type::Any(), kMachInt32},
206     {kUntaggedBase, 0, Type::Any(), kMachUint8},
207     {kUntaggedBase, 0, Type::Any(), kMachUint16},
208     {kUntaggedBase, 0, Type::Any(), kMachUint32},
209     {kUntaggedBase, 0, Type::Signed32(), kMachInt8},
210     {kUntaggedBase, 0, Type::Unsigned32(), kMachUint8},
211     {kUntaggedBase, 0, Type::Signed32(), kMachInt16},
212     {kUntaggedBase, 0, Type::Unsigned32(), kMachUint16},
213     {kUntaggedBase, 0, Type::Signed32(), kMachInt32},
214     {kUntaggedBase, 0, Type::Unsigned32(), kMachUint32},
215     {kUntaggedBase, 0, Type::Number(), kRepFloat32},
216     {kUntaggedBase, 0, Type::Number(), kRepFloat64},
217     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
218      kMachInt8},
219     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
220      kMachUint8},
221     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
222      kMachInt16},
223     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
224      kMachUint16},
225     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
226      kMachInt32},
227     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
228      kMachUint32},
229     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
230      kRepFloat32},
231     {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
232      kRepFloat64}};
233
234 }  // namespace
235
236
237 class SimplifiedElementAccessOperatorTest
238     : public TestWithZone,
239       public ::testing::WithParamInterface<ElementAccess> {};
240
241
242 TEST_P(SimplifiedElementAccessOperatorTest, LoadElement) {
243   SimplifiedOperatorBuilder simplified(zone());
244   const ElementAccess& access = GetParam();
245   const Operator* op = simplified.LoadElement(access);
246
247   EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
248   EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
249   EXPECT_EQ(access, ElementAccessOf(op));
250
251   EXPECT_EQ(2, op->ValueInputCount());
252   EXPECT_EQ(1, op->EffectInputCount());
253   EXPECT_EQ(1, op->ControlInputCount());
254   EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
255
256   EXPECT_EQ(1, op->ValueOutputCount());
257   EXPECT_EQ(1, op->EffectOutputCount());
258   EXPECT_EQ(0, op->ControlOutputCount());
259 }
260
261
262 TEST_P(SimplifiedElementAccessOperatorTest, StoreElement) {
263   SimplifiedOperatorBuilder simplified(zone());
264   const ElementAccess& access = GetParam();
265   const Operator* op = simplified.StoreElement(access);
266
267   EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
268   EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
269   EXPECT_EQ(access, ElementAccessOf(op));
270
271   EXPECT_EQ(3, op->ValueInputCount());
272   EXPECT_EQ(1, op->EffectInputCount());
273   EXPECT_EQ(1, op->ControlInputCount());
274   EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
275
276   EXPECT_EQ(0, op->ValueOutputCount());
277   EXPECT_EQ(1, op->EffectOutputCount());
278   EXPECT_EQ(0, op->ControlOutputCount());
279 }
280
281
282 INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
283                         SimplifiedElementAccessOperatorTest,
284                         ::testing::ValuesIn(kElementAccesses));
285
286 }  // namespace compiler
287 }  // namespace internal
288 }  // namespace v8