blob: 4014f24e900c03dd47da63031581c3fd9de1150c [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
5#include "src/compiler/simplified-operator.h"
6
7#include "src/compiler/operator-properties-inl.h"
8#include "src/test/test-utils.h"
9
10namespace v8 {
11namespace internal {
12namespace compiler {
13
14// TODO(bmeurer): Drop once we use std::ostream instead of our OStream.
15inline std::ostream& operator<<(std::ostream& os, const ElementAccess& access) {
16 OStringStream ost;
17 ost << access;
18 return os << ost.c_str();
19}
20
21
22// -----------------------------------------------------------------------------
23// Pure operators.
24
25
26namespace {
27
28struct PureOperator {
29 const Operator* (SimplifiedOperatorBuilder::*constructor)();
30 IrOpcode::Value opcode;
31 Operator::Properties properties;
32 int value_input_count;
33};
34
35
36std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
37 return os << IrOpcode::Mnemonic(pop.opcode);
38}
39
40
41const PureOperator kPureOperators[] = {
42#define PURE(Name, properties, input_count) \
43 { \
44 &SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
45 Operator::kPure | properties, input_count \
46 }
47 PURE(BooleanNot, Operator::kNoProperties, 1),
48 PURE(NumberEqual, Operator::kCommutative, 2),
49 PURE(NumberLessThan, Operator::kNoProperties, 2),
50 PURE(NumberLessThanOrEqual, Operator::kNoProperties, 2),
51 PURE(NumberAdd, Operator::kCommutative, 2),
52 PURE(NumberSubtract, Operator::kNoProperties, 2),
53 PURE(NumberMultiply, Operator::kCommutative, 2),
54 PURE(NumberDivide, Operator::kNoProperties, 2),
55 PURE(NumberModulus, Operator::kNoProperties, 2),
56 PURE(NumberToInt32, Operator::kNoProperties, 1),
57 PURE(NumberToUint32, Operator::kNoProperties, 1),
58 PURE(StringEqual, Operator::kCommutative, 2),
59 PURE(StringLessThan, Operator::kNoProperties, 2),
60 PURE(StringLessThanOrEqual, Operator::kNoProperties, 2),
61 PURE(StringAdd, Operator::kNoProperties, 2),
62 PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
63 PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
64 PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
65 PURE(ChangeInt32ToTagged, Operator::kNoProperties, 1),
66 PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1),
67 PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1),
68 PURE(ChangeBoolToBit, Operator::kNoProperties, 1),
69 PURE(ChangeBitToBool, Operator::kNoProperties, 1)
70#undef PURE
71};
72
73} // namespace
74
75
76class SimplifiedPureOperatorTest
77 : public TestWithZone,
78 public ::testing::WithParamInterface<PureOperator> {};
79
80
81TEST_P(SimplifiedPureOperatorTest, InstancesAreGloballyShared) {
82 const PureOperator& pop = GetParam();
83 SimplifiedOperatorBuilder simplified1(zone());
84 SimplifiedOperatorBuilder simplified2(zone());
85 EXPECT_EQ((simplified1.*pop.constructor)(), (simplified2.*pop.constructor)());
86}
87
88
89TEST_P(SimplifiedPureOperatorTest, NumberOfInputsAndOutputs) {
90 SimplifiedOperatorBuilder simplified(zone());
91 const PureOperator& pop = GetParam();
92 const Operator* op = (simplified.*pop.constructor)();
93
94 EXPECT_EQ(pop.value_input_count, OperatorProperties::GetValueInputCount(op));
95 EXPECT_EQ(0, OperatorProperties::GetEffectInputCount(op));
96 EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
97 EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
98
99 EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
100 EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
101 EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
102}
103
104
105TEST_P(SimplifiedPureOperatorTest, OpcodeIsCorrect) {
106 SimplifiedOperatorBuilder simplified(zone());
107 const PureOperator& pop = GetParam();
108 const Operator* op = (simplified.*pop.constructor)();
109 EXPECT_EQ(pop.opcode, op->opcode());
110}
111
112
113TEST_P(SimplifiedPureOperatorTest, Properties) {
114 SimplifiedOperatorBuilder simplified(zone());
115 const PureOperator& pop = GetParam();
116 const Operator* op = (simplified.*pop.constructor)();
117 EXPECT_EQ(pop.properties, op->properties() & pop.properties);
118}
119
120INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest, SimplifiedPureOperatorTest,
121 ::testing::ValuesIn(kPureOperators));
122
123
124// -----------------------------------------------------------------------------
125// Element access operators.
126
127namespace {
128
129const ElementAccess kElementAccesses[] = {
130 {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), kMachAnyTagged},
131 {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
132 kMachInt8},
133 {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
134 kMachInt16},
135 {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
136 kMachInt32},
137 {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
138 kMachUint8},
139 {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
140 kMachUint16},
141 {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
142 kMachUint32},
143 {kUntaggedBase, 0, Type::Signed32(), kMachInt8},
144 {kUntaggedBase, 0, Type::Unsigned32(), kMachUint8},
145 {kUntaggedBase, 0, Type::Signed32(), kMachInt16},
146 {kUntaggedBase, 0, Type::Unsigned32(), kMachUint16},
147 {kUntaggedBase, 0, Type::Signed32(), kMachInt32},
148 {kUntaggedBase, 0, Type::Unsigned32(), kMachUint32},
149 {kUntaggedBase, 0, Type::Number(), kRepFloat32},
150 {kUntaggedBase, 0, Type::Number(), kRepFloat64},
151 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
152 kMachInt8},
153 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
154 kMachUint8},
155 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
156 kMachInt16},
157 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
158 kMachUint16},
159 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
160 kMachInt32},
161 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
162 kMachUint32},
163 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
164 kRepFloat32},
165 {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
166 kRepFloat64}};
167
168} // namespace
169
170
171class SimplifiedElementAccessOperatorTest
172 : public TestWithZone,
173 public ::testing::WithParamInterface<ElementAccess> {};
174
175
176TEST_P(SimplifiedElementAccessOperatorTest, LoadElement) {
177 SimplifiedOperatorBuilder simplified(zone());
178 const ElementAccess& access = GetParam();
179 const Operator* op = simplified.LoadElement(access);
180
181 EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
182 EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
183 EXPECT_EQ(access, ElementAccessOf(op));
184
185 EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
186 EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
187 EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
188 EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
189
190 EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
191 EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
192 EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
193}
194
195
196TEST_P(SimplifiedElementAccessOperatorTest, StoreElement) {
197 SimplifiedOperatorBuilder simplified(zone());
198 const ElementAccess& access = GetParam();
199 const Operator* op = simplified.StoreElement(access);
200
201 EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
202 EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
203 EXPECT_EQ(access, ElementAccessOf(op));
204
205 EXPECT_EQ(4, OperatorProperties::GetValueInputCount(op));
206 EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
207 EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
208 EXPECT_EQ(6, OperatorProperties::GetTotalInputCount(op));
209
210 EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
211 EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
212 EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
213}
214
215
216INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
217 SimplifiedElementAccessOperatorTest,
218 ::testing::ValuesIn(kElementAccesses));
219
220} // namespace compiler
221} // namespace internal
222} // namespace v8