blob: 3343c8f1d27233f22580a83a7adcb02c45110c5c [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include "src/compiler/opcodes.h"
6#include "src/compiler/operator.h"
7#include "src/compiler/operator-properties.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/compiler/simplified-operator.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +01009#include "src/types.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include "test/unittests/test-utils.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011
12namespace v8 {
13namespace internal {
14namespace compiler {
15
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016// -----------------------------------------------------------------------------
17// Pure operators.
18
19
20namespace {
21
22struct PureOperator {
23 const Operator* (SimplifiedOperatorBuilder::*constructor)();
24 IrOpcode::Value opcode;
25 Operator::Properties properties;
26 int value_input_count;
27};
28
29
30std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
31 return os << IrOpcode::Mnemonic(pop.opcode);
32}
33
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034const PureOperator kPureOperators[] = {
35#define PURE(Name, properties, input_count) \
36 { \
37 &SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
38 Operator::kPure | properties, input_count \
39 }
40 PURE(BooleanNot, Operator::kNoProperties, 1),
Emily Bernierd0a1eb72015-03-24 16:35:39 -040041 PURE(BooleanToNumber, Operator::kNoProperties, 1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042 PURE(NumberEqual, Operator::kCommutative, 2),
43 PURE(NumberLessThan, Operator::kNoProperties, 2),
44 PURE(NumberLessThanOrEqual, Operator::kNoProperties, 2),
45 PURE(NumberAdd, Operator::kCommutative, 2),
46 PURE(NumberSubtract, Operator::kNoProperties, 2),
47 PURE(NumberMultiply, Operator::kCommutative, 2),
48 PURE(NumberDivide, Operator::kNoProperties, 2),
49 PURE(NumberModulus, Operator::kNoProperties, 2),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050 PURE(NumberBitwiseOr, Operator::kCommutative, 2),
51 PURE(NumberBitwiseXor, Operator::kCommutative, 2),
52 PURE(NumberBitwiseAnd, Operator::kCommutative, 2),
53 PURE(NumberShiftLeft, Operator::kNoProperties, 2),
54 PURE(NumberShiftRight, Operator::kNoProperties, 2),
55 PURE(NumberShiftRightLogical, Operator::kNoProperties, 2),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000056 PURE(NumberToInt32, Operator::kNoProperties, 1),
57 PURE(NumberToUint32, Operator::kNoProperties, 1),
Ben Murdochc5610432016-08-08 18:44:38 +010058 PURE(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
60 PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
61 PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
62 PURE(ChangeInt32ToTagged, Operator::kNoProperties, 1),
63 PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1),
64 PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1),
Ben Murdochc5610432016-08-08 18:44:38 +010065 PURE(ChangeTaggedToBit, Operator::kNoProperties, 1),
66 PURE(ChangeBitToTagged, Operator::kNoProperties, 1),
67 PURE(TruncateTaggedToWord32, Operator::kNoProperties, 1),
Ben Murdoch097c5b22016-05-18 11:27:45 +010068 PURE(ObjectIsNumber, Operator::kNoProperties, 1),
69 PURE(ObjectIsReceiver, Operator::kNoProperties, 1),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 PURE(ObjectIsSmi, Operator::kNoProperties, 1)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071#undef PURE
72};
73
74} // namespace
75
76
77class SimplifiedPureOperatorTest
78 : public TestWithZone,
79 public ::testing::WithParamInterface<PureOperator> {};
80
81
82TEST_P(SimplifiedPureOperatorTest, InstancesAreGloballyShared) {
83 const PureOperator& pop = GetParam();
84 SimplifiedOperatorBuilder simplified1(zone());
85 SimplifiedOperatorBuilder simplified2(zone());
86 EXPECT_EQ((simplified1.*pop.constructor)(), (simplified2.*pop.constructor)());
87}
88
89
90TEST_P(SimplifiedPureOperatorTest, NumberOfInputsAndOutputs) {
91 SimplifiedOperatorBuilder simplified(zone());
92 const PureOperator& pop = GetParam();
93 const Operator* op = (simplified.*pop.constructor)();
94
Emily Bernierd0a1eb72015-03-24 16:35:39 -040095 EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
96 EXPECT_EQ(0, op->EffectInputCount());
97 EXPECT_EQ(0, op->ControlInputCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000098 EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
99
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400100 EXPECT_EQ(1, op->ValueOutputCount());
101 EXPECT_EQ(0, op->EffectOutputCount());
102 EXPECT_EQ(0, op->ControlOutputCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103}
104
105
106TEST_P(SimplifiedPureOperatorTest, OpcodeIsCorrect) {
107 SimplifiedOperatorBuilder simplified(zone());
108 const PureOperator& pop = GetParam();
109 const Operator* op = (simplified.*pop.constructor)();
110 EXPECT_EQ(pop.opcode, op->opcode());
111}
112
113
114TEST_P(SimplifiedPureOperatorTest, Properties) {
115 SimplifiedOperatorBuilder simplified(zone());
116 const PureOperator& pop = GetParam();
117 const Operator* op = (simplified.*pop.constructor)();
118 EXPECT_EQ(pop.properties, op->properties() & pop.properties);
119}
120
121INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest, SimplifiedPureOperatorTest,
122 ::testing::ValuesIn(kPureOperators));
123
124
125// -----------------------------------------------------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400126// Buffer access operators.
127
128
129namespace {
130
131const ExternalArrayType kExternalArrayTypes[] = {
132 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array,
133 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array,
134 kExternalFloat32Array, kExternalFloat64Array};
135
136} // namespace
137
138
139class SimplifiedBufferAccessOperatorTest
140 : public TestWithZone,
141 public ::testing::WithParamInterface<ExternalArrayType> {};
142
143
144TEST_P(SimplifiedBufferAccessOperatorTest, InstancesAreGloballyShared) {
145 BufferAccess const access(GetParam());
146 SimplifiedOperatorBuilder simplified1(zone());
147 SimplifiedOperatorBuilder simplified2(zone());
148 EXPECT_EQ(simplified1.LoadBuffer(access), simplified2.LoadBuffer(access));
149 EXPECT_EQ(simplified1.StoreBuffer(access), simplified2.StoreBuffer(access));
150}
151
152
153TEST_P(SimplifiedBufferAccessOperatorTest, LoadBuffer) {
154 SimplifiedOperatorBuilder simplified(zone());
155 BufferAccess const access(GetParam());
156 const Operator* op = simplified.LoadBuffer(access);
157
158 EXPECT_EQ(IrOpcode::kLoadBuffer, op->opcode());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100159 EXPECT_EQ(Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
160 op->properties());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400161 EXPECT_EQ(access, BufferAccessOf(op));
162
163 EXPECT_EQ(3, op->ValueInputCount());
164 EXPECT_EQ(1, op->EffectInputCount());
165 EXPECT_EQ(1, op->ControlInputCount());
166 EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
167
168 EXPECT_EQ(1, op->ValueOutputCount());
169 EXPECT_EQ(1, op->EffectOutputCount());
170 EXPECT_EQ(0, op->ControlOutputCount());
171}
172
173
174TEST_P(SimplifiedBufferAccessOperatorTest, StoreBuffer) {
175 SimplifiedOperatorBuilder simplified(zone());
176 BufferAccess const access(GetParam());
177 const Operator* op = simplified.StoreBuffer(access);
178
179 EXPECT_EQ(IrOpcode::kStoreBuffer, op->opcode());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100180 EXPECT_EQ(Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
181 op->properties());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400182 EXPECT_EQ(access, BufferAccessOf(op));
183
184 EXPECT_EQ(4, op->ValueInputCount());
185 EXPECT_EQ(1, op->EffectInputCount());
186 EXPECT_EQ(1, op->ControlInputCount());
187 EXPECT_EQ(6, OperatorProperties::GetTotalInputCount(op));
188
189 EXPECT_EQ(0, op->ValueOutputCount());
190 EXPECT_EQ(1, op->EffectOutputCount());
191 EXPECT_EQ(0, op->ControlOutputCount());
192}
193
194
195INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
196 SimplifiedBufferAccessOperatorTest,
197 ::testing::ValuesIn(kExternalArrayTypes));
198
199
200// -----------------------------------------------------------------------------
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201// Element access operators.
202
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400203
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000204namespace {
205
206const ElementAccess kElementAccesses[] = {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 {kTaggedBase, FixedArray::kHeaderSize, Type::Any(),
Ben Murdochc5610432016-08-08 18:44:38 +0100208 MachineType::AnyTagged(), kFullWriteBarrier},
209 {kUntaggedBase, 0, Type::Any(), MachineType::Int8(), kNoWriteBarrier},
210 {kUntaggedBase, 0, Type::Any(), MachineType::Int16(), kNoWriteBarrier},
211 {kUntaggedBase, 0, Type::Any(), MachineType::Int32(), kNoWriteBarrier},
212 {kUntaggedBase, 0, Type::Any(), MachineType::Uint8(), kNoWriteBarrier},
213 {kUntaggedBase, 0, Type::Any(), MachineType::Uint16(), kNoWriteBarrier},
214 {kUntaggedBase, 0, Type::Any(), MachineType::Uint32(), kNoWriteBarrier},
215 {kUntaggedBase, 0, Type::Signed32(), MachineType::Int8(), kNoWriteBarrier},
216 {kUntaggedBase, 0, Type::Unsigned32(), MachineType::Uint8(),
217 kNoWriteBarrier},
218 {kUntaggedBase, 0, Type::Signed32(), MachineType::Int16(), kNoWriteBarrier},
219 {kUntaggedBase, 0, Type::Unsigned32(), MachineType::Uint16(),
220 kNoWriteBarrier},
221 {kUntaggedBase, 0, Type::Signed32(), MachineType::Int32(), kNoWriteBarrier},
222 {kUntaggedBase, 0, Type::Unsigned32(), MachineType::Uint32(),
223 kNoWriteBarrier},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 {kUntaggedBase, 0, Type::Number(),
Ben Murdochc5610432016-08-08 18:44:38 +0100225 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone),
226 kNoWriteBarrier},
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 {kUntaggedBase, 0, Type::Number(),
Ben Murdochc5610432016-08-08 18:44:38 +0100228 MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone),
229 kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
Ben Murdochc5610432016-08-08 18:44:38 +0100231 MachineType::Int8(), kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000232 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
Ben Murdochc5610432016-08-08 18:44:38 +0100233 MachineType::Uint8(), kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
Ben Murdochc5610432016-08-08 18:44:38 +0100235 MachineType::Int16(), kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
Ben Murdochc5610432016-08-08 18:44:38 +0100237 MachineType::Uint16(), kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000238 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
Ben Murdochc5610432016-08-08 18:44:38 +0100239 MachineType::Int32(), kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
Ben Murdochc5610432016-08-08 18:44:38 +0100241 MachineType::Uint32(), kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
Ben Murdochc5610432016-08-08 18:44:38 +0100243 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone),
244 kNoWriteBarrier},
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
Ben Murdochc5610432016-08-08 18:44:38 +0100246 MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone),
247 kNoWriteBarrier}};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000248
249} // namespace
250
251
252class SimplifiedElementAccessOperatorTest
253 : public TestWithZone,
254 public ::testing::WithParamInterface<ElementAccess> {};
255
256
257TEST_P(SimplifiedElementAccessOperatorTest, LoadElement) {
258 SimplifiedOperatorBuilder simplified(zone());
259 const ElementAccess& access = GetParam();
260 const Operator* op = simplified.LoadElement(access);
261
262 EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100263 EXPECT_EQ(Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
264 op->properties());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265 EXPECT_EQ(access, ElementAccessOf(op));
266
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400267 EXPECT_EQ(2, op->ValueInputCount());
268 EXPECT_EQ(1, op->EffectInputCount());
269 EXPECT_EQ(1, op->ControlInputCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000270 EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
271
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400272 EXPECT_EQ(1, op->ValueOutputCount());
273 EXPECT_EQ(1, op->EffectOutputCount());
274 EXPECT_EQ(0, op->ControlOutputCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000275}
276
277
278TEST_P(SimplifiedElementAccessOperatorTest, StoreElement) {
279 SimplifiedOperatorBuilder simplified(zone());
280 const ElementAccess& access = GetParam();
281 const Operator* op = simplified.StoreElement(access);
282
283 EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100284 EXPECT_EQ(Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
285 op->properties());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286 EXPECT_EQ(access, ElementAccessOf(op));
287
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400288 EXPECT_EQ(3, op->ValueInputCount());
289 EXPECT_EQ(1, op->EffectInputCount());
290 EXPECT_EQ(1, op->ControlInputCount());
291 EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400293 EXPECT_EQ(0, op->ValueOutputCount());
294 EXPECT_EQ(1, op->EffectOutputCount());
295 EXPECT_EQ(0, op->ControlOutputCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000296}
297
298
299INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
300 SimplifiedElementAccessOperatorTest,
301 ::testing::ValuesIn(kElementAccesses));
302
303} // namespace compiler
304} // namespace internal
305} // namespace v8