| 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 import '../compiler.dart' show Compiler; | 5 import '../compiler.dart' show Compiler; |
| 6 import '../constants/constant_system.dart'; | 6 import '../constants/constant_system.dart'; |
| 7 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
| 8 import '../elements/elements.dart' show Name; | 8 import '../elements/elements.dart' show Name; |
| 9 import '../elements/entities.dart'; | 9 import '../elements/entities.dart'; |
| 10 import '../js_backend/js_backend.dart'; | 10 import '../js_backend/js_backend.dart'; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 34 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { |
| 35 return null; | 35 return null; |
| 36 } | 36 } |
| 37 | 37 |
| 38 void clearAllSideEffects(HInstruction instruction) { | 38 void clearAllSideEffects(HInstruction instruction) { |
| 39 instruction.sideEffects.clearAllSideEffects(); | 39 instruction.sideEffects.clearAllSideEffects(); |
| 40 instruction.sideEffects.clearAllDependencies(); | 40 instruction.sideEffects.clearAllDependencies(); |
| 41 instruction.setUseGvn(); | 41 instruction.setUseGvn(); |
| 42 } | 42 } |
| 43 | 43 |
| 44 Selector renameToOptimizedSelector( |
| 45 String name, Selector selector, Compiler compiler) { |
| 46 if (selector.name == name) return selector; |
| 47 JavaScriptBackend backend = compiler.backend; |
| 48 return new Selector.call( |
| 49 new Name(name, backend.helpers.interceptorsLibrary), |
| 50 new CallStructure(selector.argumentCount)); |
| 51 } |
| 52 |
| 44 Operation operation(ConstantSystem constantSystem) => null; | 53 Operation operation(ConstantSystem constantSystem) => null; |
| 45 | 54 |
| 46 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) { | 55 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) { |
| 47 if (selector.isIndex) return const IndexSpecializer(); | 56 if (selector.isIndex) return const IndexSpecializer(); |
| 48 if (selector.isIndexSet) return const IndexAssignSpecializer(); | 57 if (selector.isIndexSet) return const IndexAssignSpecializer(); |
| 49 String name = selector.name; | 58 String name = selector.name; |
| 50 if (selector.isOperator) { | 59 if (selector.isOperator) { |
| 51 if (name == 'unary-') return const UnaryNegateSpecializer(); | 60 if (name == 'unary-') return const UnaryNegateSpecializer(); |
| 52 if (name == '~') return const BitNotSpecializer(); | 61 if (name == '~') return const BitNotSpecializer(); |
| 53 if (name == '+') return const AddSpecializer(); | 62 if (name == '+') return const AddSpecializer(); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 } | 243 } |
| 235 | 244 |
| 236 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) { | 245 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) { |
| 237 HInstruction left = instruction.inputs[1]; | 246 HInstruction left = instruction.inputs[1]; |
| 238 HInstruction right = instruction.inputs[2]; | 247 HInstruction right = instruction.inputs[2]; |
| 239 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld); | 248 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld); |
| 240 } | 249 } |
| 241 | 250 |
| 242 HInstruction newBuiltinVariant( | 251 HInstruction newBuiltinVariant( |
| 243 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld); | 252 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld); |
| 244 | |
| 245 Selector renameToOptimizedSelector( | |
| 246 String name, Selector selector, Compiler compiler) { | |
| 247 if (selector.name == name) return selector; | |
| 248 JavaScriptBackend backend = compiler.backend; | |
| 249 return new Selector.call( | |
| 250 new Name(name, backend.helpers.interceptorsLibrary), | |
| 251 new CallStructure(selector.argumentCount)); | |
| 252 } | |
| 253 } | 253 } |
| 254 | 254 |
| 255 class AddSpecializer extends BinaryArithmeticSpecializer { | 255 class AddSpecializer extends BinaryArithmeticSpecializer { |
| 256 const AddSpecializer(); | 256 const AddSpecializer(); |
| 257 | 257 |
| 258 TypeMask computeTypeFromInputTypes( | 258 TypeMask computeTypeFromInputTypes( |
| 259 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 259 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { |
| 260 if (inputsAreUInt31(instruction, closedWorld)) { | 260 if (inputsAreUInt31(instruction, closedWorld)) { |
| 261 return closedWorld.commonMasks.uint32Type; | 261 return closedWorld.commonMasks.uint32Type; |
| 262 } | 262 } |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 if (instruction.isConstantInteger()) { | 546 if (instruction.isConstantInteger()) { |
| 547 HConstant rightConstant = instruction; | 547 HConstant rightConstant = instruction; |
| 548 IntConstantValue intConstant = rightConstant.constant; | 548 IntConstantValue intConstant = rightConstant.constant; |
| 549 int value = intConstant.primitiveValue; | 549 int value = intConstant.primitiveValue; |
| 550 return value >= low && value <= high; | 550 return value >= low && value <= high; |
| 551 } | 551 } |
| 552 // TODO(sra): Integrate with the bit-width analysis in codegen.dart. | 552 // TODO(sra): Integrate with the bit-width analysis in codegen.dart. |
| 553 if (instruction is HBitAnd) { | 553 if (instruction is HBitAnd) { |
| 554 return low == 0 && | 554 return low == 0 && |
| 555 (argumentInRange(instruction.inputs[0], low, high) || | 555 (argumentInRange(instruction.inputs[0], low, high) || |
| 556 argumentInRange(instruction.inputs[1], low, high)); | 556 argumentInRange(instruction.inputs[1], low, high)); |
| 557 } | 557 } |
| 558 return false; | 558 return false; |
| 559 } | 559 } |
| 560 | 560 |
| 561 bool isPositive(HInstruction instruction, ClosedWorld closedWorld) { | 561 bool isPositive(HInstruction instruction, ClosedWorld closedWorld) { |
| 562 // TODO: We should use the value range analysis. Currently, ranges | 562 // TODO: We should use the value range analysis. Currently, ranges |
| 563 // are discarded just after the analysis. | 563 // are discarded just after the analysis. |
| 564 return instruction.isPositiveInteger(closedWorld); | 564 return instruction.isPositiveInteger(closedWorld); |
| 565 } | 565 } |
| 566 } | 566 } |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 HInstruction tryConvertToBuiltin( | 859 HInstruction tryConvertToBuiltin( |
| 860 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 860 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { |
| 861 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index | 861 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index |
| 862 // bounds checking optimizations as for HIndex. | 862 // bounds checking optimizations as for HIndex. |
| 863 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 863 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 864 if (receiver.isStringOrNull(closedWorld)) { | 864 if (receiver.isStringOrNull(closedWorld)) { |
| 865 // Even if there is no builtin equivalent instruction, we know | 865 // Even if there is no builtin equivalent instruction, we know |
| 866 // String.codeUnitAt does not have any side effect (other than throwing), | 866 // String.codeUnitAt does not have any side effect (other than throwing), |
| 867 // and that it can be GVN'ed. | 867 // and that it can be GVN'ed. |
| 868 clearAllSideEffects(instruction); | 868 clearAllSideEffects(instruction); |
| 869 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { |
| 870 instruction.selector = renameToOptimizedSelector( |
| 871 '_codeUnitAt', instruction.selector, compiler); |
| 872 } |
| 869 } | 873 } |
| 870 return null; | 874 return null; |
| 871 } | 875 } |
| 872 } | 876 } |
| 873 | 877 |
| 874 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { | 878 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { |
| 875 const IdempotentStringOperationSpecializer(); | 879 const IdempotentStringOperationSpecializer(); |
| 876 | 880 |
| 877 HInstruction tryConvertToBuiltin( | 881 HInstruction tryConvertToBuiltin( |
| 878 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 882 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 926 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { |
| 923 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 927 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 924 if (receiver.isNumberOrNull(closedWorld)) { | 928 if (receiver.isNumberOrNull(closedWorld)) { |
| 925 // Even if there is no builtin equivalent instruction, we know the | 929 // Even if there is no builtin equivalent instruction, we know the |
| 926 // instruction does not have any side effect, and that it can be GVN'ed. | 930 // instruction does not have any side effect, and that it can be GVN'ed. |
| 927 clearAllSideEffects(instruction); | 931 clearAllSideEffects(instruction); |
| 928 } | 932 } |
| 929 return null; | 933 return null; |
| 930 } | 934 } |
| 931 } | 935 } |
| OLD | NEW |