| 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 '../constants/constant_system.dart'; | 5 import '../constants/constant_system.dart'; |
| 6 import '../constants/values.dart'; | 6 import '../constants/values.dart'; |
| 7 import '../elements/elements.dart' show Name; | 7 import '../elements/elements.dart' show Name; |
| 8 import '../elements/entities.dart'; | 8 import '../elements/entities.dart'; |
| 9 import '../js_backend/backend_helpers.dart'; | 9 import '../js_backend/backend_helpers.dart'; |
| 10 import '../options.dart'; | 10 import '../options.dart'; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 GlobalTypeInferenceResults results, | 29 GlobalTypeInferenceResults results, |
| 30 CompilerOptions options, | 30 CompilerOptions options, |
| 31 BackendHelpers helpers, | 31 BackendHelpers helpers, |
| 32 ClosedWorld closedWorld) { | 32 ClosedWorld closedWorld) { |
| 33 return TypeMaskFactory.inferredTypeForSelector( | 33 return TypeMaskFactory.inferredTypeForSelector( |
| 34 instruction.selector, instruction.mask, results); | 34 instruction.selector, instruction.mask, results); |
| 35 } | 35 } |
| 36 | 36 |
| 37 HInstruction tryConvertToBuiltin( | 37 HInstruction tryConvertToBuiltin( |
| 38 HInvokeDynamic instruction, | 38 HInvokeDynamic instruction, |
| 39 HGraph graph, |
| 39 GlobalTypeInferenceResults results, | 40 GlobalTypeInferenceResults results, |
| 40 CompilerOptions options, | 41 CompilerOptions options, |
| 41 BackendHelpers helpers, | 42 BackendHelpers helpers, |
| 42 ClosedWorld closedWorld) { | 43 ClosedWorld closedWorld) { |
| 43 return null; | 44 return null; |
| 44 } | 45 } |
| 45 | 46 |
| 46 void clearAllSideEffects(HInstruction instruction) { | 47 void clearAllSideEffects(HInstruction instruction) { |
| 47 instruction.sideEffects.clearAllSideEffects(); | 48 instruction.sideEffects.clearAllSideEffects(); |
| 48 instruction.sideEffects.clearAllDependencies(); | 49 instruction.sideEffects.clearAllDependencies(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 return const InvokeDynamicSpecializer(); | 85 return const InvokeDynamicSpecializer(); |
| 85 } | 86 } |
| 86 if (selector.isCall) { | 87 if (selector.isCall) { |
| 87 if (selector.namedArguments.length == 0) { | 88 if (selector.namedArguments.length == 0) { |
| 88 int argumentCount = selector.argumentCount; | 89 int argumentCount = selector.argumentCount; |
| 89 if (argumentCount == 0) { | 90 if (argumentCount == 0) { |
| 90 if (name == 'round') return const RoundSpecializer(); | 91 if (name == 'round') return const RoundSpecializer(); |
| 91 if (name == 'trim') return const TrimSpecializer(); | 92 if (name == 'trim') return const TrimSpecializer(); |
| 92 } else if (argumentCount == 1) { | 93 } else if (argumentCount == 1) { |
| 93 if (name == 'codeUnitAt') return const CodeUnitAtSpecializer(); | 94 if (name == 'codeUnitAt') return const CodeUnitAtSpecializer(); |
| 95 if (name == 'compareTo') return const CompareToSpecializer(); |
| 94 if (name == 'remainder') return const RemainderSpecializer(); | 96 if (name == 'remainder') return const RemainderSpecializer(); |
| 95 if (name == 'substring') return const SubstringSpecializer(); | 97 if (name == 'substring') return const SubstringSpecializer(); |
| 96 if (name == 'contains') return const PatternMatchSpecializer(); | 98 if (name == 'contains') return const PatternMatchSpecializer(); |
| 97 if (name == 'indexOf') return const PatternMatchSpecializer(); | 99 if (name == 'indexOf') return const PatternMatchSpecializer(); |
| 98 if (name == 'startsWith') return const PatternMatchSpecializer(); | 100 if (name == 'startsWith') return const PatternMatchSpecializer(); |
| 99 if (name == 'endsWith') return const PatternMatchSpecializer(); | 101 if (name == 'endsWith') return const PatternMatchSpecializer(); |
| 100 } else if (argumentCount == 2) { | 102 } else if (argumentCount == 2) { |
| 101 if (name == 'substring') return const SubstringSpecializer(); | 103 if (name == 'substring') return const SubstringSpecializer(); |
| 102 if (name == 'contains') return const PatternMatchSpecializer(); | 104 if (name == 'contains') return const PatternMatchSpecializer(); |
| 103 if (name == 'indexOf') return const PatternMatchSpecializer(); | 105 if (name == 'indexOf') return const PatternMatchSpecializer(); |
| 104 if (name == 'startsWith') return const PatternMatchSpecializer(); | 106 if (name == 'startsWith') return const PatternMatchSpecializer(); |
| 105 if (name == 'endsWith') return const PatternMatchSpecializer(); | 107 if (name == 'endsWith') return const PatternMatchSpecializer(); |
| 106 } | 108 } |
| 107 } | 109 } |
| 108 } | 110 } |
| 109 return const InvokeDynamicSpecializer(); | 111 return const InvokeDynamicSpecializer(); |
| 110 } | 112 } |
| 111 } | 113 } |
| 112 | 114 |
| 113 class IndexAssignSpecializer extends InvokeDynamicSpecializer { | 115 class IndexAssignSpecializer extends InvokeDynamicSpecializer { |
| 114 const IndexAssignSpecializer(); | 116 const IndexAssignSpecializer(); |
| 115 | 117 |
| 116 HInstruction tryConvertToBuiltin( | 118 HInstruction tryConvertToBuiltin( |
| 117 HInvokeDynamic instruction, | 119 HInvokeDynamic instruction, |
| 120 HGraph graph, |
| 118 GlobalTypeInferenceResults results, | 121 GlobalTypeInferenceResults results, |
| 119 CompilerOptions options, | 122 CompilerOptions options, |
| 120 BackendHelpers helpers, | 123 BackendHelpers helpers, |
| 121 ClosedWorld closedWorld) { | 124 ClosedWorld closedWorld) { |
| 122 if (instruction.inputs[1].isMutableIndexable(closedWorld)) { | 125 if (instruction.inputs[1].isMutableIndexable(closedWorld)) { |
| 123 if (!instruction.inputs[2].isInteger(closedWorld) && | 126 if (!instruction.inputs[2].isInteger(closedWorld) && |
| 124 options.enableTypeAssertions) { | 127 options.enableTypeAssertions) { |
| 125 // We want the right checked mode error. | 128 // We want the right checked mode error. |
| 126 return null; | 129 return null; |
| 127 } | 130 } |
| 128 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2], | 131 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2], |
| 129 instruction.inputs[3], instruction.selector); | 132 instruction.inputs[3], instruction.selector); |
| 130 } | 133 } |
| 131 return null; | 134 return null; |
| 132 } | 135 } |
| 133 } | 136 } |
| 134 | 137 |
| 135 class IndexSpecializer extends InvokeDynamicSpecializer { | 138 class IndexSpecializer extends InvokeDynamicSpecializer { |
| 136 const IndexSpecializer(); | 139 const IndexSpecializer(); |
| 137 | 140 |
| 138 HInstruction tryConvertToBuiltin( | 141 HInstruction tryConvertToBuiltin( |
| 139 HInvokeDynamic instruction, | 142 HInvokeDynamic instruction, |
| 143 HGraph graph, |
| 140 GlobalTypeInferenceResults results, | 144 GlobalTypeInferenceResults results, |
| 141 CompilerOptions options, | 145 CompilerOptions options, |
| 142 BackendHelpers helpers, | 146 BackendHelpers helpers, |
| 143 ClosedWorld closedWorld) { | 147 ClosedWorld closedWorld) { |
| 144 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null; | 148 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null; |
| 145 if (!instruction.inputs[2].isInteger(closedWorld) && | 149 if (!instruction.inputs[2].isInteger(closedWorld) && |
| 146 options.enableTypeAssertions) { | 150 options.enableTypeAssertions) { |
| 147 // We want the right checked mode error. | 151 // We want the right checked mode error. |
| 148 return null; | 152 return null; |
| 149 } | 153 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 173 // integer or throw an error. | 177 // integer or throw an error. |
| 174 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { | 178 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { |
| 175 return closedWorld.commonMasks.uint32Type; | 179 return closedWorld.commonMasks.uint32Type; |
| 176 } | 180 } |
| 177 return super.computeTypeFromInputTypes( | 181 return super.computeTypeFromInputTypes( |
| 178 instruction, results, options, helpers, closedWorld); | 182 instruction, results, options, helpers, closedWorld); |
| 179 } | 183 } |
| 180 | 184 |
| 181 HInstruction tryConvertToBuiltin( | 185 HInstruction tryConvertToBuiltin( |
| 182 HInvokeDynamic instruction, | 186 HInvokeDynamic instruction, |
| 187 HGraph graph, |
| 183 GlobalTypeInferenceResults results, | 188 GlobalTypeInferenceResults results, |
| 184 CompilerOptions options, | 189 CompilerOptions options, |
| 185 BackendHelpers helpers, | 190 BackendHelpers helpers, |
| 186 ClosedWorld closedWorld) { | 191 ClosedWorld closedWorld) { |
| 187 HInstruction input = instruction.inputs[1]; | 192 HInstruction input = instruction.inputs[1]; |
| 188 if (input.isNumber(closedWorld)) { | 193 if (input.isNumber(closedWorld)) { |
| 189 return new HBitNot( | 194 return new HBitNot( |
| 190 input, | 195 input, |
| 191 instruction.selector, | 196 instruction.selector, |
| 192 computeTypeFromInputTypes( | 197 computeTypeFromInputTypes( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 210 BackendHelpers helpers, | 215 BackendHelpers helpers, |
| 211 ClosedWorld closedWorld) { | 216 ClosedWorld closedWorld) { |
| 212 TypeMask operandType = instruction.inputs[1].instructionType; | 217 TypeMask operandType = instruction.inputs[1].instructionType; |
| 213 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType; | 218 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType; |
| 214 return super.computeTypeFromInputTypes( | 219 return super.computeTypeFromInputTypes( |
| 215 instruction, results, options, helpers, closedWorld); | 220 instruction, results, options, helpers, closedWorld); |
| 216 } | 221 } |
| 217 | 222 |
| 218 HInstruction tryConvertToBuiltin( | 223 HInstruction tryConvertToBuiltin( |
| 219 HInvokeDynamic instruction, | 224 HInvokeDynamic instruction, |
| 225 HGraph graph, |
| 220 GlobalTypeInferenceResults results, | 226 GlobalTypeInferenceResults results, |
| 221 CompilerOptions options, | 227 CompilerOptions options, |
| 222 BackendHelpers helpers, | 228 BackendHelpers helpers, |
| 223 ClosedWorld closedWorld) { | 229 ClosedWorld closedWorld) { |
| 224 HInstruction input = instruction.inputs[1]; | 230 HInstruction input = instruction.inputs[1]; |
| 225 if (input.isNumber(closedWorld)) { | 231 if (input.isNumber(closedWorld)) { |
| 226 return new HNegate(input, instruction.selector, input.instructionType); | 232 return new HNegate(input, instruction.selector, input.instructionType); |
| 227 } | 233 } |
| 228 return null; | 234 return null; |
| 229 } | 235 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 255 instruction, results, options, helpers, closedWorld); | 261 instruction, results, options, helpers, closedWorld); |
| 256 } | 262 } |
| 257 | 263 |
| 258 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) { | 264 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) { |
| 259 return instruction.inputs[1].isNumber(closedWorld) && | 265 return instruction.inputs[1].isNumber(closedWorld) && |
| 260 instruction.inputs[2].isNumber(closedWorld); | 266 instruction.inputs[2].isNumber(closedWorld); |
| 261 } | 267 } |
| 262 | 268 |
| 263 HInstruction tryConvertToBuiltin( | 269 HInstruction tryConvertToBuiltin( |
| 264 HInvokeDynamic instruction, | 270 HInvokeDynamic instruction, |
| 271 HGraph graph, |
| 265 GlobalTypeInferenceResults results, | 272 GlobalTypeInferenceResults results, |
| 266 CompilerOptions options, | 273 CompilerOptions options, |
| 267 BackendHelpers helpers, | 274 BackendHelpers helpers, |
| 268 ClosedWorld closedWorld) { | 275 ClosedWorld closedWorld) { |
| 269 if (isBuiltin(instruction, closedWorld)) { | 276 if (isBuiltin(instruction, closedWorld)) { |
| 270 HInstruction builtin = newBuiltinVariant( | 277 HInstruction builtin = newBuiltinVariant( |
| 271 instruction, results, options, helpers, closedWorld); | 278 instruction, results, options, helpers, closedWorld); |
| 272 if (builtin != null) return builtin; | 279 if (builtin != null) return builtin; |
| 273 // Even if there is no builtin equivalent instruction, we know | 280 // Even if there is no builtin equivalent instruction, we know |
| 274 // the instruction does not have any side effect, and that it | 281 // the instruction does not have any side effect, and that it |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 } | 605 } |
| 599 if (left.isUInt32(closedWorld) && isTwoOrGreater(right)) { | 606 if (left.isUInt32(closedWorld) && isTwoOrGreater(right)) { |
| 600 return true; | 607 return true; |
| 601 } | 608 } |
| 602 } | 609 } |
| 603 return false; | 610 return false; |
| 604 } | 611 } |
| 605 | 612 |
| 606 HInstruction tryConvertToBuiltin( | 613 HInstruction tryConvertToBuiltin( |
| 607 HInvokeDynamic instruction, | 614 HInvokeDynamic instruction, |
| 615 HGraph graph, |
| 608 GlobalTypeInferenceResults results, | 616 GlobalTypeInferenceResults results, |
| 609 CompilerOptions options, | 617 CompilerOptions options, |
| 610 BackendHelpers helpers, | 618 BackendHelpers helpers, |
| 611 ClosedWorld closedWorld) { | 619 ClosedWorld closedWorld) { |
| 612 HInstruction right = instruction.inputs[2]; | 620 HInstruction right = instruction.inputs[2]; |
| 613 if (isBuiltin(instruction, closedWorld)) { | 621 if (isBuiltin(instruction, closedWorld)) { |
| 614 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) { | 622 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) { |
| 615 if (hasUint31Result(instruction, closedWorld)) { | 623 if (hasUint31Result(instruction, closedWorld)) { |
| 616 return newBuiltinVariant( | 624 return newBuiltinVariant( |
| 617 instruction, results, options, helpers, closedWorld); | 625 instruction, results, options, helpers, closedWorld); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 | 697 |
| 690 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { | 698 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { |
| 691 const ShiftLeftSpecializer(); | 699 const ShiftLeftSpecializer(); |
| 692 | 700 |
| 693 BinaryOperation operation(ConstantSystem constantSystem) { | 701 BinaryOperation operation(ConstantSystem constantSystem) { |
| 694 return constantSystem.shiftLeft; | 702 return constantSystem.shiftLeft; |
| 695 } | 703 } |
| 696 | 704 |
| 697 HInstruction tryConvertToBuiltin( | 705 HInstruction tryConvertToBuiltin( |
| 698 HInvokeDynamic instruction, | 706 HInvokeDynamic instruction, |
| 707 HGraph graph, |
| 699 GlobalTypeInferenceResults results, | 708 GlobalTypeInferenceResults results, |
| 700 CompilerOptions options, | 709 CompilerOptions options, |
| 701 BackendHelpers helpers, | 710 BackendHelpers helpers, |
| 702 ClosedWorld closedWorld) { | 711 ClosedWorld closedWorld) { |
| 703 HInstruction left = instruction.inputs[1]; | 712 HInstruction left = instruction.inputs[1]; |
| 704 HInstruction right = instruction.inputs[2]; | 713 HInstruction right = instruction.inputs[2]; |
| 705 if (left.isNumber(closedWorld)) { | 714 if (left.isNumber(closedWorld)) { |
| 706 if (argumentLessThan32(right)) { | 715 if (argumentLessThan32(right)) { |
| 707 return newBuiltinVariant( | 716 return newBuiltinVariant( |
| 708 instruction, results, options, helpers, closedWorld); | 717 instruction, results, options, helpers, closedWorld); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 BackendHelpers helpers, | 753 BackendHelpers helpers, |
| 745 ClosedWorld closedWorld) { | 754 ClosedWorld closedWorld) { |
| 746 HInstruction left = instruction.inputs[1]; | 755 HInstruction left = instruction.inputs[1]; |
| 747 if (left.isUInt32(closedWorld)) return left.instructionType; | 756 if (left.isUInt32(closedWorld)) return left.instructionType; |
| 748 return super.computeTypeFromInputTypes( | 757 return super.computeTypeFromInputTypes( |
| 749 instruction, results, options, helpers, closedWorld); | 758 instruction, results, options, helpers, closedWorld); |
| 750 } | 759 } |
| 751 | 760 |
| 752 HInstruction tryConvertToBuiltin( | 761 HInstruction tryConvertToBuiltin( |
| 753 HInvokeDynamic instruction, | 762 HInvokeDynamic instruction, |
| 763 HGraph graph, |
| 754 GlobalTypeInferenceResults results, | 764 GlobalTypeInferenceResults results, |
| 755 CompilerOptions options, | 765 CompilerOptions options, |
| 756 BackendHelpers helpers, | 766 BackendHelpers helpers, |
| 757 ClosedWorld closedWorld) { | 767 ClosedWorld closedWorld) { |
| 758 HInstruction left = instruction.inputs[1]; | 768 HInstruction left = instruction.inputs[1]; |
| 759 HInstruction right = instruction.inputs[2]; | 769 HInstruction right = instruction.inputs[2]; |
| 760 if (left.isNumber(closedWorld)) { | 770 if (left.isNumber(closedWorld)) { |
| 761 if (argumentLessThan32(right) && isPositive(left, closedWorld)) { | 771 if (argumentLessThan32(right) && isPositive(left, closedWorld)) { |
| 762 return newBuiltinVariant( | 772 return newBuiltinVariant( |
| 763 instruction, results, options, helpers, closedWorld); | 773 instruction, results, options, helpers, closedWorld); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 ClosedWorld closedWorld) { | 932 ClosedWorld closedWorld) { |
| 923 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { | 933 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { |
| 924 return closedWorld.commonMasks.boolType; | 934 return closedWorld.commonMasks.boolType; |
| 925 } | 935 } |
| 926 return super.computeTypeFromInputTypes( | 936 return super.computeTypeFromInputTypes( |
| 927 instruction, results, options, helpers, closedWorld); | 937 instruction, results, options, helpers, closedWorld); |
| 928 } | 938 } |
| 929 | 939 |
| 930 HInstruction tryConvertToBuiltin( | 940 HInstruction tryConvertToBuiltin( |
| 931 HInvokeDynamic instruction, | 941 HInvokeDynamic instruction, |
| 942 HGraph graph, |
| 932 GlobalTypeInferenceResults results, | 943 GlobalTypeInferenceResults results, |
| 933 CompilerOptions options, | 944 CompilerOptions options, |
| 934 BackendHelpers helpers, | 945 BackendHelpers helpers, |
| 935 ClosedWorld closedWorld) { | 946 ClosedWorld closedWorld) { |
| 936 HInstruction left = instruction.inputs[1]; | 947 HInstruction left = instruction.inputs[1]; |
| 937 HInstruction right = instruction.inputs[2]; | 948 HInstruction right = instruction.inputs[2]; |
| 938 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) { | 949 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) { |
| 939 return newBuiltinVariant(instruction, closedWorld); | 950 return newBuiltinVariant(instruction, closedWorld); |
| 940 } | 951 } |
| 941 return null; | 952 return null; |
| 942 } | 953 } |
| 943 | 954 |
| 944 HInstruction newBuiltinVariant( | 955 HInstruction newBuiltinVariant( |
| 945 HInvokeDynamic instruction, ClosedWorld closedWorld); | 956 HInvokeDynamic instruction, ClosedWorld closedWorld); |
| 946 } | 957 } |
| 947 | 958 |
| 948 class EqualsSpecializer extends RelationalSpecializer { | 959 class EqualsSpecializer extends RelationalSpecializer { |
| 949 const EqualsSpecializer(); | 960 const EqualsSpecializer(); |
| 950 | 961 |
| 951 HInstruction tryConvertToBuiltin( | 962 HInstruction tryConvertToBuiltin( |
| 952 HInvokeDynamic instruction, | 963 HInvokeDynamic instruction, |
| 964 HGraph graph, |
| 953 GlobalTypeInferenceResults results, | 965 GlobalTypeInferenceResults results, |
| 954 CompilerOptions options, | 966 CompilerOptions options, |
| 955 BackendHelpers helpers, | 967 BackendHelpers helpers, |
| 956 ClosedWorld closedWorld) { | 968 ClosedWorld closedWorld) { |
| 957 HInstruction left = instruction.inputs[1]; | 969 HInstruction left = instruction.inputs[1]; |
| 958 HInstruction right = instruction.inputs[2]; | 970 HInstruction right = instruction.inputs[2]; |
| 959 TypeMask instructionType = left.instructionType; | 971 TypeMask instructionType = left.instructionType; |
| 960 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) { | 972 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) { |
| 961 return newBuiltinVariant(instruction, closedWorld); | 973 return newBuiltinVariant(instruction, closedWorld); |
| 962 } | 974 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 | 1053 |
| 1042 class CodeUnitAtSpecializer extends InvokeDynamicSpecializer { | 1054 class CodeUnitAtSpecializer extends InvokeDynamicSpecializer { |
| 1043 const CodeUnitAtSpecializer(); | 1055 const CodeUnitAtSpecializer(); |
| 1044 | 1056 |
| 1045 BinaryOperation operation(ConstantSystem constantSystem) { | 1057 BinaryOperation operation(ConstantSystem constantSystem) { |
| 1046 return constantSystem.codeUnitAt; | 1058 return constantSystem.codeUnitAt; |
| 1047 } | 1059 } |
| 1048 | 1060 |
| 1049 HInstruction tryConvertToBuiltin( | 1061 HInstruction tryConvertToBuiltin( |
| 1050 HInvokeDynamic instruction, | 1062 HInvokeDynamic instruction, |
| 1063 HGraph graph, |
| 1051 GlobalTypeInferenceResults results, | 1064 GlobalTypeInferenceResults results, |
| 1052 CompilerOptions options, | 1065 CompilerOptions options, |
| 1053 BackendHelpers helpers, | 1066 BackendHelpers helpers, |
| 1054 ClosedWorld closedWorld) { | 1067 ClosedWorld closedWorld) { |
| 1055 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index | 1068 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index |
| 1056 // bounds checking optimizations as for HIndex. | 1069 // bounds checking optimizations as for HIndex. |
| 1057 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1070 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 1058 if (receiver.isStringOrNull(closedWorld)) { | 1071 if (receiver.isStringOrNull(closedWorld)) { |
| 1059 // Even if there is no builtin equivalent instruction, we know | 1072 // Even if there is no builtin equivalent instruction, we know |
| 1060 // String.codeUnitAt does not have any side effect (other than throwing), | 1073 // String.codeUnitAt does not have any side effect (other than throwing), |
| 1061 // and that it can be GVN'ed. | 1074 // and that it can be GVN'ed. |
| 1062 clearAllSideEffects(instruction); | 1075 clearAllSideEffects(instruction); |
| 1063 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { | 1076 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { |
| 1064 instruction.selector = renameToOptimizedSelector( | 1077 instruction.selector = renameToOptimizedSelector( |
| 1065 '_codeUnitAt', instruction.selector, helpers); | 1078 '_codeUnitAt', instruction.selector, helpers); |
| 1066 } | 1079 } |
| 1067 } | 1080 } |
| 1068 return null; | 1081 return null; |
| 1069 } | 1082 } |
| 1070 } | 1083 } |
| 1071 | 1084 |
| 1085 class CompareToSpecializer extends InvokeDynamicSpecializer { |
| 1086 const CompareToSpecializer(); |
| 1087 |
| 1088 HInstruction tryConvertToBuiltin( |
| 1089 HInvokeDynamic instruction, |
| 1090 HGraph graph, |
| 1091 GlobalTypeInferenceResults results, |
| 1092 CompilerOptions options, |
| 1093 BackendHelpers helpers, |
| 1094 ClosedWorld closedWorld) { |
| 1095 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 1096 // `compareTo` has no side-effect (other than throwing) and can be GVN'ed |
| 1097 // for some known types. |
| 1098 if (receiver.isStringOrNull(closedWorld) || |
| 1099 receiver.isNumberOrNull(closedWorld)) { |
| 1100 // Replace `a.compareTo(a)` with `0`, but only if receiver and argument |
| 1101 // are such that no exceptions can be thrown. |
| 1102 HInstruction argument = instruction.inputs.last; |
| 1103 if ((receiver.isNumber(closedWorld) && argument.isNumber(closedWorld)) || |
| 1104 (receiver.isString(closedWorld) && argument.isString(closedWorld))) { |
| 1105 if (identical(receiver.nonCheck(), argument.nonCheck())) { |
| 1106 return graph.addConstantInt(0, closedWorld); |
| 1107 } |
| 1108 } |
| 1109 clearAllSideEffects(instruction); |
| 1110 } |
| 1111 return null; |
| 1112 } |
| 1113 } |
| 1114 |
| 1072 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { | 1115 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { |
| 1073 const IdempotentStringOperationSpecializer(); | 1116 const IdempotentStringOperationSpecializer(); |
| 1074 | 1117 |
| 1075 HInstruction tryConvertToBuiltin( | 1118 HInstruction tryConvertToBuiltin( |
| 1076 HInvokeDynamic instruction, | 1119 HInvokeDynamic instruction, |
| 1120 HGraph graph, |
| 1077 GlobalTypeInferenceResults results, | 1121 GlobalTypeInferenceResults results, |
| 1078 CompilerOptions options, | 1122 CompilerOptions options, |
| 1079 BackendHelpers helpers, | 1123 BackendHelpers helpers, |
| 1080 ClosedWorld closedWorld) { | 1124 ClosedWorld closedWorld) { |
| 1081 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1125 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 1082 if (receiver.isStringOrNull(closedWorld)) { | 1126 if (receiver.isStringOrNull(closedWorld)) { |
| 1083 // String.xxx does not have any side effect (other than throwing), and it | 1127 // String.xxx does not have any side effect (other than throwing), and it |
| 1084 // can be GVN'ed. | 1128 // can be GVN'ed. |
| 1085 clearAllSideEffects(instruction); | 1129 clearAllSideEffects(instruction); |
| 1086 } | 1130 } |
| 1087 return null; | 1131 return null; |
| 1088 } | 1132 } |
| 1089 } | 1133 } |
| 1090 | 1134 |
| 1091 class SubstringSpecializer extends IdempotentStringOperationSpecializer { | 1135 class SubstringSpecializer extends IdempotentStringOperationSpecializer { |
| 1092 const SubstringSpecializer(); | 1136 const SubstringSpecializer(); |
| 1093 } | 1137 } |
| 1094 | 1138 |
| 1095 class TrimSpecializer extends IdempotentStringOperationSpecializer { | 1139 class TrimSpecializer extends IdempotentStringOperationSpecializer { |
| 1096 const TrimSpecializer(); | 1140 const TrimSpecializer(); |
| 1097 } | 1141 } |
| 1098 | 1142 |
| 1099 class PatternMatchSpecializer extends InvokeDynamicSpecializer { | 1143 class PatternMatchSpecializer extends InvokeDynamicSpecializer { |
| 1100 const PatternMatchSpecializer(); | 1144 const PatternMatchSpecializer(); |
| 1101 | 1145 |
| 1102 HInstruction tryConvertToBuiltin( | 1146 HInstruction tryConvertToBuiltin( |
| 1103 HInvokeDynamic instruction, | 1147 HInvokeDynamic instruction, |
| 1148 HGraph graph, |
| 1104 GlobalTypeInferenceResults results, | 1149 GlobalTypeInferenceResults results, |
| 1105 CompilerOptions options, | 1150 CompilerOptions options, |
| 1106 BackendHelpers helpers, | 1151 BackendHelpers helpers, |
| 1107 ClosedWorld closedWorld) { | 1152 ClosedWorld closedWorld) { |
| 1108 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1153 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 1109 HInstruction pattern = instruction.inputs[2]; | 1154 HInstruction pattern = instruction.inputs[2]; |
| 1110 if (receiver.isStringOrNull(closedWorld) && | 1155 if (receiver.isStringOrNull(closedWorld) && |
| 1111 pattern.isStringOrNull(closedWorld)) { | 1156 pattern.isStringOrNull(closedWorld)) { |
| 1112 // String.contains(String s) does not have any side effect (other than | 1157 // String.contains(String s) does not have any side effect (other than |
| 1113 // throwing), and it can be GVN'ed. | 1158 // throwing), and it can be GVN'ed. |
| 1114 clearAllSideEffects(instruction); | 1159 clearAllSideEffects(instruction); |
| 1115 } | 1160 } |
| 1116 return null; | 1161 return null; |
| 1117 } | 1162 } |
| 1118 } | 1163 } |
| 1119 | 1164 |
| 1120 class RoundSpecializer extends InvokeDynamicSpecializer { | 1165 class RoundSpecializer extends InvokeDynamicSpecializer { |
| 1121 const RoundSpecializer(); | 1166 const RoundSpecializer(); |
| 1122 | 1167 |
| 1123 UnaryOperation operation(ConstantSystem constantSystem) { | 1168 UnaryOperation operation(ConstantSystem constantSystem) { |
| 1124 return constantSystem.round; | 1169 return constantSystem.round; |
| 1125 } | 1170 } |
| 1126 | 1171 |
| 1127 HInstruction tryConvertToBuiltin( | 1172 HInstruction tryConvertToBuiltin( |
| 1128 HInvokeDynamic instruction, | 1173 HInvokeDynamic instruction, |
| 1174 HGraph graph, |
| 1129 GlobalTypeInferenceResults results, | 1175 GlobalTypeInferenceResults results, |
| 1130 CompilerOptions options, | 1176 CompilerOptions options, |
| 1131 BackendHelpers helpers, | 1177 BackendHelpers helpers, |
| 1132 ClosedWorld closedWorld) { | 1178 ClosedWorld closedWorld) { |
| 1133 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1179 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 1134 if (receiver.isNumberOrNull(closedWorld)) { | 1180 if (receiver.isNumberOrNull(closedWorld)) { |
| 1135 // Even if there is no builtin equivalent instruction, we know the | 1181 // Even if there is no builtin equivalent instruction, we know the |
| 1136 // instruction does not have any side effect, and that it can be GVN'ed. | 1182 // instruction does not have any side effect, and that it can be GVN'ed. |
| 1137 clearAllSideEffects(instruction); | 1183 clearAllSideEffects(instruction); |
| 1138 } | 1184 } |
| 1139 return null; | 1185 return null; |
| 1140 } | 1186 } |
| 1141 } | 1187 } |
| OLD | NEW |