OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of ssa; | 5 part of ssa; |
6 | 6 |
7 /** | 7 /** |
8 * [InvokeDynamicSpecializer] and its subclasses are helpers to | 8 * [InvokeDynamicSpecializer] and its subclasses are helpers to |
9 * optimize intercepted dynamic calls. It knows what input types | 9 * optimize intercepted dynamic calls. It knows what input types |
10 * would be beneficial for performance, and how to change a invoke | 10 * would be beneficial for performance, and how to change a invoke |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 } | 260 } |
261 | 261 |
262 bool isBuiltin(HInvokeDynamicMethod instruction, HTypeMap types) { | 262 bool isBuiltin(HInvokeDynamicMethod instruction, HTypeMap types) { |
263 return instruction.inputs[1].isNumber(types) | 263 return instruction.inputs[1].isNumber(types) |
264 && instruction.inputs[2].isNumber(types); | 264 && instruction.inputs[2].isNumber(types); |
265 } | 265 } |
266 | 266 |
267 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 267 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, |
268 HTypeMap types) { | 268 HTypeMap types) { |
269 if (isBuiltin(instruction, types)) { | 269 if (isBuiltin(instruction, types)) { |
270 return newBuiltinVariant(instruction.inputs[1], instruction.inputs[2]); | 270 HInstruction builtin = |
| 271 newBuiltinVariant(instruction.inputs[1], instruction.inputs[2]); |
| 272 if (builtin != null) return builtin; |
| 273 // Even if there is no builtin equivalent instruction, we know |
| 274 // the instruction is pure, and that it can be GVN'ed. |
| 275 instruction.clearAllSideEffects(); |
| 276 instruction.clearAllDependencies(); |
| 277 instruction.setUseGvn(); |
271 } | 278 } |
272 return null; | 279 return null; |
273 } | 280 } |
274 | 281 |
275 HInstruction newBuiltinVariant(HInstruction left, HInstruction right); | 282 HInstruction newBuiltinVariant(HInstruction left, HInstruction right); |
276 } | 283 } |
277 | 284 |
278 class AddSpecializer extends BinaryArithmeticSpecializer { | 285 class AddSpecializer extends BinaryArithmeticSpecializer { |
279 const AddSpecializer(); | 286 const AddSpecializer(); |
280 | 287 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 } | 325 } |
319 } | 326 } |
320 | 327 |
321 class ModuloSpecializer extends BinaryArithmeticSpecializer { | 328 class ModuloSpecializer extends BinaryArithmeticSpecializer { |
322 const ModuloSpecializer(); | 329 const ModuloSpecializer(); |
323 | 330 |
324 BinaryOperation operation(ConstantSystem constantSystem) { | 331 BinaryOperation operation(ConstantSystem constantSystem) { |
325 return constantSystem.modulo; | 332 return constantSystem.modulo; |
326 } | 333 } |
327 | 334 |
328 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 335 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
329 HTypeMap types) { | |
330 // Modulo cannot be mapped to the native operator (different semantics). | 336 // Modulo cannot be mapped to the native operator (different semantics). |
331 return null; | 337 return null; |
332 } | 338 } |
333 | |
334 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | |
335 throw 'Modulo has no builtin variant'; | |
336 } | |
337 } | 339 } |
338 | 340 |
339 class MultiplySpecializer extends BinaryArithmeticSpecializer { | 341 class MultiplySpecializer extends BinaryArithmeticSpecializer { |
340 const MultiplySpecializer(); | 342 const MultiplySpecializer(); |
341 | 343 |
342 BinaryOperation operation(ConstantSystem constantSystem) { | 344 BinaryOperation operation(ConstantSystem constantSystem) { |
343 return constantSystem.multiply; | 345 return constantSystem.multiply; |
344 } | 346 } |
345 | 347 |
346 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | 348 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
(...skipping 13 matching lines...) Expand all Loading... |
360 } | 362 } |
361 } | 363 } |
362 | 364 |
363 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { | 365 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { |
364 const TruncatingDivideSpecializer(); | 366 const TruncatingDivideSpecializer(); |
365 | 367 |
366 BinaryOperation operation(ConstantSystem constantSystem) { | 368 BinaryOperation operation(ConstantSystem constantSystem) { |
367 return constantSystem.truncatingDivide; | 369 return constantSystem.truncatingDivide; |
368 } | 370 } |
369 | 371 |
370 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 372 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
371 HTypeMap types) { | |
372 // Truncating divide does not have a JS equivalent. | 373 // Truncating divide does not have a JS equivalent. |
373 return null; | 374 return null; |
374 } | 375 } |
375 | |
376 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | |
377 throw 'Truncating divide has no builtin variant'; | |
378 } | |
379 } | 376 } |
380 | 377 |
381 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 378 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
382 const BinaryBitOpSpecializer(); | 379 const BinaryBitOpSpecializer(); |
383 | 380 |
384 HType computeTypeFromInputTypes(HInvokeDynamicMethod instruction, | 381 HType computeTypeFromInputTypes(HInvokeDynamicMethod instruction, |
385 HTypeMap types, | 382 HTypeMap types, |
386 Compiler compiler) { | 383 Compiler compiler) { |
387 // All bitwise operations on primitive types either produce an | 384 // All bitwise operations on primitive types either produce an |
388 // integer or throw an error. | 385 // integer or throw an error. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 } | 426 } |
430 | 427 |
431 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | 428 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
432 return new HShiftLeft(left, right); | 429 return new HShiftLeft(left, right); |
433 } | 430 } |
434 } | 431 } |
435 | 432 |
436 class ShiftRightSpecializer extends BinaryBitOpSpecializer { | 433 class ShiftRightSpecializer extends BinaryBitOpSpecializer { |
437 const ShiftRightSpecializer(); | 434 const ShiftRightSpecializer(); |
438 | 435 |
439 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction, | 436 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
440 HTypeMap types) { | |
441 // Shift right cannot be mapped to the native operator easily. | 437 // Shift right cannot be mapped to the native operator easily. |
442 return null; | 438 return null; |
443 } | 439 } |
444 | 440 |
445 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | |
446 throw 'Shift right has no builtin variant'; | |
447 } | |
448 | |
449 BinaryOperation operation(ConstantSystem constantSystem) { | 441 BinaryOperation operation(ConstantSystem constantSystem) { |
450 return constantSystem.shiftRight; | 442 return constantSystem.shiftRight; |
451 } | 443 } |
452 } | 444 } |
453 | 445 |
454 class BitOrSpecializer extends BinaryBitOpSpecializer { | 446 class BitOrSpecializer extends BinaryBitOpSpecializer { |
455 const BitOrSpecializer(); | 447 const BitOrSpecializer(); |
456 | 448 |
457 BinaryOperation operation(ConstantSystem constantSystem) { | 449 BinaryOperation operation(ConstantSystem constantSystem) { |
458 return constantSystem.bitOr; | 450 return constantSystem.bitOr; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 const LessEqualSpecializer(); | 610 const LessEqualSpecializer(); |
619 | 611 |
620 BinaryOperation operation(ConstantSystem constantSystem) { | 612 BinaryOperation operation(ConstantSystem constantSystem) { |
621 return constantSystem.lessEqual; | 613 return constantSystem.lessEqual; |
622 } | 614 } |
623 | 615 |
624 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { | 616 HInstruction newBuiltinVariant(HInstruction left, HInstruction right) { |
625 return new HLessEqual(left, right); | 617 return new HLessEqual(left, right); |
626 } | 618 } |
627 } | 619 } |
OLD | NEW |