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 struct PureOperator { |
161 const Operator* (MachineOperatorBuilder::*constructor)(); | 160 const Operator* (MachineOperatorBuilder::*constructor)(); |
162 IrOpcode::Value opcode; | 161 char const* const constructor_name; |
163 int value_input_count; | 162 int value_input_count; |
164 int control_input_count; | 163 int control_input_count; |
165 int value_output_count; | 164 int value_output_count; |
166 }; | 165 }; |
167 | 166 |
168 | 167 |
169 std::ostream& operator<<(std::ostream& os, const PureOperator& pop) { | 168 std::ostream& operator<<(std::ostream& os, PureOperator const& pop) { |
170 return os << IrOpcode::Mnemonic(pop.opcode); | 169 return os << pop.constructor_name; |
171 } | 170 } |
172 | 171 |
173 | |
174 const PureOperator kPureOperators[] = { | 172 const PureOperator kPureOperators[] = { |
175 #define PURE(Name, value_input_count, control_input_count, value_output_count) \ | 173 #define PURE(Name, value_input_count, control_input_count, value_output_count) \ |
176 { \ | 174 { \ |
177 &MachineOperatorBuilder::Name, IrOpcode::k##Name, value_input_count, \ | 175 &MachineOperatorBuilder::Name, #Name, value_input_count, \ |
178 control_input_count, value_output_count \ | 176 control_input_count, value_output_count \ |
179 } | 177 } |
180 PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1), | 178 PURE(Word32And, 2, 0, 1), // -- |
181 PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1), | 179 PURE(Word32Or, 2, 0, 1), // -- |
182 PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1), | 180 PURE(Word32Xor, 2, 0, 1), // -- |
183 PURE(Word32Equal, 2, 0, 1), PURE(Word32Clz, 1, 0, 1), | 181 PURE(Word32Shl, 2, 0, 1), // -- |
184 PURE(Word64And, 2, 0, 1), PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1), | 182 PURE(Word32Shr, 2, 0, 1), // -- |
185 PURE(Word64Shl, 2, 0, 1), PURE(Word64Shr, 2, 0, 1), | 183 PURE(Word32Sar, 2, 0, 1), // -- |
186 PURE(Word64Sar, 2, 0, 1), PURE(Word64Ror, 2, 0, 1), | 184 PURE(Word32Ror, 2, 0, 1), // -- |
187 PURE(Word64Equal, 2, 0, 1), PURE(Int32Add, 2, 0, 1), | 185 PURE(Word32Equal, 2, 0, 1), // -- |
188 PURE(Int32AddWithOverflow, 2, 0, 2), PURE(Int32Sub, 2, 0, 1), | 186 PURE(Word32Clz, 1, 0, 1), // -- |
189 PURE(Int32SubWithOverflow, 2, 0, 2), PURE(Int32Mul, 2, 0, 1), | 187 PURE(Word64And, 2, 0, 1), // -- |
190 PURE(Int32MulHigh, 2, 0, 1), PURE(Int32Div, 2, 1, 1), | 188 PURE(Word64Or, 2, 0, 1), // -- |
191 PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1), PURE(Uint32Mod, 2, 1, 1), | 189 PURE(Word64Xor, 2, 0, 1), // -- |
192 PURE(Int32LessThan, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1), | 190 PURE(Word64Shl, 2, 0, 1), // -- |
193 PURE(Uint32LessThan, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1), | 191 PURE(Word64Shr, 2, 0, 1), // -- |
194 PURE(Int64Add, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), | 192 PURE(Word64Sar, 2, 0, 1), // -- |
195 PURE(Int64Div, 2, 0, 1), PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1), | 193 PURE(Word64Ror, 2, 0, 1), // -- |
196 PURE(Uint64Mod, 2, 0, 1), PURE(Int64LessThan, 2, 0, 1), | 194 PURE(Word64Equal, 2, 0, 1), // -- |
197 PURE(Int64LessThanOrEqual, 2, 0, 1), PURE(Uint64LessThan, 2, 0, 1), | 195 PURE(Int32Add, 2, 0, 1), // -- |
198 PURE(ChangeFloat32ToFloat64, 1, 0, 1), PURE(ChangeFloat64ToInt32, 1, 0, 1), | 196 PURE(Int32AddWithOverflow, 2, 0, 2), // -- |
199 PURE(ChangeFloat64ToUint32, 1, 0, 1), PURE(ChangeInt32ToInt64, 1, 0, 1), | 197 PURE(Int32Sub, 2, 0, 1), // -- |
200 PURE(ChangeUint32ToFloat64, 1, 0, 1), PURE(ChangeUint32ToUint64, 1, 0, 1), | 198 PURE(Int32SubWithOverflow, 2, 0, 2), // -- |
201 PURE(TruncateFloat64ToFloat32, 1, 0, 1), | 199 PURE(Int32Mul, 2, 0, 1), // -- |
202 PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1, 0, 1), | 200 PURE(Int32MulHigh, 2, 0, 1), // -- |
203 PURE(Float32Add, 2, 0, 1), PURE(Float32Sub, 2, 0, 1), | 201 PURE(Int32Div, 2, 1, 1), // -- |
204 PURE(Float32Mul, 2, 0, 1), PURE(Float32Div, 2, 0, 1), | 202 PURE(Uint32Div, 2, 1, 1), // -- |
205 PURE(Float32Abs, 1, 0, 1), PURE(Float32Sqrt, 1, 0, 1), | 203 PURE(Int32Mod, 2, 1, 1), // -- |
206 PURE(Float32Equal, 2, 0, 1), PURE(Float32LessThan, 2, 0, 1), | 204 PURE(Uint32Mod, 2, 1, 1), // -- |
207 PURE(Float32LessThanOrEqual, 2, 0, 1), PURE(Float32Max, 2, 0, 1), | 205 PURE(Int32LessThan, 2, 0, 1), // -- |
208 PURE(Float32Min, 2, 0, 1), PURE(Float64Add, 2, 0, 1), | 206 PURE(Int32LessThanOrEqual, 2, 0, 1), // -- |
209 PURE(Float64Sub, 2, 0, 1), PURE(Float64Mul, 2, 0, 1), | 207 PURE(Uint32LessThan, 2, 0, 1), // -- |
210 PURE(Float64Div, 2, 0, 1), PURE(Float64Mod, 2, 0, 1), | 208 PURE(Uint32LessThanOrEqual, 2, 0, 1), // -- |
211 PURE(Float64Abs, 1, 0, 1), PURE(Float64Sqrt, 1, 0, 1), | 209 PURE(Int64Add, 2, 0, 1), // -- |
212 PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1), | 210 PURE(Int64Sub, 2, 0, 1), // -- |
213 PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(Float64Max, 2, 0, 1), | 211 PURE(Int64Mul, 2, 0, 1), // -- |
214 PURE(Float64Min, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1), | 212 PURE(Int64Div, 2, 0, 1), // -- |
215 PURE(Float64RoundDown, 1, 0, 1), PURE(Float64RoundTruncate, 1, 0, 1), | 213 PURE(Uint64Div, 2, 0, 1), // -- |
216 PURE(Float64RoundTiesAway, 1, 0, 1), PURE(Float64ExtractLowWord32, 1, 0, 1), | 214 PURE(Int64Mod, 2, 0, 1), // -- |
217 PURE(Float64ExtractHighWord32, 1, 0, 1), | 215 PURE(Uint64Mod, 2, 0, 1), // -- |
218 PURE(Float64InsertLowWord32, 2, 0, 1), | 216 PURE(Int64LessThan, 2, 0, 1), // -- |
219 PURE(Float64InsertHighWord32, 2, 0, 1) | 217 PURE(Int64LessThanOrEqual, 2, 0, 1), // -- |
| 218 PURE(Uint64LessThan, 2, 0, 1), // -- |
| 219 PURE(ChangeFloat32ToFloat64, 1, 0, 1), // -- |
| 220 PURE(ChangeFloat64ToInt32, 1, 0, 1), // -- |
| 221 PURE(ChangeFloat64ToUint32, 1, 0, 1), // -- |
| 222 PURE(ChangeInt32ToInt64, 1, 0, 1), // -- |
| 223 PURE(ChangeUint32ToFloat64, 1, 0, 1), // -- |
| 224 PURE(ChangeUint32ToUint64, 1, 0, 1), // -- |
| 225 PURE(TruncateFloat64ToFloat32, 1, 0, 1), // -- |
| 226 PURE(TruncateFloat64ToInt32, 1, 0, 1), // -- |
| 227 PURE(TruncateInt64ToInt32, 1, 0, 1), // -- |
| 228 PURE(Float32Abs, 1, 0, 1), // -- |
| 229 PURE(Float32Add, 2, 0, 1), // -- |
| 230 PURE(Float32Sub, 2, 0, 1), // -- |
| 231 PURE(Float32Mul, 2, 0, 1), // -- |
| 232 PURE(Float32Div, 2, 0, 1), // -- |
| 233 PURE(Float32Sqrt, 1, 0, 1), // -- |
| 234 PURE(Float32Equal, 2, 0, 1), // -- |
| 235 PURE(Float32LessThan, 2, 0, 1), // -- |
| 236 PURE(Float32LessThanOrEqual, 2, 0, 1), // -- |
| 237 PURE(Float64Abs, 1, 0, 1), // -- |
| 238 PURE(Float64Add, 2, 0, 1), // -- |
| 239 PURE(Float64Sub, 2, 0, 1), // -- |
| 240 PURE(Float64Mul, 2, 0, 1), // -- |
| 241 PURE(Float64Div, 2, 0, 1), // -- |
| 242 PURE(Float64Mod, 2, 0, 1), // -- |
| 243 PURE(Float64Sqrt, 1, 0, 1), // -- |
| 244 PURE(Float64Equal, 2, 0, 1), // -- |
| 245 PURE(Float64LessThan, 2, 0, 1), // -- |
| 246 PURE(Float64LessThanOrEqual, 2, 0, 1), // -- |
| 247 PURE(LoadStackPointer, 0, 0, 1), // -- |
| 248 PURE(Float64ExtractLowWord32, 1, 0, 1), // -- |
| 249 PURE(Float64ExtractHighWord32, 1, 0, 1), // -- |
| 250 PURE(Float64InsertLowWord32, 2, 0, 1), // -- |
| 251 PURE(Float64InsertHighWord32, 2, 0, 1), // -- |
220 #undef PURE | 252 #undef PURE |
221 }; | 253 }; |
222 | 254 |
| 255 } // namespace |
223 | 256 |
224 typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest; | 257 class MachinePureOperatorTest : public TestWithZone { |
| 258 protected: |
| 259 MachineType word_type() { return kMachPtr; } |
| 260 }; |
225 | 261 |
| 262 |
| 263 TEST_F(MachinePureOperatorTest, PureOperators) { |
| 264 TRACED_FOREACH(MachineType, machine_rep1, kMachineReps) { |
| 265 MachineOperatorBuilder machine1(zone(), machine_rep1); |
| 266 TRACED_FOREACH(MachineType, machine_rep2, kMachineReps) { |
| 267 MachineOperatorBuilder machine2(zone(), machine_rep2); |
| 268 TRACED_FOREACH(PureOperator, pop, kPureOperators) { |
| 269 const Operator* op1 = (machine1.*pop.constructor)(); |
| 270 const Operator* op2 = (machine2.*pop.constructor)(); |
| 271 EXPECT_EQ(op1, op2); |
| 272 EXPECT_EQ(pop.value_input_count, op1->ValueInputCount()); |
| 273 EXPECT_EQ(pop.control_input_count, op1->ControlInputCount()); |
| 274 EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount()); |
| 275 } |
| 276 } |
| 277 } |
| 278 } |
| 279 |
| 280 |
| 281 // Optional operators. |
| 282 |
| 283 namespace { |
| 284 |
| 285 struct OptionalOperatorEntry { |
| 286 const OptionalOperator (MachineOperatorBuilder::*constructor)(); |
| 287 MachineOperatorBuilder::Flag enabling_flag; |
| 288 char const* const constructor_name; |
| 289 int value_input_count; |
| 290 int control_input_count; |
| 291 int value_output_count; |
| 292 }; |
| 293 |
| 294 |
| 295 std::ostream& operator<<(std::ostream& os, OptionalOperatorEntry const& pop) { |
| 296 return os << pop.constructor_name; |
| 297 } |
| 298 |
| 299 const OptionalOperatorEntry kOptionalOperators[] = { |
| 300 #define OPTIONAL_ENTRY(Name, value_input_count, control_input_count, \ |
| 301 value_output_count) \ |
| 302 { \ |
| 303 &MachineOperatorBuilder::Name, MachineOperatorBuilder::k##Name, #Name, \ |
| 304 value_input_count, control_input_count, value_output_count \ |
| 305 } |
| 306 OPTIONAL_ENTRY(Float32Max, 2, 0, 1), // -- |
| 307 OPTIONAL_ENTRY(Float32Min, 2, 0, 1), // -- |
| 308 OPTIONAL_ENTRY(Float64Max, 2, 0, 1), // -- |
| 309 OPTIONAL_ENTRY(Float64Min, 2, 0, 1), // -- |
| 310 OPTIONAL_ENTRY(Float64RoundDown, 1, 0, 1), // -- |
| 311 OPTIONAL_ENTRY(Float64RoundTruncate, 1, 0, 1), // -- |
| 312 OPTIONAL_ENTRY(Float64RoundTiesAway, 1, 0, 1), // -- |
| 313 #undef OPTIONAL_ENTRY |
| 314 }; |
226 } // namespace | 315 } // namespace |
227 | 316 |
228 | 317 |
229 TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) { | 318 class MachineOptionalOperatorTest : public TestWithZone { |
230 const PureOperator& pop = GetParam(); | 319 protected: |
231 MachineOperatorBuilder machine1(zone(), type()); | 320 MachineType word_type() { return kMachPtr; } |
232 MachineOperatorBuilder machine2(zone(), type()); | 321 }; |
233 EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)()); | 322 |
| 323 |
| 324 TEST_F(MachineOptionalOperatorTest, OptionalOperators) { |
| 325 TRACED_FOREACH(OptionalOperatorEntry, pop, kOptionalOperators) { |
| 326 TRACED_FOREACH(MachineType, machine_rep1, kMachineReps) { |
| 327 MachineOperatorBuilder machine1(zone(), machine_rep1, pop.enabling_flag); |
| 328 TRACED_FOREACH(MachineType, machine_rep2, kMachineReps) { |
| 329 MachineOperatorBuilder machine2(zone(), machine_rep2, |
| 330 pop.enabling_flag); |
| 331 const Operator* op1 = (machine1.*pop.constructor)().op(); |
| 332 const Operator* op2 = (machine2.*pop.constructor)().op(); |
| 333 EXPECT_EQ(op1, op2); |
| 334 EXPECT_EQ(pop.value_input_count, op1->ValueInputCount()); |
| 335 EXPECT_EQ(pop.control_input_count, op1->ControlInputCount()); |
| 336 EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount()); |
| 337 |
| 338 MachineOperatorBuilder machine3(zone(), word_type()); |
| 339 EXPECT_TRUE((machine1.*pop.constructor)().IsSupported()); |
| 340 EXPECT_FALSE((machine3.*pop.constructor)().IsSupported()); |
| 341 } |
| 342 } |
| 343 } |
234 } | 344 } |
235 | 345 |
236 | 346 |
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 // ----------------------------------------------------------------------------- | 347 // ----------------------------------------------------------------------------- |
279 // Pseudo operators. | 348 // Pseudo operators. |
280 | 349 |
281 | 350 |
282 namespace { | 351 namespace { |
283 | 352 |
284 typedef TestWithZone MachineOperatorTest; | 353 typedef TestWithZone MachineOperatorTest; |
285 | 354 |
286 } // namespace | 355 } // namespace |
287 | 356 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 EXPECT_EQ(machine.Uint64Div(), machine.UintDiv()); | 394 EXPECT_EQ(machine.Uint64Div(), machine.UintDiv()); |
326 EXPECT_EQ(machine.Int64Mod(), machine.IntMod()); | 395 EXPECT_EQ(machine.Int64Mod(), machine.IntMod()); |
327 EXPECT_EQ(machine.Uint64Mod(), machine.UintMod()); | 396 EXPECT_EQ(machine.Uint64Mod(), machine.UintMod()); |
328 EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan()); | 397 EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan()); |
329 EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual()); | 398 EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual()); |
330 } | 399 } |
331 | 400 |
332 } // namespace compiler | 401 } // namespace compiler |
333 } // namespace internal | 402 } // namespace internal |
334 } // namespace v8 | 403 } // namespace v8 |
OLD | NEW |