Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart

Issue 2739953002: dart2js: num.compareTo is pure, and a.compareTo(a) is zero (Closed)
Patch Set: Fix merge error Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/optimize.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698