OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/machine-operator.h" | 5 #include "src/compiler/machine-operator.h" |
6 #include "src/compiler/opcodes.h" | 6 #include "src/compiler/opcodes.h" |
7 #include "src/compiler/operator.h" | 7 #include "src/compiler/operator.h" |
8 #include "src/compiler/operator-properties.h" | 8 #include "src/compiler/operator-properties.h" |
9 #include "test/unittests/test-utils.h" | 9 #include "test/unittests/test-utils.h" |
10 | 10 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 } | 142 } |
143 | 143 |
144 | 144 |
145 INSTANTIATE_TEST_CASE_P( | 145 INSTANTIATE_TEST_CASE_P( |
146 MachineOperatorTest, MachineStoreOperatorTest, | 146 MachineOperatorTest, MachineStoreOperatorTest, |
147 ::testing::Combine( | 147 ::testing::Combine( |
148 ::testing::ValuesIn(kMachineReps), | 148 ::testing::ValuesIn(kMachineReps), |
149 ::testing::Combine(::testing::ValuesIn(kMachineTypes), | 149 ::testing::Combine(::testing::ValuesIn(kMachineTypes), |
150 ::testing::Values(kNoWriteBarrier, | 150 ::testing::Values(kNoWriteBarrier, |
151 kFullWriteBarrier)))); | 151 kFullWriteBarrier)))); |
152 | 152 #endif |
153 | 153 |
154 // ----------------------------------------------------------------------------- | 154 // ----------------------------------------------------------------------------- |
155 // Pure operators. | 155 // Pure operators. |
156 | 156 |
157 | |
158 namespace { | 157 namespace { |
159 | 158 |
160 struct PureOperator { | 159 typedef const Operator* (MachineOperatorBuilder::*OperatorConstructor)(); |
161 const Operator* (MachineOperatorBuilder::*constructor)(); | 160 typedef const OptionalOperator ( |
162 IrOpcode::Value opcode; | 161 MachineOperatorBuilder::*OptionalOperatorConstructor)(); |
163 int value_input_count; | 162 } |
Benedikt Meurer
2015/05/07 04:48:38
Add // namespace comment after } and empty line be
| |
164 int control_input_count; | 163 |
165 int value_output_count; | 164 |
165 class MachinePureOperatorTest : public TestWithZone { | |
166 protected: | |
167 void CheckGlobalCaching(OperatorConstructor constructor) { | |
168 MachineOperatorBuilder machine1(zone(), word_type()); | |
169 MachineOperatorBuilder machine2(zone(), word_type()); | |
170 EXPECT_EQ((machine1.*constructor)(), (machine2.*constructor)()); | |
Benedikt Meurer
2015/05/07 04:48:38
Don't move test expectations into helper functions
titzer
2015/05/11 11:55:29
I can inline them directly into the MACRO.
| |
171 } | |
172 | |
173 void CheckCounts(OperatorConstructor constructor, int value_input_count, | |
174 int control_input_count, int value_output_count) { | |
175 MachineOperatorBuilder machine(zone(), word_type()); | |
176 const Operator* op = (machine.*constructor)(); | |
177 EXPECT_EQ(value_input_count, op->ValueInputCount()); | |
178 EXPECT_EQ(control_input_count, op->ControlInputCount()); | |
179 EXPECT_EQ(value_output_count, op->ValueOutputCount()); | |
180 } | |
181 | |
182 void CheckGlobalCaching(OptionalOperatorConstructor constructor, | |
183 MachineOperatorBuilder::Flag enabling_flag) { | |
184 MachineOperatorBuilder machine1(zone(), word_type(), enabling_flag); | |
185 MachineOperatorBuilder machine2(zone(), word_type(), enabling_flag); | |
186 EXPECT_EQ((machine1.*constructor)().op(), (machine2.*constructor)().op()); | |
187 } | |
188 | |
189 void CheckEnablingFlag(OptionalOperatorConstructor constructor, | |
190 MachineOperatorBuilder::Flag enabling_flag) { | |
191 MachineOperatorBuilder machine1(zone(), word_type(), enabling_flag); | |
192 MachineOperatorBuilder machine2(zone(), word_type()); | |
193 EXPECT_TRUE((machine1.*constructor)().supported()); | |
194 EXPECT_FALSE((machine2.*constructor)().supported()); | |
195 } | |
196 | |
197 private: | |
198 MachineType word_type() { return kMachPtr; } | |
166 }; | 199 }; |
167 | 200 |
168 | 201 |
169 std::ostream& operator<<(std::ostream& os, const PureOperator& pop) { | 202 TEST_F(MachinePureOperatorTest, PureOperators) { |
170 return os << IrOpcode::Mnemonic(pop.opcode); | 203 #define PURE(Name, value_input_count, control_input_count, value_output_count) \ |
204 CheckGlobalCaching(&MachineOperatorBuilder::Name); \ | |
205 CheckCounts(&MachineOperatorBuilder::Name, value_input_count, \ | |
206 control_input_count, value_output_count); | |
207 | |
208 PURE(Word32And, 2, 0, 1); | |
Benedikt Meurer
2015/05/07 04:48:38
This is a lot of boilerplate and macroism and indi
titzer
2015/05/11 11:55:29
I can inline the helper functions into the macro,
Benedikt Meurer
2015/05/12 05:15:41
What's the point of putting everything into the ma
| |
209 PURE(Word32Or, 2, 0, 1); | |
210 PURE(Word32Xor, 2, 0, 1); | |
211 PURE(Word32Shl, 2, 0, 1); | |
212 PURE(Word32Shr, 2, 0, 1); | |
213 PURE(Word32Sar, 2, 0, 1); | |
214 PURE(Word32Ror, 2, 0, 1); | |
215 PURE(Word32Equal, 2, 0, 1); | |
216 PURE(Word32Clz, 1, 0, 1); | |
217 PURE(Word64And, 2, 0, 1); | |
218 PURE(Word64Or, 2, 0, 1); | |
219 PURE(Word64Xor, 2, 0, 1); | |
220 PURE(Word64Shl, 2, 0, 1); | |
221 PURE(Word64Shr, 2, 0, 1); | |
222 PURE(Word64Sar, 2, 0, 1); | |
223 PURE(Word64Ror, 2, 0, 1); | |
224 PURE(Word64Equal, 2, 0, 1); | |
225 PURE(Int32Add, 2, 0, 1); | |
226 PURE(Int32AddWithOverflow, 2, 0, 2); | |
227 PURE(Int32Sub, 2, 0, 1); | |
228 PURE(Int32SubWithOverflow, 2, 0, 2); | |
229 PURE(Int32Mul, 2, 0, 1); | |
230 PURE(Int32MulHigh, 2, 0, 1); | |
231 PURE(Int32Div, 2, 1, 1); | |
232 PURE(Uint32Div, 2, 1, 1); | |
233 PURE(Int32Mod, 2, 1, 1); | |
234 PURE(Uint32Mod, 2, 1, 1); | |
235 PURE(Int32LessThan, 2, 0, 1); | |
236 PURE(Int32LessThanOrEqual, 2, 0, 1); | |
237 PURE(Uint32LessThan, 2, 0, 1); | |
238 PURE(Uint32LessThanOrEqual, 2, 0, 1); | |
239 PURE(Int64Add, 2, 0, 1); | |
240 PURE(Int64Sub, 2, 0, 1); | |
241 PURE(Int64Mul, 2, 0, 1); | |
242 PURE(Int64Div, 2, 0, 1); | |
243 PURE(Uint64Div, 2, 0, 1); | |
244 PURE(Int64Mod, 2, 0, 1); | |
245 PURE(Uint64Mod, 2, 0, 1); | |
246 PURE(Int64LessThan, 2, 0, 1); | |
247 PURE(Int64LessThanOrEqual, 2, 0, 1); | |
248 PURE(Uint64LessThan, 2, 0, 1); | |
249 PURE(ChangeFloat32ToFloat64, 1, 0, 1); | |
250 PURE(ChangeFloat64ToInt32, 1, 0, 1); | |
251 PURE(ChangeFloat64ToUint32, 1, 0, 1); | |
252 PURE(ChangeInt32ToInt64, 1, 0, 1); | |
253 PURE(ChangeUint32ToFloat64, 1, 0, 1); | |
254 PURE(ChangeUint32ToUint64, 1, 0, 1); | |
255 PURE(TruncateFloat64ToFloat32, 1, 0, 1); | |
256 PURE(TruncateFloat64ToInt32, 1, 0, 1); | |
257 PURE(TruncateInt64ToInt32, 1, 0, 1); | |
258 PURE(Float32Add, 2, 0, 1); | |
259 PURE(Float32Sub, 2, 0, 1); | |
260 PURE(Float32Mul, 2, 0, 1); | |
261 PURE(Float32Div, 2, 0, 1); | |
262 PURE(Float32Sqrt, 1, 0, 1); | |
263 PURE(Float32Equal, 2, 0, 1); | |
264 PURE(Float32LessThan, 2, 0, 1); | |
265 PURE(Float32LessThanOrEqual, 2, 0, 1); | |
266 PURE(Float64Add, 2, 0, 1); | |
267 PURE(Float64Sub, 2, 0, 1); | |
268 PURE(Float64Mul, 2, 0, 1); | |
269 PURE(Float64Div, 2, 0, 1); | |
270 PURE(Float64Mod, 2, 0, 1); | |
271 PURE(Float64Sqrt, 1, 0, 1); | |
272 PURE(Float64Equal, 2, 0, 1); | |
273 PURE(Float64LessThan, 2, 0, 1); | |
274 PURE(Float64LessThanOrEqual, 2, 0, 1); | |
275 PURE(LoadStackPointer, 0, 0, 1); | |
276 PURE(Float64ExtractLowWord32, 1, 0, 1); | |
277 PURE(Float64ExtractHighWord32, 1, 0, 1); | |
278 PURE(Float64InsertLowWord32, 2, 0, 1); | |
279 PURE(Float64InsertHighWord32, 2, 0, 1); | |
280 #undef PURE | |
171 } | 281 } |
172 | 282 |
173 | 283 |
174 const PureOperator kPureOperators[] = { | 284 TEST_F(MachinePureOperatorTest, PureOptionalOperators) { |
175 #define PURE(Name, value_input_count, control_input_count, value_output_count) \ | 285 #define OPTIONAL(Name, value_input_count, control_input_count, \ |
176 { \ | 286 value_output_count) \ |
177 &MachineOperatorBuilder::Name, IrOpcode::k##Name, value_input_count, \ | 287 CheckGlobalCaching(&MachineOperatorBuilder::Name, \ |
178 control_input_count, value_output_count \ | 288 MachineOperatorBuilder::k##Name); \ |
179 } | 289 CheckEnablingFlag(&MachineOperatorBuilder::Name, \ |
180 PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1), | 290 MachineOperatorBuilder::k##Name); |
181 PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1), | |
182 PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1), | |
183 PURE(Word32Equal, 2, 0, 1), PURE(Word32Clz, 1, 0, 1), | |
184 PURE(Word64And, 2, 0, 1), PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1), | |
185 PURE(Word64Shl, 2, 0, 1), PURE(Word64Shr, 2, 0, 1), | |
186 PURE(Word64Sar, 2, 0, 1), PURE(Word64Ror, 2, 0, 1), | |
187 PURE(Word64Equal, 2, 0, 1), PURE(Int32Add, 2, 0, 1), | |
188 PURE(Int32AddWithOverflow, 2, 0, 2), PURE(Int32Sub, 2, 0, 1), | |
189 PURE(Int32SubWithOverflow, 2, 0, 2), PURE(Int32Mul, 2, 0, 1), | |
190 PURE(Int32MulHigh, 2, 0, 1), PURE(Int32Div, 2, 1, 1), | |
191 PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1), PURE(Uint32Mod, 2, 1, 1), | |
192 PURE(Int32LessThan, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1), | |
193 PURE(Uint32LessThan, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1), | |
194 PURE(Int64Add, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), | |
195 PURE(Int64Div, 2, 0, 1), PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1), | |
196 PURE(Uint64Mod, 2, 0, 1), PURE(Int64LessThan, 2, 0, 1), | |
197 PURE(Int64LessThanOrEqual, 2, 0, 1), PURE(Uint64LessThan, 2, 0, 1), | |
198 PURE(ChangeFloat32ToFloat64, 1, 0, 1), PURE(ChangeFloat64ToInt32, 1, 0, 1), | |
199 PURE(ChangeFloat64ToUint32, 1, 0, 1), PURE(ChangeInt32ToInt64, 1, 0, 1), | |
200 PURE(ChangeUint32ToFloat64, 1, 0, 1), PURE(ChangeUint32ToUint64, 1, 0, 1), | |
201 PURE(TruncateFloat64ToFloat32, 1, 0, 1), | |
202 PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1, 0, 1), | |
203 PURE(Float32Add, 2, 0, 1), PURE(Float32Sub, 2, 0, 1), | |
204 PURE(Float32Mul, 2, 0, 1), PURE(Float32Div, 2, 0, 1), | |
205 PURE(Float32Abs, 1, 0, 1), PURE(Float32Sqrt, 1, 0, 1), | |
206 PURE(Float32Equal, 2, 0, 1), PURE(Float32LessThan, 2, 0, 1), | |
207 PURE(Float32LessThanOrEqual, 2, 0, 1), PURE(Float32Max, 2, 0, 1), | |
208 PURE(Float32Min, 2, 0, 1), PURE(Float64Add, 2, 0, 1), | |
209 PURE(Float64Sub, 2, 0, 1), PURE(Float64Mul, 2, 0, 1), | |
210 PURE(Float64Div, 2, 0, 1), PURE(Float64Mod, 2, 0, 1), | |
211 PURE(Float64Abs, 1, 0, 1), PURE(Float64Sqrt, 1, 0, 1), | |
212 PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1), | |
213 PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(Float64Max, 2, 0, 1), | |
214 PURE(Float64Min, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1), | |
215 PURE(Float64RoundDown, 1, 0, 1), PURE(Float64RoundTruncate, 1, 0, 1), | |
216 PURE(Float64RoundTiesAway, 1, 0, 1), PURE(Float64ExtractLowWord32, 1, 0, 1), | |
217 PURE(Float64ExtractHighWord32, 1, 0, 1), | |
218 PURE(Float64InsertLowWord32, 2, 0, 1), | |
219 PURE(Float64InsertHighWord32, 2, 0, 1) | |
220 #undef PURE | |
221 }; | |
222 | 291 |
223 | 292 OPTIONAL(Float32Max, 2, 0, 1); |
224 typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest; | 293 OPTIONAL(Float32Min, 2, 0, 1); |
225 | 294 OPTIONAL(Float32Abs, 1, 0, 1); |
226 } // namespace | 295 OPTIONAL(Float64Abs, 1, 0, 1); |
227 | 296 OPTIONAL(Float64Max, 2, 0, 1); |
228 | 297 OPTIONAL(Float64Min, 2, 0, 1); |
229 TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) { | 298 OPTIONAL(Float64RoundDown, 1, 0, 1); |
230 const PureOperator& pop = GetParam(); | 299 OPTIONAL(Float64RoundTruncate, 1, 0, 1); |
231 MachineOperatorBuilder machine1(zone(), type()); | 300 OPTIONAL(Float64RoundTiesAway, 1, 0, 1); |
232 MachineOperatorBuilder machine2(zone(), type()); | 301 #undef OPTIONAL |
233 EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)()); | |
234 } | 302 } |
235 | 303 |
236 | 304 |
237 TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) { | |
238 MachineOperatorBuilder machine(zone(), type()); | |
239 const PureOperator& pop = GetParam(); | |
240 const Operator* op = (machine.*pop.constructor)(); | |
241 | |
242 EXPECT_EQ(pop.value_input_count, op->ValueInputCount()); | |
243 EXPECT_EQ(0, op->EffectInputCount()); | |
244 EXPECT_EQ(pop.control_input_count, op->ControlInputCount()); | |
245 EXPECT_EQ(pop.value_input_count + pop.control_input_count, | |
246 OperatorProperties::GetTotalInputCount(op)); | |
247 | |
248 EXPECT_EQ(pop.value_output_count, op->ValueOutputCount()); | |
249 EXPECT_EQ(0, op->EffectOutputCount()); | |
250 EXPECT_EQ(0, op->ControlOutputCount()); | |
251 } | |
252 | |
253 | |
254 TEST_P(MachinePureOperatorTest, MarkedAsPure) { | |
255 MachineOperatorBuilder machine(zone(), type()); | |
256 const PureOperator& pop = GetParam(); | |
257 const Operator* op = (machine.*pop.constructor)(); | |
258 EXPECT_TRUE(op->HasProperty(Operator::kPure)); | |
259 } | |
260 | |
261 | |
262 TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) { | |
263 MachineOperatorBuilder machine(zone(), type()); | |
264 const PureOperator& pop = GetParam(); | |
265 const Operator* op = (machine.*pop.constructor)(); | |
266 EXPECT_EQ(pop.opcode, op->opcode()); | |
267 } | |
268 | |
269 | |
270 INSTANTIATE_TEST_CASE_P( | |
271 MachineOperatorTest, MachinePureOperatorTest, | |
272 ::testing::Combine(::testing::ValuesIn(kMachineReps), | |
273 ::testing::ValuesIn(kPureOperators))); | |
274 | |
275 #endif // GTEST_HAS_COMBINE | |
276 | |
277 | |
278 // ----------------------------------------------------------------------------- | 305 // ----------------------------------------------------------------------------- |
279 // Pseudo operators. | 306 // Pseudo operators. |
280 | 307 |
281 | 308 |
282 namespace { | 309 namespace { |
283 | 310 |
284 typedef TestWithZone MachineOperatorTest; | 311 typedef TestWithZone MachineOperatorTest; |
285 | 312 |
286 } // namespace | 313 } // namespace |
287 | 314 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
325 EXPECT_EQ(machine.Uint64Div(), machine.UintDiv()); | 352 EXPECT_EQ(machine.Uint64Div(), machine.UintDiv()); |
326 EXPECT_EQ(machine.Int64Mod(), machine.IntMod()); | 353 EXPECT_EQ(machine.Int64Mod(), machine.IntMod()); |
327 EXPECT_EQ(machine.Uint64Mod(), machine.UintMod()); | 354 EXPECT_EQ(machine.Uint64Mod(), machine.UintMod()); |
328 EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan()); | 355 EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan()); |
329 EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual()); | 356 EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual()); |
330 } | 357 } |
331 | 358 |
332 } // namespace compiler | 359 } // namespace compiler |
333 } // namespace internal | 360 } // namespace internal |
334 } // namespace v8 | 361 } // namespace v8 |
OLD | NEW |