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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 | 222 |
223 bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) { | 223 bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) { |
224 HInstruction left = instruction.inputs[1]; | 224 HInstruction left = instruction.inputs[1]; |
225 HInstruction right = instruction.inputs[2]; | 225 HInstruction right = instruction.inputs[2]; |
226 JavaScriptBackend backend = compiler.backend; | 226 JavaScriptBackend backend = compiler.backend; |
227 return left.isPositiveIntegerOrNull(compiler) | 227 return left.isPositiveIntegerOrNull(compiler) |
228 && right.isPositiveIntegerOrNull(compiler); | 228 && right.isPositiveIntegerOrNull(compiler); |
229 } | 229 } |
230 | 230 |
231 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); | 231 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); |
232 | |
233 | |
kasperl
2013/12/10 14:22:54
Too much whitespace.
ngeoffray
2013/12/10 15:26:17
Done.
| |
234 Selector renameToOptimizedSelector(String name, | |
235 Selector selector, | |
236 Compiler compiler) { | |
237 if (selector.name == name) return selector; | |
238 return new TypedSelector( | |
239 selector.mask, | |
240 new Selector(SelectorKind.CALL, | |
241 name, | |
242 compiler.interceptorsLibrary, | |
243 selector.argumentCount)); | |
244 } | |
232 } | 245 } |
233 | 246 |
234 class AddSpecializer extends BinaryArithmeticSpecializer { | 247 class AddSpecializer extends BinaryArithmeticSpecializer { |
235 const AddSpecializer(); | 248 const AddSpecializer(); |
236 | 249 |
237 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | 250 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
238 Compiler compiler) { | 251 Compiler compiler) { |
239 if (inputsArePositiveIntegers(instruction, compiler)) { | 252 if (inputsArePositiveIntegers(instruction, compiler)) { |
240 JavaScriptBackend backend = compiler.backend; | 253 JavaScriptBackend backend = compiler.backend; |
241 return backend.positiveIntType; | 254 return backend.positiveIntType; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 | 365 |
353 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | 366 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
354 Compiler compiler) { | 367 Compiler compiler) { |
355 if (inputsArePositiveIntegers(instruction, compiler)) { | 368 if (inputsArePositiveIntegers(instruction, compiler)) { |
356 JavaScriptBackend backend = compiler.backend; | 369 JavaScriptBackend backend = compiler.backend; |
357 return backend.positiveIntType; | 370 return backend.positiveIntType; |
358 } | 371 } |
359 return super.computeTypeFromInputTypes(instruction, compiler); | 372 return super.computeTypeFromInputTypes(instruction, compiler); |
360 } | 373 } |
361 | 374 |
375 bool isNotZero(HInstruction instruction, Compiler compiler) { | |
376 if (!instruction.isConstantInteger()) return false; | |
377 HConstant rightConstant = instruction; | |
378 IntConstant intConstant = rightConstant.constant; | |
379 int count = intConstant.value; | |
380 return count != 0; | |
381 } | |
382 | |
383 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, | |
384 Compiler compiler) { | |
385 HInstruction left = instruction.inputs[1]; | |
386 HInstruction right = instruction.inputs[2]; | |
387 if (isBuiltin(instruction, compiler)) { | |
388 if (right.isUInt32(compiler) && isNotZero(right, compiler)) { | |
floitsch
2013/12/10 15:45:16
Right side only needs to be an integer != 0.
ngeoffray
2013/12/10 15:48:15
Done.
| |
389 if (left.isUInt32(compiler)) { | |
floitsch
2013/12/10 15:45:16
left.isUInt31, or left.isInt32
ngeoffray
2013/12/10 15:48:15
Changed to left.isUInt31 (we don't have isInt32).
| |
390 return newBuiltinVariant(instruction, compiler); | |
391 } | |
392 clearAllSideEffects(instruction); | |
393 instruction.selector = renameToOptimizedSelector( | |
kasperl
2013/12/10 14:22:54
Add a comment that explains what the contract for
ngeoffray
2013/12/10 15:26:17
Done.
| |
394 '_tdivFast', instruction.selector, compiler); | |
395 } | |
396 } | |
397 return null; | |
398 } | |
399 | |
362 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 400 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
363 Compiler compiler) { | 401 Compiler compiler) { |
364 // Truncating divide does not have a JS equivalent. | 402 return new HTruncatingDivide( |
365 return null; | 403 instruction.inputs[1], instruction.inputs[2], |
404 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | |
366 } | 405 } |
367 } | 406 } |
368 | 407 |
369 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 408 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
370 const BinaryBitOpSpecializer(); | 409 const BinaryBitOpSpecializer(); |
371 | 410 |
372 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | 411 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
373 Compiler compiler) { | 412 Compiler compiler) { |
374 // All bitwise operations on primitive types either produce an | 413 // All bitwise operations on primitive types either produce an |
375 // integer or throw an error. | 414 // integer or throw an error. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 HInstruction left = instruction.inputs[1]; | 447 HInstruction left = instruction.inputs[1]; |
409 HInstruction right = instruction.inputs[2]; | 448 HInstruction right = instruction.inputs[2]; |
410 if (left.isNumber(compiler)) { | 449 if (left.isNumber(compiler)) { |
411 if (argumentLessThan32(right)) { | 450 if (argumentLessThan32(right)) { |
412 return newBuiltinVariant(instruction, compiler); | 451 return newBuiltinVariant(instruction, compiler); |
413 } | 452 } |
414 // Even if there is no builtin equivalent instruction, we know | 453 // Even if there is no builtin equivalent instruction, we know |
415 // the instruction does not have any side effect, and that it | 454 // the instruction does not have any side effect, and that it |
416 // can be GVN'ed. | 455 // can be GVN'ed. |
417 clearAllSideEffects(instruction); | 456 clearAllSideEffects(instruction); |
457 Selector selector = instruction.selector; | |
458 if (isPositive(right, compiler)) { | |
459 instruction.selector = renameToOptimizedSelector( | |
460 '_shlPositive', instruction.selector, compiler); | |
461 } | |
418 } | 462 } |
419 return null; | 463 return null; |
420 } | 464 } |
421 | 465 |
422 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 466 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
423 Compiler compiler) { | 467 Compiler compiler) { |
424 JavaScriptBackend backend = compiler.backend; | 468 JavaScriptBackend backend = compiler.backend; |
425 return new HShiftLeft( | 469 return new HShiftLeft( |
426 instruction.inputs[1], instruction.inputs[2], | 470 instruction.inputs[1], instruction.inputs[2], |
427 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 471 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
(...skipping 17 matching lines...) Expand all Loading... | |
445 HInstruction left = instruction.inputs[1]; | 489 HInstruction left = instruction.inputs[1]; |
446 HInstruction right = instruction.inputs[2]; | 490 HInstruction right = instruction.inputs[2]; |
447 if (left.isNumber(compiler)) { | 491 if (left.isNumber(compiler)) { |
448 if (argumentLessThan32(right) && isPositive(left, compiler)) { | 492 if (argumentLessThan32(right) && isPositive(left, compiler)) { |
449 return newBuiltinVariant(instruction, compiler); | 493 return newBuiltinVariant(instruction, compiler); |
450 } | 494 } |
451 // Even if there is no builtin equivalent instruction, we know | 495 // Even if there is no builtin equivalent instruction, we know |
452 // the instruction does not have any side effect, and that it | 496 // the instruction does not have any side effect, and that it |
453 // can be GVN'ed. | 497 // can be GVN'ed. |
454 clearAllSideEffects(instruction); | 498 clearAllSideEffects(instruction); |
499 if (isPositive(right, compiler) && isPositive(left, compiler)) { | |
500 instruction.selector = renameToOptimizedSelector( | |
501 '_shrBothPositive', instruction.selector, compiler); | |
502 } else if (isPositive(left, compiler) && right.isNumber(compiler)) { | |
503 instruction.selector = renameToOptimizedSelector( | |
504 '_shrReceiverPositive', instruction.selector, compiler); | |
505 } else if (isPositive(right, compiler)) { | |
506 instruction.selector = renameToOptimizedSelector( | |
507 '_shrOtherPositive', instruction.selector, compiler); | |
508 } | |
455 } | 509 } |
456 return null; | 510 return null; |
457 } | 511 } |
458 | 512 |
459 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 513 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
460 Compiler compiler) { | 514 Compiler compiler) { |
461 JavaScriptBackend backend = compiler.backend; | 515 JavaScriptBackend backend = compiler.backend; |
462 return new HShiftRight( | 516 return new HShiftRight( |
463 instruction.inputs[1], instruction.inputs[2], | 517 instruction.inputs[1], instruction.inputs[2], |
464 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 518 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
669 } | 723 } |
670 | 724 |
671 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 725 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
672 Compiler compiler) { | 726 Compiler compiler) { |
673 JavaScriptBackend backend = compiler.backend; | 727 JavaScriptBackend backend = compiler.backend; |
674 return new HLessEqual( | 728 return new HLessEqual( |
675 instruction.inputs[1], instruction.inputs[2], | 729 instruction.inputs[1], instruction.inputs[2], |
676 instruction.selector, backend.boolType); | 730 instruction.selector, backend.boolType); |
677 } | 731 } |
678 } | 732 } |
OLD | NEW |