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 |