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