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

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

Issue 2777163002: Make codegen and optimizations depend more directly on data objects. (Closed)
Patch Set: Created 3 years, 9 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
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 '../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';
11 import '../js_backend/backend_helpers.dart';
12 import '../options.dart';
11 import '../types/types.dart'; 13 import '../types/types.dart';
12 import '../universe/call_structure.dart'; 14 import '../universe/call_structure.dart';
13 import '../universe/selector.dart'; 15 import '../universe/selector.dart';
14 import '../world.dart' show ClosedWorld; 16 import '../world.dart' show ClosedWorld;
15 import 'nodes.dart'; 17 import 'nodes.dart';
16 import 'types.dart'; 18 import 'types.dart';
17 19
18 /** 20 /**
19 * [InvokeDynamicSpecializer] and its subclasses are helpers to 21 * [InvokeDynamicSpecializer] and its subclasses are helpers to
20 * optimize intercepted dynamic calls. It knows what input types 22 * optimize intercepted dynamic calls. It knows what input types
21 * would be beneficial for performance, and how to change a invoke 23 * would be beneficial for performance, and how to change a invoke
22 * dynamic to a builtin instruction (e.g. HIndex, HBitNot). 24 * dynamic to a builtin instruction (e.g. HIndex, HBitNot).
23 */ 25 */
24 class InvokeDynamicSpecializer { 26 class InvokeDynamicSpecializer {
25 const InvokeDynamicSpecializer(); 27 const InvokeDynamicSpecializer();
26 28
27 TypeMask computeTypeFromInputTypes( 29 TypeMask computeTypeFromInputTypes(
28 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 30 HInvokeDynamic instruction,
29 return TypeMaskFactory.inferredTypeForSelector(instruction.selector, 31 GlobalTypeInferenceResults results,
30 instruction.mask, compiler.globalInference.results); 32 CompilerOptions options,
33 BackendHelpers helpers,
34 ClosedWorld closedWorld) {
35 return TypeMaskFactory.inferredTypeForSelector(
36 instruction.selector, instruction.mask, results);
31 } 37 }
32 38
33 HInstruction tryConvertToBuiltin( 39 HInstruction tryConvertToBuiltin(
34 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 40 HInvokeDynamic instruction,
41 GlobalTypeInferenceResults results,
42 CompilerOptions options,
43 BackendHelpers helpers,
44 ClosedWorld closedWorld) {
35 return null; 45 return null;
36 } 46 }
37 47
38 void clearAllSideEffects(HInstruction instruction) { 48 void clearAllSideEffects(HInstruction instruction) {
39 instruction.sideEffects.clearAllSideEffects(); 49 instruction.sideEffects.clearAllSideEffects();
40 instruction.sideEffects.clearAllDependencies(); 50 instruction.sideEffects.clearAllDependencies();
41 instruction.setUseGvn(); 51 instruction.setUseGvn();
42 } 52 }
43 53
44 Selector renameToOptimizedSelector( 54 Selector renameToOptimizedSelector(
45 String name, Selector selector, Compiler compiler) { 55 String name, Selector selector, BackendHelpers helpers) {
46 if (selector.name == name) return selector; 56 if (selector.name == name) return selector;
47 JavaScriptBackend backend = compiler.backend; 57 return new Selector.call(new Name(name, helpers.interceptorsLibrary),
48 return new Selector.call(
49 new Name(name, backend.helpers.interceptorsLibrary),
50 new CallStructure(selector.argumentCount)); 58 new CallStructure(selector.argumentCount));
51 } 59 }
52 60
53 Operation operation(ConstantSystem constantSystem) => null; 61 Operation operation(ConstantSystem constantSystem) => null;
54 62
55 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) { 63 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) {
56 if (selector.isIndex) return const IndexSpecializer(); 64 if (selector.isIndex) return const IndexSpecializer();
57 if (selector.isIndexSet) return const IndexAssignSpecializer(); 65 if (selector.isIndexSet) return const IndexAssignSpecializer();
58 String name = selector.name; 66 String name = selector.name;
59 if (selector.isOperator) { 67 if (selector.isOperator) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 } 109 }
102 } 110 }
103 return const InvokeDynamicSpecializer(); 111 return const InvokeDynamicSpecializer();
104 } 112 }
105 } 113 }
106 114
107 class IndexAssignSpecializer extends InvokeDynamicSpecializer { 115 class IndexAssignSpecializer extends InvokeDynamicSpecializer {
108 const IndexAssignSpecializer(); 116 const IndexAssignSpecializer();
109 117
110 HInstruction tryConvertToBuiltin( 118 HInstruction tryConvertToBuiltin(
111 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 119 HInvokeDynamic instruction,
120 GlobalTypeInferenceResults results,
121 CompilerOptions options,
122 BackendHelpers helpers,
123 ClosedWorld closedWorld) {
112 if (instruction.inputs[1].isMutableIndexable(closedWorld)) { 124 if (instruction.inputs[1].isMutableIndexable(closedWorld)) {
113 if (!instruction.inputs[2].isInteger(closedWorld) && 125 if (!instruction.inputs[2].isInteger(closedWorld) &&
114 compiler.options.enableTypeAssertions) { 126 options.enableTypeAssertions) {
115 // We want the right checked mode error. 127 // We want the right checked mode error.
116 return null; 128 return null;
117 } 129 }
118 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2], 130 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2],
119 instruction.inputs[3], instruction.selector); 131 instruction.inputs[3], instruction.selector);
120 } 132 }
121 return null; 133 return null;
122 } 134 }
123 } 135 }
124 136
125 class IndexSpecializer extends InvokeDynamicSpecializer { 137 class IndexSpecializer extends InvokeDynamicSpecializer {
126 const IndexSpecializer(); 138 const IndexSpecializer();
127 139
128 HInstruction tryConvertToBuiltin( 140 HInstruction tryConvertToBuiltin(
129 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 141 HInvokeDynamic instruction,
142 GlobalTypeInferenceResults results,
143 CompilerOptions options,
144 BackendHelpers helpers,
145 ClosedWorld closedWorld) {
130 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null; 146 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null;
131 if (!instruction.inputs[2].isInteger(closedWorld) && 147 if (!instruction.inputs[2].isInteger(closedWorld) &&
132 compiler.options.enableTypeAssertions) { 148 options.enableTypeAssertions) {
133 // We want the right checked mode error. 149 // We want the right checked mode error.
134 return null; 150 return null;
135 } 151 }
136 TypeMask receiverType = 152 TypeMask receiverType =
137 instruction.getDartReceiver(closedWorld).instructionType; 153 instruction.getDartReceiver(closedWorld).instructionType;
138 TypeMask type = TypeMaskFactory.inferredTypeForSelector( 154 TypeMask type = TypeMaskFactory.inferredTypeForSelector(
139 instruction.selector, receiverType, compiler.globalInference.results); 155 instruction.selector, receiverType, results);
140 return new HIndex(instruction.inputs[1], instruction.inputs[2], 156 return new HIndex(instruction.inputs[1], instruction.inputs[2],
141 instruction.selector, type); 157 instruction.selector, type);
142 } 158 }
143 } 159 }
144 160
145 class BitNotSpecializer extends InvokeDynamicSpecializer { 161 class BitNotSpecializer extends InvokeDynamicSpecializer {
146 const BitNotSpecializer(); 162 const BitNotSpecializer();
147 163
148 UnaryOperation operation(ConstantSystem constantSystem) { 164 UnaryOperation operation(ConstantSystem constantSystem) {
149 return constantSystem.bitNot; 165 return constantSystem.bitNot;
150 } 166 }
151 167
152 TypeMask computeTypeFromInputTypes( 168 TypeMask computeTypeFromInputTypes(
153 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 169 HInvokeDynamic instruction,
170 GlobalTypeInferenceResults results,
171 CompilerOptions options,
172 BackendHelpers helpers,
173 ClosedWorld closedWorld) {
154 // All bitwise operations on primitive types either produce an 174 // All bitwise operations on primitive types either produce an
155 // integer or throw an error. 175 // integer or throw an error.
156 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { 176 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) {
157 return closedWorld.commonMasks.uint32Type; 177 return closedWorld.commonMasks.uint32Type;
158 } 178 }
159 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 179 return super.computeTypeFromInputTypes(
180 instruction, results, options, helpers, closedWorld);
160 } 181 }
161 182
162 HInstruction tryConvertToBuiltin( 183 HInstruction tryConvertToBuiltin(
163 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 184 HInvokeDynamic instruction,
185 GlobalTypeInferenceResults results,
186 CompilerOptions options,
187 BackendHelpers helpers,
188 ClosedWorld closedWorld) {
164 HInstruction input = instruction.inputs[1]; 189 HInstruction input = instruction.inputs[1];
165 if (input.isNumber(closedWorld)) { 190 if (input.isNumber(closedWorld)) {
166 return new HBitNot(input, instruction.selector, 191 return new HBitNot(
167 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 192 input,
193 instruction.selector,
194 computeTypeFromInputTypes(
195 instruction, results, options, helpers, closedWorld));
168 } 196 }
169 return null; 197 return null;
170 } 198 }
171 } 199 }
172 200
173 class UnaryNegateSpecializer extends InvokeDynamicSpecializer { 201 class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
174 const UnaryNegateSpecializer(); 202 const UnaryNegateSpecializer();
175 203
176 UnaryOperation operation(ConstantSystem constantSystem) { 204 UnaryOperation operation(ConstantSystem constantSystem) {
177 return constantSystem.negate; 205 return constantSystem.negate;
178 } 206 }
179 207
180 TypeMask computeTypeFromInputTypes( 208 TypeMask computeTypeFromInputTypes(
181 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 209 HInvokeDynamic instruction,
210 GlobalTypeInferenceResults results,
211 CompilerOptions options,
212 BackendHelpers helpers,
213 ClosedWorld closedWorld) {
182 TypeMask operandType = instruction.inputs[1].instructionType; 214 TypeMask operandType = instruction.inputs[1].instructionType;
183 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType; 215 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType;
184 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 216 return super.computeTypeFromInputTypes(
217 instruction, results, options, helpers, closedWorld);
185 } 218 }
186 219
187 HInstruction tryConvertToBuiltin( 220 HInstruction tryConvertToBuiltin(
188 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 221 HInvokeDynamic instruction,
222 GlobalTypeInferenceResults results,
223 CompilerOptions options,
224 BackendHelpers helpers,
225 ClosedWorld closedWorld) {
189 HInstruction input = instruction.inputs[1]; 226 HInstruction input = instruction.inputs[1];
190 if (input.isNumber(closedWorld)) { 227 if (input.isNumber(closedWorld)) {
191 return new HNegate(input, instruction.selector, input.instructionType); 228 return new HNegate(input, instruction.selector, input.instructionType);
192 } 229 }
193 return null; 230 return null;
194 } 231 }
195 } 232 }
196 233
197 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer { 234 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
198 const BinaryArithmeticSpecializer(); 235 const BinaryArithmeticSpecializer();
199 236
200 TypeMask computeTypeFromInputTypes( 237 TypeMask computeTypeFromInputTypes(
201 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 238 HInvokeDynamic instruction,
239 GlobalTypeInferenceResults results,
240 CompilerOptions options,
241 BackendHelpers helpers,
242 ClosedWorld closedWorld) {
202 HInstruction left = instruction.inputs[1]; 243 HInstruction left = instruction.inputs[1];
203 HInstruction right = instruction.inputs[2]; 244 HInstruction right = instruction.inputs[2];
204 if (left.isIntegerOrNull(closedWorld) && 245 if (left.isIntegerOrNull(closedWorld) &&
205 right.isIntegerOrNull(closedWorld)) { 246 right.isIntegerOrNull(closedWorld)) {
206 return closedWorld.commonMasks.intType; 247 return closedWorld.commonMasks.intType;
207 } 248 }
208 if (left.isNumberOrNull(closedWorld)) { 249 if (left.isNumberOrNull(closedWorld)) {
209 if (left.isDoubleOrNull(closedWorld) || 250 if (left.isDoubleOrNull(closedWorld) ||
210 right.isDoubleOrNull(closedWorld)) { 251 right.isDoubleOrNull(closedWorld)) {
211 return closedWorld.commonMasks.doubleType; 252 return closedWorld.commonMasks.doubleType;
212 } 253 }
213 return closedWorld.commonMasks.numType; 254 return closedWorld.commonMasks.numType;
214 } 255 }
215 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 256 return super.computeTypeFromInputTypes(
257 instruction, results, options, helpers, closedWorld);
216 } 258 }
217 259
218 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) { 260 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) {
219 return instruction.inputs[1].isNumber(closedWorld) && 261 return instruction.inputs[1].isNumber(closedWorld) &&
220 instruction.inputs[2].isNumber(closedWorld); 262 instruction.inputs[2].isNumber(closedWorld);
221 } 263 }
222 264
223 HInstruction tryConvertToBuiltin( 265 HInstruction tryConvertToBuiltin(
224 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 266 HInvokeDynamic instruction,
267 GlobalTypeInferenceResults results,
268 CompilerOptions options,
269 BackendHelpers helpers,
270 ClosedWorld closedWorld) {
225 if (isBuiltin(instruction, closedWorld)) { 271 if (isBuiltin(instruction, closedWorld)) {
226 HInstruction builtin = 272 HInstruction builtin = newBuiltinVariant(
227 newBuiltinVariant(instruction, compiler, closedWorld); 273 instruction, results, options, helpers, closedWorld);
228 if (builtin != null) return builtin; 274 if (builtin != null) return builtin;
229 // Even if there is no builtin equivalent instruction, we know 275 // Even if there is no builtin equivalent instruction, we know
230 // the instruction does not have any side effect, and that it 276 // the instruction does not have any side effect, and that it
231 // can be GVN'ed. 277 // can be GVN'ed.
232 clearAllSideEffects(instruction); 278 clearAllSideEffects(instruction);
233 } 279 }
234 return null; 280 return null;
235 } 281 }
236 282
237 bool inputsArePositiveIntegers( 283 bool inputsArePositiveIntegers(
238 HInstruction instruction, ClosedWorld closedWorld) { 284 HInstruction instruction, ClosedWorld closedWorld) {
239 HInstruction left = instruction.inputs[1]; 285 HInstruction left = instruction.inputs[1];
240 HInstruction right = instruction.inputs[2]; 286 HInstruction right = instruction.inputs[2];
241 return left.isPositiveIntegerOrNull(closedWorld) && 287 return left.isPositiveIntegerOrNull(closedWorld) &&
242 right.isPositiveIntegerOrNull(closedWorld); 288 right.isPositiveIntegerOrNull(closedWorld);
243 } 289 }
244 290
245 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) { 291 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) {
246 HInstruction left = instruction.inputs[1]; 292 HInstruction left = instruction.inputs[1];
247 HInstruction right = instruction.inputs[2]; 293 HInstruction right = instruction.inputs[2];
248 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld); 294 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld);
249 } 295 }
250 296
251 HInstruction newBuiltinVariant( 297 HInstruction newBuiltinVariant(
252 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld); 298 HInvokeDynamic instruction,
299 GlobalTypeInferenceResults results,
300 CompilerOptions options,
301 BackendHelpers helpers,
302 ClosedWorld closedWorld);
253 } 303 }
254 304
255 class AddSpecializer extends BinaryArithmeticSpecializer { 305 class AddSpecializer extends BinaryArithmeticSpecializer {
256 const AddSpecializer(); 306 const AddSpecializer();
257 307
258 TypeMask computeTypeFromInputTypes( 308 TypeMask computeTypeFromInputTypes(
259 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 309 HInvokeDynamic instruction,
310 GlobalTypeInferenceResults results,
311 CompilerOptions options,
312 BackendHelpers helpers,
313 ClosedWorld closedWorld) {
260 if (inputsAreUInt31(instruction, closedWorld)) { 314 if (inputsAreUInt31(instruction, closedWorld)) {
261 return closedWorld.commonMasks.uint32Type; 315 return closedWorld.commonMasks.uint32Type;
262 } 316 }
263 if (inputsArePositiveIntegers(instruction, closedWorld)) { 317 if (inputsArePositiveIntegers(instruction, closedWorld)) {
264 return closedWorld.commonMasks.positiveIntType; 318 return closedWorld.commonMasks.positiveIntType;
265 } 319 }
266 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 320 return super.computeTypeFromInputTypes(
321 instruction, results, options, helpers, closedWorld);
267 } 322 }
268 323
269 BinaryOperation operation(ConstantSystem constantSystem) { 324 BinaryOperation operation(ConstantSystem constantSystem) {
270 return constantSystem.add; 325 return constantSystem.add;
271 } 326 }
272 327
273 HInstruction newBuiltinVariant( 328 HInstruction newBuiltinVariant(
274 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 329 HInvokeDynamic instruction,
330 GlobalTypeInferenceResults results,
331 CompilerOptions options,
332 BackendHelpers helpers,
333 ClosedWorld closedWorld) {
275 return new HAdd( 334 return new HAdd(
276 instruction.inputs[1], 335 instruction.inputs[1],
277 instruction.inputs[2], 336 instruction.inputs[2],
278 instruction.selector, 337 instruction.selector,
279 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 338 computeTypeFromInputTypes(
339 instruction, results, options, helpers, closedWorld));
280 } 340 }
281 } 341 }
282 342
283 class DivideSpecializer extends BinaryArithmeticSpecializer { 343 class DivideSpecializer extends BinaryArithmeticSpecializer {
284 const DivideSpecializer(); 344 const DivideSpecializer();
285 345
286 BinaryOperation operation(ConstantSystem constantSystem) { 346 BinaryOperation operation(ConstantSystem constantSystem) {
287 return constantSystem.divide; 347 return constantSystem.divide;
288 } 348 }
289 349
290 TypeMask computeTypeFromInputTypes( 350 TypeMask computeTypeFromInputTypes(
291 HInstruction instruction, Compiler compiler, ClosedWorld closedWorld) { 351 HInstruction instruction,
352 GlobalTypeInferenceResults results,
353 CompilerOptions options,
354 BackendHelpers helpers,
355 ClosedWorld closedWorld) {
292 HInstruction left = instruction.inputs[1]; 356 HInstruction left = instruction.inputs[1];
293 if (left.isNumberOrNull(closedWorld)) { 357 if (left.isNumberOrNull(closedWorld)) {
294 return closedWorld.commonMasks.doubleType; 358 return closedWorld.commonMasks.doubleType;
295 } 359 }
296 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 360 return super.computeTypeFromInputTypes(
361 instruction, results, options, helpers, closedWorld);
297 } 362 }
298 363
299 HInstruction newBuiltinVariant( 364 HInstruction newBuiltinVariant(
300 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 365 HInvokeDynamic instruction,
366 GlobalTypeInferenceResults results,
367 CompilerOptions options,
368 BackendHelpers helpers,
369 ClosedWorld closedWorld) {
301 return new HDivide(instruction.inputs[1], instruction.inputs[2], 370 return new HDivide(instruction.inputs[1], instruction.inputs[2],
302 instruction.selector, closedWorld.commonMasks.doubleType); 371 instruction.selector, closedWorld.commonMasks.doubleType);
303 } 372 }
304 } 373 }
305 374
306 class ModuloSpecializer extends BinaryArithmeticSpecializer { 375 class ModuloSpecializer extends BinaryArithmeticSpecializer {
307 const ModuloSpecializer(); 376 const ModuloSpecializer();
308 377
309 TypeMask computeTypeFromInputTypes( 378 TypeMask computeTypeFromInputTypes(
310 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 379 HInvokeDynamic instruction,
380 GlobalTypeInferenceResults results,
381 CompilerOptions options,
382 BackendHelpers helpers,
383 ClosedWorld closedWorld) {
311 if (inputsArePositiveIntegers(instruction, closedWorld)) { 384 if (inputsArePositiveIntegers(instruction, closedWorld)) {
312 return closedWorld.commonMasks.positiveIntType; 385 return closedWorld.commonMasks.positiveIntType;
313 } 386 }
314 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 387 return super.computeTypeFromInputTypes(
388 instruction, results, options, helpers, closedWorld);
315 } 389 }
316 390
317 BinaryOperation operation(ConstantSystem constantSystem) { 391 BinaryOperation operation(ConstantSystem constantSystem) {
318 return constantSystem.modulo; 392 return constantSystem.modulo;
319 } 393 }
320 394
321 HInstruction newBuiltinVariant( 395 HInstruction newBuiltinVariant(
322 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 396 HInvokeDynamic instruction,
397 GlobalTypeInferenceResults results,
398 CompilerOptions options,
399 BackendHelpers helpers,
400 ClosedWorld closedWorld) {
323 // Modulo cannot be mapped to the native operator (different semantics). 401 // Modulo cannot be mapped to the native operator (different semantics).
324 402
325 // We can use HRemainder if both inputs are non-negative and the receiver 403 // We can use HRemainder if both inputs are non-negative and the receiver
326 // cannot be -0.0. Note that -0.0 is considered to be an int, so until we 404 // cannot be -0.0. Note that -0.0 is considered to be an int, so until we
327 // track -0.0 precisely, we have to syntatically filter inputs that cannot 405 // track -0.0 precisely, we have to syntatically filter inputs that cannot
328 // generate -0.0. 406 // generate -0.0.
329 bool canBePositiveZero(HInstruction input) { 407 bool canBePositiveZero(HInstruction input) {
330 if (input is HConstant) { 408 if (input is HConstant) {
331 ConstantValue value = input.constant; 409 ConstantValue value = input.constant;
332 if (value is DoubleConstantValue && value.isZero) return true; 410 if (value is DoubleConstantValue && value.isZero) return true;
(...skipping 26 matching lines...) Expand all
359 } 437 }
360 return true; 438 return true;
361 } 439 }
362 440
363 if (inputsArePositiveIntegers(instruction, closedWorld) && 441 if (inputsArePositiveIntegers(instruction, closedWorld) &&
364 !canBeNegativeZero(instruction.getDartReceiver(closedWorld))) { 442 !canBeNegativeZero(instruction.getDartReceiver(closedWorld))) {
365 return new HRemainder( 443 return new HRemainder(
366 instruction.inputs[1], 444 instruction.inputs[1],
367 instruction.inputs[2], 445 instruction.inputs[2],
368 instruction.selector, 446 instruction.selector,
369 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 447 computeTypeFromInputTypes(
448 instruction, results, options, helpers, closedWorld));
370 } 449 }
371 // TODO(sra): 450 // TODO(sra):
372 // a % N --> a & (N-1), N=2^k, where a>=0, does not have -0.0 problem. 451 // a % N --> a & (N-1), N=2^k, where a>=0, does not have -0.0 problem.
373 452
374 // TODO(sra): We could avoid problems with -0.0 if we generate x % y as (x + 453 // TODO(sra): We could avoid problems with -0.0 if we generate x % y as (x +
375 // 0) % y, but we would have to fix HAdd optimizations. 454 // 0) % y, but we would have to fix HAdd optimizations.
376 455
377 // TODO(sra): We could replace $mod with HRemainder when we don't care about 456 // TODO(sra): We could replace $mod with HRemainder when we don't care about
378 // a -0.0 result (e.g. a % 10 == 0, a[i % 3]). This is tricky, since we 457 // a -0.0 result (e.g. a % 10 == 0, a[i % 3]). This is tricky, since we
379 // don't want to ruin GVN opportunities. 458 // don't want to ruin GVN opportunities.
380 return null; 459 return null;
381 } 460 }
382 } 461 }
383 462
384 class RemainderSpecializer extends BinaryArithmeticSpecializer { 463 class RemainderSpecializer extends BinaryArithmeticSpecializer {
385 const RemainderSpecializer(); 464 const RemainderSpecializer();
386 465
387 TypeMask computeTypeFromInputTypes( 466 TypeMask computeTypeFromInputTypes(
388 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 467 HInvokeDynamic instruction,
468 GlobalTypeInferenceResults results,
469 CompilerOptions options,
470 BackendHelpers helpers,
471 ClosedWorld closedWorld) {
389 if (inputsArePositiveIntegers(instruction, closedWorld)) { 472 if (inputsArePositiveIntegers(instruction, closedWorld)) {
390 return closedWorld.commonMasks.positiveIntType; 473 return closedWorld.commonMasks.positiveIntType;
391 } 474 }
392 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 475 return super.computeTypeFromInputTypes(
476 instruction, results, options, helpers, closedWorld);
393 } 477 }
394 478
395 BinaryOperation operation(ConstantSystem constantSystem) { 479 BinaryOperation operation(ConstantSystem constantSystem) {
396 return constantSystem.remainder; 480 return constantSystem.remainder;
397 } 481 }
398 482
399 HInstruction newBuiltinVariant( 483 HInstruction newBuiltinVariant(
400 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 484 HInvokeDynamic instruction,
485 GlobalTypeInferenceResults results,
486 CompilerOptions options,
487 BackendHelpers helpers,
488 ClosedWorld closedWorld) {
401 return new HRemainder( 489 return new HRemainder(
402 instruction.inputs[1], 490 instruction.inputs[1],
403 instruction.inputs[2], 491 instruction.inputs[2],
404 instruction.selector, 492 instruction.selector,
405 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 493 computeTypeFromInputTypes(
494 instruction, results, options, helpers, closedWorld));
406 } 495 }
407 } 496 }
408 497
409 class MultiplySpecializer extends BinaryArithmeticSpecializer { 498 class MultiplySpecializer extends BinaryArithmeticSpecializer {
410 const MultiplySpecializer(); 499 const MultiplySpecializer();
411 500
412 BinaryOperation operation(ConstantSystem constantSystem) { 501 BinaryOperation operation(ConstantSystem constantSystem) {
413 return constantSystem.multiply; 502 return constantSystem.multiply;
414 } 503 }
415 504
416 TypeMask computeTypeFromInputTypes( 505 TypeMask computeTypeFromInputTypes(
417 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 506 HInvokeDynamic instruction,
507 GlobalTypeInferenceResults results,
508 CompilerOptions options,
509 BackendHelpers helpers,
510 ClosedWorld closedWorld) {
418 if (inputsArePositiveIntegers(instruction, closedWorld)) { 511 if (inputsArePositiveIntegers(instruction, closedWorld)) {
419 return closedWorld.commonMasks.positiveIntType; 512 return closedWorld.commonMasks.positiveIntType;
420 } 513 }
421 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 514 return super.computeTypeFromInputTypes(
515 instruction, results, options, helpers, closedWorld);
422 } 516 }
423 517
424 HInstruction newBuiltinVariant( 518 HInstruction newBuiltinVariant(
425 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 519 HInvokeDynamic instruction,
520 GlobalTypeInferenceResults results,
521 CompilerOptions options,
522 BackendHelpers helpers,
523 ClosedWorld closedWorld) {
426 return new HMultiply( 524 return new HMultiply(
427 instruction.inputs[1], 525 instruction.inputs[1],
428 instruction.inputs[2], 526 instruction.inputs[2],
429 instruction.selector, 527 instruction.selector,
430 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 528 computeTypeFromInputTypes(
529 instruction, results, options, helpers, closedWorld));
431 } 530 }
432 } 531 }
433 532
434 class SubtractSpecializer extends BinaryArithmeticSpecializer { 533 class SubtractSpecializer extends BinaryArithmeticSpecializer {
435 const SubtractSpecializer(); 534 const SubtractSpecializer();
436 535
437 BinaryOperation operation(ConstantSystem constantSystem) { 536 BinaryOperation operation(ConstantSystem constantSystem) {
438 return constantSystem.subtract; 537 return constantSystem.subtract;
439 } 538 }
440 539
441 HInstruction newBuiltinVariant( 540 HInstruction newBuiltinVariant(
442 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 541 HInvokeDynamic instruction,
542 GlobalTypeInferenceResults results,
543 CompilerOptions options,
544 BackendHelpers helpers,
545 ClosedWorld closedWorld) {
443 return new HSubtract( 546 return new HSubtract(
444 instruction.inputs[1], 547 instruction.inputs[1],
445 instruction.inputs[2], 548 instruction.inputs[2],
446 instruction.selector, 549 instruction.selector,
447 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 550 computeTypeFromInputTypes(
551 instruction, results, options, helpers, closedWorld));
448 } 552 }
449 } 553 }
450 554
451 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { 555 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
452 const TruncatingDivideSpecializer(); 556 const TruncatingDivideSpecializer();
453 557
454 BinaryOperation operation(ConstantSystem constantSystem) { 558 BinaryOperation operation(ConstantSystem constantSystem) {
455 return constantSystem.truncatingDivide; 559 return constantSystem.truncatingDivide;
456 } 560 }
457 561
458 TypeMask computeTypeFromInputTypes( 562 TypeMask computeTypeFromInputTypes(
459 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 563 HInvokeDynamic instruction,
564 GlobalTypeInferenceResults results,
565 CompilerOptions options,
566 BackendHelpers helpers,
567 ClosedWorld closedWorld) {
460 if (hasUint31Result(instruction, closedWorld)) { 568 if (hasUint31Result(instruction, closedWorld)) {
461 return closedWorld.commonMasks.uint31Type; 569 return closedWorld.commonMasks.uint31Type;
462 } 570 }
463 if (inputsArePositiveIntegers(instruction, closedWorld)) { 571 if (inputsArePositiveIntegers(instruction, closedWorld)) {
464 return closedWorld.commonMasks.positiveIntType; 572 return closedWorld.commonMasks.positiveIntType;
465 } 573 }
466 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 574 return super.computeTypeFromInputTypes(
575 instruction, results, options, helpers, closedWorld);
467 } 576 }
468 577
469 bool isNotZero(HInstruction instruction) { 578 bool isNotZero(HInstruction instruction) {
470 if (!instruction.isConstantInteger()) return false; 579 if (!instruction.isConstantInteger()) return false;
471 HConstant rightConstant = instruction; 580 HConstant rightConstant = instruction;
472 IntConstantValue intConstant = rightConstant.constant; 581 IntConstantValue intConstant = rightConstant.constant;
473 int count = intConstant.primitiveValue; 582 int count = intConstant.primitiveValue;
474 return count != 0; 583 return count != 0;
475 } 584 }
476 585
(...skipping 13 matching lines...) Expand all
490 return true; 599 return true;
491 } 600 }
492 if (left.isUInt32(closedWorld) && isTwoOrGreater(right)) { 601 if (left.isUInt32(closedWorld) && isTwoOrGreater(right)) {
493 return true; 602 return true;
494 } 603 }
495 } 604 }
496 return false; 605 return false;
497 } 606 }
498 607
499 HInstruction tryConvertToBuiltin( 608 HInstruction tryConvertToBuiltin(
500 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 609 HInvokeDynamic instruction,
610 GlobalTypeInferenceResults results,
611 CompilerOptions options,
612 BackendHelpers helpers,
613 ClosedWorld closedWorld) {
501 HInstruction right = instruction.inputs[2]; 614 HInstruction right = instruction.inputs[2];
502 if (isBuiltin(instruction, closedWorld)) { 615 if (isBuiltin(instruction, closedWorld)) {
503 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) { 616 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) {
504 if (hasUint31Result(instruction, closedWorld)) { 617 if (hasUint31Result(instruction, closedWorld)) {
505 return newBuiltinVariant(instruction, compiler, closedWorld); 618 return newBuiltinVariant(
619 instruction, results, options, helpers, closedWorld);
506 } 620 }
507 // We can call _tdivFast because the rhs is a 32bit integer 621 // We can call _tdivFast because the rhs is a 32bit integer
508 // and not 0, nor -1. 622 // and not 0, nor -1.
509 instruction.selector = renameToOptimizedSelector( 623 instruction.selector = renameToOptimizedSelector(
510 '_tdivFast', instruction.selector, compiler); 624 '_tdivFast', instruction.selector, helpers);
511 } 625 }
512 clearAllSideEffects(instruction); 626 clearAllSideEffects(instruction);
513 } 627 }
514 return null; 628 return null;
515 } 629 }
516 630
517 HInstruction newBuiltinVariant( 631 HInstruction newBuiltinVariant(
518 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 632 HInvokeDynamic instruction,
633 GlobalTypeInferenceResults results,
634 CompilerOptions options,
635 BackendHelpers helpers,
636 ClosedWorld closedWorld) {
519 return new HTruncatingDivide( 637 return new HTruncatingDivide(
520 instruction.inputs[1], 638 instruction.inputs[1],
521 instruction.inputs[2], 639 instruction.inputs[2],
522 instruction.selector, 640 instruction.selector,
523 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 641 computeTypeFromInputTypes(
642 instruction, results, options, helpers, closedWorld));
524 } 643 }
525 } 644 }
526 645
527 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { 646 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
528 const BinaryBitOpSpecializer(); 647 const BinaryBitOpSpecializer();
529 648
530 TypeMask computeTypeFromInputTypes( 649 TypeMask computeTypeFromInputTypes(
531 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 650 HInvokeDynamic instruction,
651 GlobalTypeInferenceResults results,
652 CompilerOptions options,
653 BackendHelpers helpers,
654 ClosedWorld closedWorld) {
532 // All bitwise operations on primitive types either produce an 655 // All bitwise operations on primitive types either produce an
533 // integer or throw an error. 656 // integer or throw an error.
534 HInstruction left = instruction.inputs[1]; 657 HInstruction left = instruction.inputs[1];
535 if (left.isPrimitiveOrNull(closedWorld)) { 658 if (left.isPrimitiveOrNull(closedWorld)) {
536 return closedWorld.commonMasks.uint32Type; 659 return closedWorld.commonMasks.uint32Type;
537 } 660 }
538 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 661 return super.computeTypeFromInputTypes(
662 instruction, results, options, helpers, closedWorld);
539 } 663 }
540 664
541 bool argumentLessThan32(HInstruction instruction) { 665 bool argumentLessThan32(HInstruction instruction) {
542 return argumentInRange(instruction, 0, 31); 666 return argumentInRange(instruction, 0, 31);
543 } 667 }
544 668
545 bool argumentInRange(HInstruction instruction, int low, int high) { 669 bool argumentInRange(HInstruction instruction, int low, int high) {
546 if (instruction.isConstantInteger()) { 670 if (instruction.isConstantInteger()) {
547 HConstant rightConstant = instruction; 671 HConstant rightConstant = instruction;
548 IntConstantValue intConstant = rightConstant.constant; 672 IntConstantValue intConstant = rightConstant.constant;
(...skipping 17 matching lines...) Expand all
566 } 690 }
567 691
568 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { 692 class ShiftLeftSpecializer extends BinaryBitOpSpecializer {
569 const ShiftLeftSpecializer(); 693 const ShiftLeftSpecializer();
570 694
571 BinaryOperation operation(ConstantSystem constantSystem) { 695 BinaryOperation operation(ConstantSystem constantSystem) {
572 return constantSystem.shiftLeft; 696 return constantSystem.shiftLeft;
573 } 697 }
574 698
575 HInstruction tryConvertToBuiltin( 699 HInstruction tryConvertToBuiltin(
576 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 700 HInvokeDynamic instruction,
701 GlobalTypeInferenceResults results,
702 CompilerOptions options,
703 BackendHelpers helpers,
704 ClosedWorld closedWorld) {
577 HInstruction left = instruction.inputs[1]; 705 HInstruction left = instruction.inputs[1];
578 HInstruction right = instruction.inputs[2]; 706 HInstruction right = instruction.inputs[2];
579 if (left.isNumber(closedWorld)) { 707 if (left.isNumber(closedWorld)) {
580 if (argumentLessThan32(right)) { 708 if (argumentLessThan32(right)) {
581 return newBuiltinVariant(instruction, compiler, closedWorld); 709 return newBuiltinVariant(
710 instruction, results, options, helpers, closedWorld);
582 } 711 }
583 // Even if there is no builtin equivalent instruction, we know 712 // Even if there is no builtin equivalent instruction, we know
584 // the instruction does not have any side effect, and that it 713 // the instruction does not have any side effect, and that it
585 // can be GVN'ed. 714 // can be GVN'ed.
586 clearAllSideEffects(instruction); 715 clearAllSideEffects(instruction);
587 if (isPositive(right, closedWorld)) { 716 if (isPositive(right, closedWorld)) {
588 instruction.selector = renameToOptimizedSelector( 717 instruction.selector = renameToOptimizedSelector(
589 '_shlPositive', instruction.selector, compiler); 718 '_shlPositive', instruction.selector, helpers);
590 } 719 }
591 } 720 }
592 return null; 721 return null;
593 } 722 }
594 723
595 HInstruction newBuiltinVariant( 724 HInstruction newBuiltinVariant(
596 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 725 HInvokeDynamic instruction,
726 GlobalTypeInferenceResults results,
727 CompilerOptions options,
728 BackendHelpers helpers,
729 ClosedWorld closedWorld) {
597 return new HShiftLeft( 730 return new HShiftLeft(
598 instruction.inputs[1], 731 instruction.inputs[1],
599 instruction.inputs[2], 732 instruction.inputs[2],
600 instruction.selector, 733 instruction.selector,
601 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 734 computeTypeFromInputTypes(
735 instruction, results, options, helpers, closedWorld));
602 } 736 }
603 } 737 }
604 738
605 class ShiftRightSpecializer extends BinaryBitOpSpecializer { 739 class ShiftRightSpecializer extends BinaryBitOpSpecializer {
606 const ShiftRightSpecializer(); 740 const ShiftRightSpecializer();
607 741
608 TypeMask computeTypeFromInputTypes( 742 TypeMask computeTypeFromInputTypes(
609 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 743 HInvokeDynamic instruction,
744 GlobalTypeInferenceResults results,
745 CompilerOptions options,
746 BackendHelpers helpers,
747 ClosedWorld closedWorld) {
610 HInstruction left = instruction.inputs[1]; 748 HInstruction left = instruction.inputs[1];
611 if (left.isUInt32(closedWorld)) return left.instructionType; 749 if (left.isUInt32(closedWorld)) return left.instructionType;
612 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 750 return super.computeTypeFromInputTypes(
751 instruction, results, options, helpers, closedWorld);
613 } 752 }
614 753
615 HInstruction tryConvertToBuiltin( 754 HInstruction tryConvertToBuiltin(
616 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 755 HInvokeDynamic instruction,
756 GlobalTypeInferenceResults results,
757 CompilerOptions options,
758 BackendHelpers helpers,
759 ClosedWorld closedWorld) {
617 HInstruction left = instruction.inputs[1]; 760 HInstruction left = instruction.inputs[1];
618 HInstruction right = instruction.inputs[2]; 761 HInstruction right = instruction.inputs[2];
619 if (left.isNumber(closedWorld)) { 762 if (left.isNumber(closedWorld)) {
620 if (argumentLessThan32(right) && isPositive(left, closedWorld)) { 763 if (argumentLessThan32(right) && isPositive(left, closedWorld)) {
621 return newBuiltinVariant(instruction, compiler, closedWorld); 764 return newBuiltinVariant(
765 instruction, results, options, helpers, closedWorld);
622 } 766 }
623 // Even if there is no builtin equivalent instruction, we know 767 // Even if there is no builtin equivalent instruction, we know
624 // the instruction does not have any side effect, and that it 768 // the instruction does not have any side effect, and that it
625 // can be GVN'ed. 769 // can be GVN'ed.
626 clearAllSideEffects(instruction); 770 clearAllSideEffects(instruction);
627 if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) { 771 if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) {
628 instruction.selector = renameToOptimizedSelector( 772 instruction.selector = renameToOptimizedSelector(
629 '_shrBothPositive', instruction.selector, compiler); 773 '_shrBothPositive', instruction.selector, helpers);
630 } else if (isPositive(left, closedWorld) && right.isNumber(closedWorld)) { 774 } else if (isPositive(left, closedWorld) && right.isNumber(closedWorld)) {
631 instruction.selector = renameToOptimizedSelector( 775 instruction.selector = renameToOptimizedSelector(
632 '_shrReceiverPositive', instruction.selector, compiler); 776 '_shrReceiverPositive', instruction.selector, helpers);
633 } else if (isPositive(right, closedWorld)) { 777 } else if (isPositive(right, closedWorld)) {
634 instruction.selector = renameToOptimizedSelector( 778 instruction.selector = renameToOptimizedSelector(
635 '_shrOtherPositive', instruction.selector, compiler); 779 '_shrOtherPositive', instruction.selector, helpers);
636 } 780 }
637 } 781 }
638 return null; 782 return null;
639 } 783 }
640 784
641 HInstruction newBuiltinVariant( 785 HInstruction newBuiltinVariant(
642 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 786 HInvokeDynamic instruction,
787 GlobalTypeInferenceResults results,
788 CompilerOptions options,
789 BackendHelpers helpers,
790 ClosedWorld closedWorld) {
643 return new HShiftRight( 791 return new HShiftRight(
644 instruction.inputs[1], 792 instruction.inputs[1],
645 instruction.inputs[2], 793 instruction.inputs[2],
646 instruction.selector, 794 instruction.selector,
647 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 795 computeTypeFromInputTypes(
796 instruction, results, options, helpers, closedWorld));
648 } 797 }
649 798
650 BinaryOperation operation(ConstantSystem constantSystem) { 799 BinaryOperation operation(ConstantSystem constantSystem) {
651 return constantSystem.shiftRight; 800 return constantSystem.shiftRight;
652 } 801 }
653 } 802 }
654 803
655 class BitOrSpecializer extends BinaryBitOpSpecializer { 804 class BitOrSpecializer extends BinaryBitOpSpecializer {
656 const BitOrSpecializer(); 805 const BitOrSpecializer();
657 806
658 BinaryOperation operation(ConstantSystem constantSystem) { 807 BinaryOperation operation(ConstantSystem constantSystem) {
659 return constantSystem.bitOr; 808 return constantSystem.bitOr;
660 } 809 }
661 810
662 TypeMask computeTypeFromInputTypes( 811 TypeMask computeTypeFromInputTypes(
663 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 812 HInvokeDynamic instruction,
813 GlobalTypeInferenceResults results,
814 CompilerOptions options,
815 BackendHelpers helpers,
816 ClosedWorld closedWorld) {
664 HInstruction left = instruction.inputs[1]; 817 HInstruction left = instruction.inputs[1];
665 HInstruction right = instruction.inputs[2]; 818 HInstruction right = instruction.inputs[2];
666 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { 819 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) {
667 return closedWorld.commonMasks.uint31Type; 820 return closedWorld.commonMasks.uint31Type;
668 } 821 }
669 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 822 return super.computeTypeFromInputTypes(
823 instruction, results, options, helpers, closedWorld);
670 } 824 }
671 825
672 HInstruction newBuiltinVariant( 826 HInstruction newBuiltinVariant(
673 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 827 HInvokeDynamic instruction,
828 GlobalTypeInferenceResults results,
829 CompilerOptions options,
830 BackendHelpers helpers,
831 ClosedWorld closedWorld) {
674 return new HBitOr( 832 return new HBitOr(
675 instruction.inputs[1], 833 instruction.inputs[1],
676 instruction.inputs[2], 834 instruction.inputs[2],
677 instruction.selector, 835 instruction.selector,
678 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 836 computeTypeFromInputTypes(
837 instruction, results, options, helpers, closedWorld));
679 } 838 }
680 } 839 }
681 840
682 class BitAndSpecializer extends BinaryBitOpSpecializer { 841 class BitAndSpecializer extends BinaryBitOpSpecializer {
683 const BitAndSpecializer(); 842 const BitAndSpecializer();
684 843
685 BinaryOperation operation(ConstantSystem constantSystem) { 844 BinaryOperation operation(ConstantSystem constantSystem) {
686 return constantSystem.bitAnd; 845 return constantSystem.bitAnd;
687 } 846 }
688 847
689 TypeMask computeTypeFromInputTypes( 848 TypeMask computeTypeFromInputTypes(
690 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 849 HInvokeDynamic instruction,
850 GlobalTypeInferenceResults results,
851 CompilerOptions options,
852 BackendHelpers helpers,
853 ClosedWorld closedWorld) {
691 HInstruction left = instruction.inputs[1]; 854 HInstruction left = instruction.inputs[1];
692 HInstruction right = instruction.inputs[2]; 855 HInstruction right = instruction.inputs[2];
693 if (left.isPrimitiveOrNull(closedWorld) && 856 if (left.isPrimitiveOrNull(closedWorld) &&
694 (left.isUInt31(closedWorld) || right.isUInt31(closedWorld))) { 857 (left.isUInt31(closedWorld) || right.isUInt31(closedWorld))) {
695 return closedWorld.commonMasks.uint31Type; 858 return closedWorld.commonMasks.uint31Type;
696 } 859 }
697 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 860 return super.computeTypeFromInputTypes(
861 instruction, results, options, helpers, closedWorld);
698 } 862 }
699 863
700 HInstruction newBuiltinVariant( 864 HInstruction newBuiltinVariant(
701 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 865 HInvokeDynamic instruction,
866 GlobalTypeInferenceResults results,
867 CompilerOptions options,
868 BackendHelpers helpers,
869 ClosedWorld closedWorld) {
702 return new HBitAnd( 870 return new HBitAnd(
703 instruction.inputs[1], 871 instruction.inputs[1],
704 instruction.inputs[2], 872 instruction.inputs[2],
705 instruction.selector, 873 instruction.selector,
706 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 874 computeTypeFromInputTypes(
875 instruction, results, options, helpers, closedWorld));
707 } 876 }
708 } 877 }
709 878
710 class BitXorSpecializer extends BinaryBitOpSpecializer { 879 class BitXorSpecializer extends BinaryBitOpSpecializer {
711 const BitXorSpecializer(); 880 const BitXorSpecializer();
712 881
713 BinaryOperation operation(ConstantSystem constantSystem) { 882 BinaryOperation operation(ConstantSystem constantSystem) {
714 return constantSystem.bitXor; 883 return constantSystem.bitXor;
715 } 884 }
716 885
717 TypeMask computeTypeFromInputTypes( 886 TypeMask computeTypeFromInputTypes(
718 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 887 HInvokeDynamic instruction,
888 GlobalTypeInferenceResults results,
889 CompilerOptions options,
890 BackendHelpers helpers,
891 ClosedWorld closedWorld) {
719 HInstruction left = instruction.inputs[1]; 892 HInstruction left = instruction.inputs[1];
720 HInstruction right = instruction.inputs[2]; 893 HInstruction right = instruction.inputs[2];
721 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { 894 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) {
722 return closedWorld.commonMasks.uint31Type; 895 return closedWorld.commonMasks.uint31Type;
723 } 896 }
724 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 897 return super.computeTypeFromInputTypes(
898 instruction, results, options, helpers, closedWorld);
725 } 899 }
726 900
727 HInstruction newBuiltinVariant( 901 HInstruction newBuiltinVariant(
728 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 902 HInvokeDynamic instruction,
903 GlobalTypeInferenceResults results,
904 CompilerOptions options,
905 BackendHelpers helpers,
906 ClosedWorld closedWorld) {
729 return new HBitXor( 907 return new HBitXor(
730 instruction.inputs[1], 908 instruction.inputs[1],
731 instruction.inputs[2], 909 instruction.inputs[2],
732 instruction.selector, 910 instruction.selector,
733 computeTypeFromInputTypes(instruction, compiler, closedWorld)); 911 computeTypeFromInputTypes(
912 instruction, results, options, helpers, closedWorld));
734 } 913 }
735 } 914 }
736 915
737 abstract class RelationalSpecializer extends InvokeDynamicSpecializer { 916 abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
738 const RelationalSpecializer(); 917 const RelationalSpecializer();
739 918
740 TypeMask computeTypeFromInputTypes( 919 TypeMask computeTypeFromInputTypes(
741 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 920 HInvokeDynamic instruction,
921 GlobalTypeInferenceResults results,
922 CompilerOptions options,
923 BackendHelpers helpers,
924 ClosedWorld closedWorld) {
742 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { 925 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) {
743 return closedWorld.commonMasks.boolType; 926 return closedWorld.commonMasks.boolType;
744 } 927 }
745 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); 928 return super.computeTypeFromInputTypes(
929 instruction, results, options, helpers, closedWorld);
746 } 930 }
747 931
748 HInstruction tryConvertToBuiltin( 932 HInstruction tryConvertToBuiltin(
749 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 933 HInvokeDynamic instruction,
934 GlobalTypeInferenceResults results,
935 CompilerOptions options,
936 BackendHelpers helpers,
937 ClosedWorld closedWorld) {
750 HInstruction left = instruction.inputs[1]; 938 HInstruction left = instruction.inputs[1];
751 HInstruction right = instruction.inputs[2]; 939 HInstruction right = instruction.inputs[2];
752 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) { 940 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) {
753 return newBuiltinVariant(instruction, closedWorld); 941 return newBuiltinVariant(instruction, closedWorld);
754 } 942 }
755 return null; 943 return null;
756 } 944 }
757 945
758 HInstruction newBuiltinVariant( 946 HInstruction newBuiltinVariant(
759 HInvokeDynamic instruction, ClosedWorld closedWorld); 947 HInvokeDynamic instruction, ClosedWorld closedWorld);
760 } 948 }
761 949
762 class EqualsSpecializer extends RelationalSpecializer { 950 class EqualsSpecializer extends RelationalSpecializer {
763 const EqualsSpecializer(); 951 const EqualsSpecializer();
764 952
765 HInstruction tryConvertToBuiltin( 953 HInstruction tryConvertToBuiltin(
766 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 954 HInvokeDynamic instruction,
955 GlobalTypeInferenceResults results,
956 CompilerOptions options,
957 BackendHelpers helpers,
958 ClosedWorld closedWorld) {
767 HInstruction left = instruction.inputs[1]; 959 HInstruction left = instruction.inputs[1];
768 HInstruction right = instruction.inputs[2]; 960 HInstruction right = instruction.inputs[2];
769 TypeMask instructionType = left.instructionType; 961 TypeMask instructionType = left.instructionType;
770 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) { 962 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) {
771 return newBuiltinVariant(instruction, closedWorld); 963 return newBuiltinVariant(instruction, closedWorld);
772 } 964 }
773 Iterable<MemberEntity> matches = 965 Iterable<MemberEntity> matches =
774 closedWorld.allFunctions.filter(instruction.selector, instructionType); 966 closedWorld.allFunctions.filter(instruction.selector, instructionType);
775 // This test relies the on `Object.==` and `Interceptor.==` always being 967 // This test relies the on `Object.==` and `Interceptor.==` always being
776 // implemented because if the selector matches by subtype, it still will be 968 // implemented because if the selector matches by subtype, it still will be
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 } 1042 }
851 1043
852 class CodeUnitAtSpecializer extends InvokeDynamicSpecializer { 1044 class CodeUnitAtSpecializer extends InvokeDynamicSpecializer {
853 const CodeUnitAtSpecializer(); 1045 const CodeUnitAtSpecializer();
854 1046
855 BinaryOperation operation(ConstantSystem constantSystem) { 1047 BinaryOperation operation(ConstantSystem constantSystem) {
856 return constantSystem.codeUnitAt; 1048 return constantSystem.codeUnitAt;
857 } 1049 }
858 1050
859 HInstruction tryConvertToBuiltin( 1051 HInstruction tryConvertToBuiltin(
860 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 1052 HInvokeDynamic instruction,
1053 GlobalTypeInferenceResults results,
1054 CompilerOptions options,
1055 BackendHelpers helpers,
1056 ClosedWorld closedWorld) {
861 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index 1057 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index
862 // bounds checking optimizations as for HIndex. 1058 // bounds checking optimizations as for HIndex.
863 HInstruction receiver = instruction.getDartReceiver(closedWorld); 1059 HInstruction receiver = instruction.getDartReceiver(closedWorld);
864 if (receiver.isStringOrNull(closedWorld)) { 1060 if (receiver.isStringOrNull(closedWorld)) {
865 // Even if there is no builtin equivalent instruction, we know 1061 // Even if there is no builtin equivalent instruction, we know
866 // String.codeUnitAt does not have any side effect (other than throwing), 1062 // String.codeUnitAt does not have any side effect (other than throwing),
867 // and that it can be GVN'ed. 1063 // and that it can be GVN'ed.
868 clearAllSideEffects(instruction); 1064 clearAllSideEffects(instruction);
869 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { 1065 if (instruction.inputs.last.isPositiveInteger(closedWorld)) {
870 instruction.selector = renameToOptimizedSelector( 1066 instruction.selector = renameToOptimizedSelector(
871 '_codeUnitAt', instruction.selector, compiler); 1067 '_codeUnitAt', instruction.selector, helpers);
872 } 1068 }
873 } 1069 }
874 return null; 1070 return null;
875 } 1071 }
876 } 1072 }
877 1073
878 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { 1074 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer {
879 const IdempotentStringOperationSpecializer(); 1075 const IdempotentStringOperationSpecializer();
880 1076
881 HInstruction tryConvertToBuiltin( 1077 HInstruction tryConvertToBuiltin(
882 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 1078 HInvokeDynamic instruction,
1079 GlobalTypeInferenceResults results,
1080 CompilerOptions options,
1081 BackendHelpers helpers,
1082 ClosedWorld closedWorld) {
883 HInstruction receiver = instruction.getDartReceiver(closedWorld); 1083 HInstruction receiver = instruction.getDartReceiver(closedWorld);
884 if (receiver.isStringOrNull(closedWorld)) { 1084 if (receiver.isStringOrNull(closedWorld)) {
885 // String.xxx does not have any side effect (other than throwing), and it 1085 // String.xxx does not have any side effect (other than throwing), and it
886 // can be GVN'ed. 1086 // can be GVN'ed.
887 clearAllSideEffects(instruction); 1087 clearAllSideEffects(instruction);
888 } 1088 }
889 return null; 1089 return null;
890 } 1090 }
891 } 1091 }
892 1092
893 class SubstringSpecializer extends IdempotentStringOperationSpecializer { 1093 class SubstringSpecializer extends IdempotentStringOperationSpecializer {
894 const SubstringSpecializer(); 1094 const SubstringSpecializer();
895 } 1095 }
896 1096
897 class TrimSpecializer extends IdempotentStringOperationSpecializer { 1097 class TrimSpecializer extends IdempotentStringOperationSpecializer {
898 const TrimSpecializer(); 1098 const TrimSpecializer();
899 } 1099 }
900 1100
901 class PatternMatchSpecializer extends InvokeDynamicSpecializer { 1101 class PatternMatchSpecializer extends InvokeDynamicSpecializer {
902 const PatternMatchSpecializer(); 1102 const PatternMatchSpecializer();
903 1103
904 HInstruction tryConvertToBuiltin( 1104 HInstruction tryConvertToBuiltin(
905 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 1105 HInvokeDynamic instruction,
1106 GlobalTypeInferenceResults results,
1107 CompilerOptions options,
1108 BackendHelpers helpers,
1109 ClosedWorld closedWorld) {
906 HInstruction receiver = instruction.getDartReceiver(closedWorld); 1110 HInstruction receiver = instruction.getDartReceiver(closedWorld);
907 HInstruction pattern = instruction.inputs[2]; 1111 HInstruction pattern = instruction.inputs[2];
908 if (receiver.isStringOrNull(closedWorld) && 1112 if (receiver.isStringOrNull(closedWorld) &&
909 pattern.isStringOrNull(closedWorld)) { 1113 pattern.isStringOrNull(closedWorld)) {
910 // String.contains(String s) does not have any side effect (other than 1114 // String.contains(String s) does not have any side effect (other than
911 // throwing), and it can be GVN'ed. 1115 // throwing), and it can be GVN'ed.
912 clearAllSideEffects(instruction); 1116 clearAllSideEffects(instruction);
913 } 1117 }
914 return null; 1118 return null;
915 } 1119 }
916 } 1120 }
917 1121
918 class RoundSpecializer extends InvokeDynamicSpecializer { 1122 class RoundSpecializer extends InvokeDynamicSpecializer {
919 const RoundSpecializer(); 1123 const RoundSpecializer();
920 1124
921 UnaryOperation operation(ConstantSystem constantSystem) { 1125 UnaryOperation operation(ConstantSystem constantSystem) {
922 return constantSystem.round; 1126 return constantSystem.round;
923 } 1127 }
924 1128
925 HInstruction tryConvertToBuiltin( 1129 HInstruction tryConvertToBuiltin(
926 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { 1130 HInvokeDynamic instruction,
1131 GlobalTypeInferenceResults results,
1132 CompilerOptions options,
1133 BackendHelpers helpers,
1134 ClosedWorld closedWorld) {
927 HInstruction receiver = instruction.getDartReceiver(closedWorld); 1135 HInstruction receiver = instruction.getDartReceiver(closedWorld);
928 if (receiver.isNumberOrNull(closedWorld)) { 1136 if (receiver.isNumberOrNull(closedWorld)) {
929 // Even if there is no builtin equivalent instruction, we know the 1137 // Even if there is no builtin equivalent instruction, we know the
930 // instruction does not have any side effect, and that it can be GVN'ed. 1138 // instruction does not have any side effect, and that it can be GVN'ed.
931 clearAllSideEffects(instruction); 1139 clearAllSideEffects(instruction);
932 } 1140 }
933 return null; 1141 return null;
934 } 1142 }
935 } 1143 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/interceptor_simplifier.dart ('k') | pkg/compiler/lib/src/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698