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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart

Issue 692513002: Remove old dart2js code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of ssa;
6
7 /**
8 * [InvokeDynamicSpecializer] and its subclasses are helpers to
9 * optimize intercepted dynamic calls. It knows what input types
10 * would be beneficial for performance, and how to change a invoke
11 * dynamic to a builtin instruction (e.g. HIndex, HBitNot).
12 */
13 class InvokeDynamicSpecializer {
14 const InvokeDynamicSpecializer();
15
16 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
17 Compiler compiler) {
18 Selector selector = instruction.selector;
19 return TypeMaskFactory.inferredTypeForSelector(selector, compiler);
20 }
21
22 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
23 Compiler compiler) {
24 return null;
25 }
26
27 Operation operation(ConstantSystem constantSystem) => null;
28
29 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) {
30 if (selector.kind == SelectorKind.INDEX) {
31 return selector.name == '[]'
32 ? const IndexSpecializer()
33 : const IndexAssignSpecializer();
34 } else if (selector.kind == SelectorKind.OPERATOR) {
35 if (selector.name == 'unary-') {
36 return const UnaryNegateSpecializer();
37 } else if (selector.name == '~') {
38 return const BitNotSpecializer();
39 } else if (selector.name == '+') {
40 return const AddSpecializer();
41 } else if (selector.name == '-') {
42 return const SubtractSpecializer();
43 } else if (selector.name == '*') {
44 return const MultiplySpecializer();
45 } else if (selector.name == '/') {
46 return const DivideSpecializer();
47 } else if (selector.name == '~/') {
48 return const TruncatingDivideSpecializer();
49 } else if (selector.name == '%') {
50 return const ModuloSpecializer();
51 } else if (selector.name == '>>') {
52 return const ShiftRightSpecializer();
53 } else if (selector.name == '<<') {
54 return const ShiftLeftSpecializer();
55 } else if (selector.name == '&') {
56 return const BitAndSpecializer();
57 } else if (selector.name == '|') {
58 return const BitOrSpecializer();
59 } else if (selector.name == '^') {
60 return const BitXorSpecializer();
61 } else if (selector.name == '==') {
62 return const EqualsSpecializer();
63 } else if (selector.name == '<') {
64 return const LessSpecializer();
65 } else if (selector.name == '<=') {
66 return const LessEqualSpecializer();
67 } else if (selector.name == '>') {
68 return const GreaterSpecializer();
69 } else if (selector.name == '>=') {
70 return const GreaterEqualSpecializer();
71 }
72 }
73 return const InvokeDynamicSpecializer();
74 }
75 }
76
77 class IndexAssignSpecializer extends InvokeDynamicSpecializer {
78 const IndexAssignSpecializer();
79
80 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
81 Compiler compiler) {
82 if (instruction.inputs[1].isMutableIndexable(compiler)) {
83 if (!instruction.inputs[2].isInteger(compiler)
84 && compiler.enableTypeAssertions) {
85 // We want the right checked mode error.
86 return null;
87 }
88 return new HIndexAssign(instruction.inputs[1],
89 instruction.inputs[2],
90 instruction.inputs[3],
91 instruction.selector);
92 }
93 return null;
94 }
95 }
96
97 class IndexSpecializer extends InvokeDynamicSpecializer {
98 const IndexSpecializer();
99
100 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
101 Compiler compiler) {
102 if (!instruction.inputs[1].isIndexablePrimitive(compiler)) return null;
103 if (!instruction.inputs[2].isInteger(compiler)
104 && compiler.enableTypeAssertions) {
105 // We want the right checked mode error.
106 return null;
107 }
108 TypeMask receiverType =
109 instruction.getDartReceiver(compiler).instructionType;
110 Selector refined = new TypedSelector(receiverType, instruction.selector,
111 compiler.world);
112 TypeMask type = TypeMaskFactory.inferredTypeForSelector(refined, compiler);
113 return new HIndex(
114 instruction.inputs[1], instruction.inputs[2],
115 instruction.selector, type);
116 }
117 }
118
119 class BitNotSpecializer extends InvokeDynamicSpecializer {
120 const BitNotSpecializer();
121
122 UnaryOperation operation(ConstantSystem constantSystem) {
123 return constantSystem.bitNot;
124 }
125
126 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
127 Compiler compiler) {
128 // All bitwise operations on primitive types either produce an
129 // integer or throw an error.
130 JavaScriptBackend backend = compiler.backend;
131 if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
132 return backend.uint32Type;
133 }
134 return super.computeTypeFromInputTypes(instruction, compiler);
135 }
136
137 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
138 Compiler compiler) {
139 JavaScriptBackend backend = compiler.backend;
140 HInstruction input = instruction.inputs[1];
141 if (input.isNumber(compiler)) {
142 return new HBitNot(input, instruction.selector,
143 computeTypeFromInputTypes(instruction, compiler));
144 }
145 return null;
146 }
147 }
148
149 class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
150 const UnaryNegateSpecializer();
151
152 UnaryOperation operation(ConstantSystem constantSystem) {
153 return constantSystem.negate;
154 }
155
156 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
157 Compiler compiler) {
158 TypeMask operandType = instruction.inputs[1].instructionType;
159 if (instruction.inputs[1].isNumberOrNull(compiler)) return operandType;
160 return super.computeTypeFromInputTypes(instruction, compiler);
161 }
162
163 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
164 Compiler compiler) {
165 HInstruction input = instruction.inputs[1];
166 if (input.isNumber(compiler)) {
167 return new HNegate(input, instruction.selector, input.instructionType);
168 }
169 return null;
170 }
171 }
172
173 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
174 const BinaryArithmeticSpecializer();
175
176 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
177 Compiler compiler) {
178 HInstruction left = instruction.inputs[1];
179 HInstruction right = instruction.inputs[2];
180 JavaScriptBackend backend = compiler.backend;
181 if (left.isIntegerOrNull(compiler) && right.isIntegerOrNull(compiler)) {
182 return backend.intType;
183 }
184 if (left.isNumberOrNull(compiler)) {
185 if (left.isDoubleOrNull(compiler) || right.isDoubleOrNull(compiler)) {
186 return backend.doubleType;
187 }
188 return backend.numType;
189 }
190 return super.computeTypeFromInputTypes(instruction, compiler);
191 }
192
193 bool isBuiltin(HInvokeDynamic instruction, Compiler compiler) {
194 return instruction.inputs[1].isNumber(compiler)
195 && instruction.inputs[2].isNumber(compiler);
196 }
197
198 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
199 Compiler compiler) {
200 if (isBuiltin(instruction, compiler)) {
201 HInstruction builtin = newBuiltinVariant(instruction, compiler);
202 if (builtin != null) return builtin;
203 // Even if there is no builtin equivalent instruction, we know
204 // the instruction does not have any side effect, and that it
205 // can be GVN'ed.
206 clearAllSideEffects(instruction);
207 }
208 return null;
209 }
210
211 void clearAllSideEffects(HInstruction instruction) {
212 instruction.sideEffects.clearAllSideEffects();
213 instruction.sideEffects.clearAllDependencies();
214 instruction.setUseGvn();
215 }
216
217 bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) {
218 HInstruction left = instruction.inputs[1];
219 HInstruction right = instruction.inputs[2];
220 JavaScriptBackend backend = compiler.backend;
221 return left.isPositiveIntegerOrNull(compiler)
222 && right.isPositiveIntegerOrNull(compiler);
223 }
224
225 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);
226
227 Selector renameToOptimizedSelector(String name,
228 Selector selector,
229 Compiler compiler) {
230 if (selector.name == name) return selector;
231 JavaScriptBackend backend = compiler.backend;
232 Selector newSelector = new Selector(
233 SelectorKind.CALL, name, backend.interceptorsLibrary,
234 selector.argumentCount);
235 return selector.mask == null
236 ? newSelector
237 : new TypedSelector(selector.mask, newSelector, compiler.world);
238 }
239 }
240
241 class AddSpecializer extends BinaryArithmeticSpecializer {
242 const AddSpecializer();
243
244 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
245 Compiler compiler) {
246 if (inputsArePositiveIntegers(instruction, compiler)) {
247 JavaScriptBackend backend = compiler.backend;
248 return backend.positiveIntType;
249 }
250 return super.computeTypeFromInputTypes(instruction, compiler);
251 }
252
253 BinaryOperation operation(ConstantSystem constantSystem) {
254 return constantSystem.add;
255 }
256
257 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
258 Compiler compiler) {
259 return new HAdd(
260 instruction.inputs[1], instruction.inputs[2],
261 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
262 }
263 }
264
265 class DivideSpecializer extends BinaryArithmeticSpecializer {
266 const DivideSpecializer();
267
268 BinaryOperation operation(ConstantSystem constantSystem) {
269 return constantSystem.divide;
270 }
271
272 TypeMask computeTypeFromInputTypes(HInstruction instruction,
273 Compiler compiler) {
274 HInstruction left = instruction.inputs[1];
275 JavaScriptBackend backend = compiler.backend;
276 if (left.isNumberOrNull(compiler)) {
277 return backend.doubleType;
278 }
279 return super.computeTypeFromInputTypes(instruction, compiler);
280 }
281
282 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
283 Compiler compiler) {
284 JavaScriptBackend backend = compiler.backend;
285 return new HDivide(
286 instruction.inputs[1], instruction.inputs[2],
287 instruction.selector, backend.doubleType);
288 }
289 }
290
291 class ModuloSpecializer extends BinaryArithmeticSpecializer {
292 const ModuloSpecializer();
293
294 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
295 Compiler compiler) {
296 if (inputsArePositiveIntegers(instruction, compiler)) {
297 JavaScriptBackend backend = compiler.backend;
298 return backend.positiveIntType;
299 }
300 return super.computeTypeFromInputTypes(instruction, compiler);
301 }
302
303 BinaryOperation operation(ConstantSystem constantSystem) {
304 return constantSystem.modulo;
305 }
306
307 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
308 Compiler compiler) {
309 // Modulo cannot be mapped to the native operator (different semantics).
310 return null;
311 }
312 }
313
314 class MultiplySpecializer extends BinaryArithmeticSpecializer {
315 const MultiplySpecializer();
316
317 BinaryOperation operation(ConstantSystem constantSystem) {
318 return constantSystem.multiply;
319 }
320
321 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
322 Compiler compiler) {
323 if (inputsArePositiveIntegers(instruction, compiler)) {
324 JavaScriptBackend backend = compiler.backend;
325 return backend.positiveIntType;
326 }
327 return super.computeTypeFromInputTypes(instruction, compiler);
328 }
329
330 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
331 Compiler compiler) {
332 return new HMultiply(
333 instruction.inputs[1], instruction.inputs[2],
334 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
335 }
336 }
337
338 class SubtractSpecializer extends BinaryArithmeticSpecializer {
339 const SubtractSpecializer();
340
341 BinaryOperation operation(ConstantSystem constantSystem) {
342 return constantSystem.subtract;
343 }
344
345 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
346 Compiler compiler) {
347 return new HSubtract(
348 instruction.inputs[1], instruction.inputs[2],
349 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
350 }
351 }
352
353 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
354 const TruncatingDivideSpecializer();
355
356 BinaryOperation operation(ConstantSystem constantSystem) {
357 return constantSystem.truncatingDivide;
358 }
359
360 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
361 Compiler compiler) {
362 if (inputsArePositiveIntegers(instruction, compiler)) {
363 JavaScriptBackend backend = compiler.backend;
364 return backend.positiveIntType;
365 }
366 return super.computeTypeFromInputTypes(instruction, compiler);
367 }
368
369 bool isNotZero(HInstruction instruction, Compiler compiler) {
370 if (!instruction.isConstantInteger()) return false;
371 HConstant rightConstant = instruction;
372 IntConstantValue intConstant = rightConstant.constant;
373 int count = intConstant.primitiveValue;
374 return count != 0;
375 }
376
377 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
378 Compiler compiler) {
379 HInstruction left = instruction.inputs[1];
380 HInstruction right = instruction.inputs[2];
381 if (isBuiltin(instruction, compiler)) {
382 if (right.isPositiveInteger(compiler) && isNotZero(right, compiler)) {
383 if (left.isUInt31(compiler)) {
384 return newBuiltinVariant(instruction, compiler);
385 }
386 // We can call _tdivFast because the rhs is a 32bit integer
387 // and not 0, nor -1.
388 instruction.selector = renameToOptimizedSelector(
389 '_tdivFast', instruction.selector, compiler);
390 }
391 clearAllSideEffects(instruction);
392 }
393 return null;
394 }
395
396 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
397 Compiler compiler) {
398 return new HTruncatingDivide(
399 instruction.inputs[1], instruction.inputs[2],
400 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
401 }
402 }
403
404 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
405 const BinaryBitOpSpecializer();
406
407 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
408 Compiler compiler) {
409 // All bitwise operations on primitive types either produce an
410 // integer or throw an error.
411 HInstruction left = instruction.inputs[1];
412 JavaScriptBackend backend = compiler.backend;
413 if (left.isPrimitiveOrNull(compiler)) {
414 return backend.uint32Type;
415 }
416 return super.computeTypeFromInputTypes(instruction, compiler);
417 }
418
419 bool argumentLessThan32(HInstruction instruction) {
420 if (!instruction.isConstantInteger()) return false;
421 HConstant rightConstant = instruction;
422 IntConstantValue intConstant = rightConstant.constant;
423 int count = intConstant.primitiveValue;
424 return count >= 0 && count <= 31;
425 }
426
427 bool isPositive(HInstruction instruction, Compiler compiler) {
428 // TODO: We should use the value range analysis. Currently, ranges
429 // are discarded just after the analysis.
430 return instruction.isPositiveInteger(compiler);
431 }
432 }
433
434 class ShiftLeftSpecializer extends BinaryBitOpSpecializer {
435 const ShiftLeftSpecializer();
436
437 BinaryOperation operation(ConstantSystem constantSystem) {
438 return constantSystem.shiftLeft;
439 }
440
441 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
442 Compiler compiler) {
443 HInstruction left = instruction.inputs[1];
444 HInstruction right = instruction.inputs[2];
445 if (left.isNumber(compiler)) {
446 if (argumentLessThan32(right)) {
447 return newBuiltinVariant(instruction, compiler);
448 }
449 // Even if there is no builtin equivalent instruction, we know
450 // the instruction does not have any side effect, and that it
451 // can be GVN'ed.
452 clearAllSideEffects(instruction);
453 Selector selector = instruction.selector;
454 if (isPositive(right, compiler)) {
455 instruction.selector = renameToOptimizedSelector(
456 '_shlPositive', instruction.selector, compiler);
457 }
458 }
459 return null;
460 }
461
462 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
463 Compiler compiler) {
464 JavaScriptBackend backend = compiler.backend;
465 return new HShiftLeft(
466 instruction.inputs[1], instruction.inputs[2],
467 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
468 }
469 }
470
471 class ShiftRightSpecializer extends BinaryBitOpSpecializer {
472 const ShiftRightSpecializer();
473
474 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
475 Compiler compiler) {
476 HInstruction left = instruction.inputs[1];
477 HInstruction right = instruction.inputs[2];
478 JavaScriptBackend backend = compiler.backend;
479 if (left.isUInt32(compiler)) return left.instructionType;
480 return super.computeTypeFromInputTypes(instruction, compiler);
481 }
482
483 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
484 Compiler compiler) {
485 HInstruction left = instruction.inputs[1];
486 HInstruction right = instruction.inputs[2];
487 if (left.isNumber(compiler)) {
488 if (argumentLessThan32(right) && isPositive(left, compiler)) {
489 return newBuiltinVariant(instruction, compiler);
490 }
491 // Even if there is no builtin equivalent instruction, we know
492 // the instruction does not have any side effect, and that it
493 // can be GVN'ed.
494 clearAllSideEffects(instruction);
495 if (isPositive(right, compiler) && isPositive(left, compiler)) {
496 instruction.selector = renameToOptimizedSelector(
497 '_shrBothPositive', instruction.selector, compiler);
498 } else if (isPositive(left, compiler) && right.isNumber(compiler)) {
499 instruction.selector = renameToOptimizedSelector(
500 '_shrReceiverPositive', instruction.selector, compiler);
501 } else if (isPositive(right, compiler)) {
502 instruction.selector = renameToOptimizedSelector(
503 '_shrOtherPositive', instruction.selector, compiler);
504 }
505 }
506 return null;
507 }
508
509 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
510 Compiler compiler) {
511 JavaScriptBackend backend = compiler.backend;
512 return new HShiftRight(
513 instruction.inputs[1], instruction.inputs[2],
514 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
515 }
516
517 BinaryOperation operation(ConstantSystem constantSystem) {
518 return constantSystem.shiftRight;
519 }
520 }
521
522 class BitOrSpecializer extends BinaryBitOpSpecializer {
523 const BitOrSpecializer();
524
525 BinaryOperation operation(ConstantSystem constantSystem) {
526 return constantSystem.bitOr;
527 }
528
529 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
530 Compiler compiler) {
531 HInstruction left = instruction.inputs[1];
532 HInstruction right = instruction.inputs[2];
533 JavaScriptBackend backend = compiler.backend;
534 if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
535 return backend.uint31Type;
536 }
537 return super.computeTypeFromInputTypes(instruction, compiler);
538 }
539
540 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
541 Compiler compiler) {
542 JavaScriptBackend backend = compiler.backend;
543 return new HBitOr(
544 instruction.inputs[1], instruction.inputs[2],
545 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
546 }
547 }
548
549 class BitAndSpecializer extends BinaryBitOpSpecializer {
550 const BitAndSpecializer();
551
552 BinaryOperation operation(ConstantSystem constantSystem) {
553 return constantSystem.bitAnd;
554 }
555
556 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
557 Compiler compiler) {
558 HInstruction left = instruction.inputs[1];
559 HInstruction right = instruction.inputs[2];
560 JavaScriptBackend backend = compiler.backend;
561 if (left.isUInt31(compiler) || right.isUInt31(compiler)) {
562 return backend.uint31Type;
563 }
564 return super.computeTypeFromInputTypes(instruction, compiler);
565 }
566
567 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
568 Compiler compiler) {
569 JavaScriptBackend backend = compiler.backend;
570 return new HBitAnd(
571 instruction.inputs[1], instruction.inputs[2],
572 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
573 }
574 }
575
576 class BitXorSpecializer extends BinaryBitOpSpecializer {
577 const BitXorSpecializer();
578
579 BinaryOperation operation(ConstantSystem constantSystem) {
580 return constantSystem.bitXor;
581 }
582
583 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
584 Compiler compiler) {
585 HInstruction left = instruction.inputs[1];
586 HInstruction right = instruction.inputs[2];
587 JavaScriptBackend backend = compiler.backend;
588 if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
589 return backend.uint31Type;
590 }
591 return super.computeTypeFromInputTypes(instruction, compiler);
592 }
593
594 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
595 Compiler compiler) {
596 JavaScriptBackend backend = compiler.backend;
597 return new HBitXor(
598 instruction.inputs[1], instruction.inputs[2],
599 instruction.selector, computeTypeFromInputTypes(instruction, compiler));
600 }
601 }
602
603 abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
604 const RelationalSpecializer();
605
606 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
607 Compiler compiler) {
608 JavaScriptBackend backend = compiler.backend;
609 if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
610 return backend.boolType;
611 }
612 return super.computeTypeFromInputTypes(instruction, compiler);
613 }
614
615 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
616 Compiler compiler) {
617 HInstruction left = instruction.inputs[1];
618 HInstruction right = instruction.inputs[2];
619 if (left.isNumber(compiler) && right.isNumber(compiler)) {
620 return newBuiltinVariant(instruction, compiler);
621 }
622 return null;
623 }
624
625 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);
626 }
627
628 class EqualsSpecializer extends RelationalSpecializer {
629 const EqualsSpecializer();
630
631 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
632 Compiler compiler) {
633 HInstruction left = instruction.inputs[1];
634 HInstruction right = instruction.inputs[2];
635 TypeMask instructionType = left.instructionType;
636 if (right.isConstantNull() || left.isPrimitiveOrNull(compiler)) {
637 return newBuiltinVariant(instruction, compiler);
638 }
639 World world = compiler.world;
640 Selector selector =
641 new TypedSelector(instructionType, instruction.selector, world);
642 JavaScriptBackend backend = compiler.backend;
643 Iterable<Element> matches = world.allFunctions.filter(selector);
644 // This test relies the on `Object.==` and `Interceptor.==` always being
645 // implemented because if the selector matches by subtype, it still will be
646 // a regular object or an interceptor.
647 if (matches.every(backend.isDefaultEqualityImplementation)) {
648 return newBuiltinVariant(instruction, compiler);
649 }
650 return null;
651 }
652
653 BinaryOperation operation(ConstantSystem constantSystem) {
654 return constantSystem.equal;
655 }
656
657 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
658 Compiler compiler) {
659 JavaScriptBackend backend = compiler.backend;
660 return new HIdentity(
661 instruction.inputs[1], instruction.inputs[2],
662 instruction.selector, backend.boolType);
663 }
664 }
665
666 class LessSpecializer extends RelationalSpecializer {
667 const LessSpecializer();
668
669 BinaryOperation operation(ConstantSystem constantSystem) {
670 return constantSystem.less;
671 }
672
673 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
674 Compiler compiler) {
675 JavaScriptBackend backend = compiler.backend;
676 return new HLess(
677 instruction.inputs[1], instruction.inputs[2],
678 instruction.selector, backend.boolType);
679 }
680 }
681
682 class GreaterSpecializer extends RelationalSpecializer {
683 const GreaterSpecializer();
684
685 BinaryOperation operation(ConstantSystem constantSystem) {
686 return constantSystem.greater;
687 }
688
689 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
690 Compiler compiler) {
691 JavaScriptBackend backend = compiler.backend;
692 return new HGreater(
693 instruction.inputs[1], instruction.inputs[2],
694 instruction.selector, backend.boolType);
695 }
696 }
697
698 class GreaterEqualSpecializer extends RelationalSpecializer {
699 const GreaterEqualSpecializer();
700
701 BinaryOperation operation(ConstantSystem constantSystem) {
702 return constantSystem.greaterEqual;
703 }
704
705 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
706 Compiler compiler) {
707 JavaScriptBackend backend = compiler.backend;
708 return new HGreaterEqual(
709 instruction.inputs[1], instruction.inputs[2],
710 instruction.selector, backend.boolType);
711 }
712 }
713
714 class LessEqualSpecializer extends RelationalSpecializer {
715 const LessEqualSpecializer();
716
717 BinaryOperation operation(ConstantSystem constantSystem) {
718 return constantSystem.lessEqual;
719 }
720
721 HInstruction newBuiltinVariant(HInvokeDynamic instruction,
722 Compiler compiler) {
723 JavaScriptBackend backend = compiler.backend;
724 return new HLessEqual(
725 instruction.inputs[1], instruction.inputs[2],
726 instruction.selector, backend.boolType);
727 }
728 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698