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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1220193003: dart2js cps: Fuse tear-off and call invocation. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase Created 5 years, 5 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/cps_ir/type_propagation.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 library dart2js.ir_nodes; 4 library dart2js.ir_nodes;
5 5
6 import '../constants/values.dart' as values show ConstantValue; 6 import '../constants/values.dart' as values show ConstantValue;
7 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; 7 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../io/source_information.dart' show SourceInformation; 9 import '../io/source_information.dart' show SourceInformation;
10 import '../types/types.dart' show TypeMask; 10 import '../types/types.dart' show TypeMask;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 if (this.hint == null) { 88 if (this.hint == null) {
89 this.hint = hint; 89 this.hint = hint;
90 } 90 }
91 } 91 }
92 92
93 /// True if the primitive can be removed, assuming it has no uses 93 /// True if the primitive can be removed, assuming it has no uses
94 /// (this getter does not check if there are any uses). 94 /// (this getter does not check if there are any uses).
95 /// 95 ///
96 /// False must be returned for primitives that may throw, diverge, or have 96 /// False must be returned for primitives that may throw, diverge, or have
97 /// observable side-effects. 97 /// observable side-effects.
98 bool get isSafeForElimination => true; 98 bool get isSafeForElimination;
99
100 /// True if time-of-evaluation is irrelevant for the given primitive,
101 /// assuming its inputs are the same values.
102 bool get isSafeForReordering;
99 } 103 }
100 104
101 /// Operands to invocations and primitives are always variables. They point to 105 /// Operands to invocations and primitives are always variables. They point to
102 /// their definition and are doubly-linked into a list of occurrences. 106 /// their definition and are doubly-linked into a list of occurrences.
103 class Reference<T extends Definition<T>> { 107 class Reference<T extends Definition<T>> {
104 T definition; 108 T definition;
105 Reference<T> previous; 109 Reference<T> previous;
106 Reference<T> next; 110 Reference<T> next;
107 111
108 /// A pointer to the parent node. Is null until set by optimization passes. 112 /// A pointer to the parent node. Is null until set by optimization passes.
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 final SourceInformation sourceInformation; 263 final SourceInformation sourceInformation;
260 264
261 InvokeStatic(this.target, 265 InvokeStatic(this.target,
262 this.selector, 266 this.selector,
263 List<Primitive> args, 267 List<Primitive> args,
264 Continuation cont, 268 Continuation cont,
265 [this.sourceInformation]) 269 [this.sourceInformation])
266 : arguments = _referenceList(args), 270 : arguments = _referenceList(args),
267 continuation = new Reference<Continuation>(cont); 271 continuation = new Reference<Continuation>(cont);
268 272
273 InvokeStatic.byReference(this.target,
274 this.selector,
275 this.arguments,
276 this.continuation,
277 [this.sourceInformation]);
278
269 accept(Visitor visitor) => visitor.visitInvokeStatic(this); 279 accept(Visitor visitor) => visitor.visitInvokeStatic(this);
270 } 280 }
271 281
272 /// Invoke a method on an object. 282 /// Invoke a method on an object.
273 /// 283 ///
274 /// This includes getters, setters, operators, and index getter/setters. 284 /// This includes getters, setters, operators, and index getter/setters.
275 /// 285 ///
276 /// Tearing off a method is treated like a getter invocation (getters and 286 /// Tearing off a method is treated like a getter invocation (getters and
277 /// tear-offs cannot be distinguished at compile-time). 287 /// tear-offs cannot be distinguished at compile-time).
278 /// 288 ///
(...skipping 13 matching lines...) Expand all
292 InvokeMethod(Primitive receiver, 302 InvokeMethod(Primitive receiver,
293 this.selector, 303 this.selector,
294 this.mask, 304 this.mask,
295 List<Primitive> arguments, 305 List<Primitive> arguments,
296 Continuation continuation, 306 Continuation continuation,
297 [this.sourceInformation]) 307 [this.sourceInformation])
298 : this.receiver = new Reference<Primitive>(receiver), 308 : this.receiver = new Reference<Primitive>(receiver),
299 this.arguments = _referenceList(arguments), 309 this.arguments = _referenceList(arguments),
300 this.continuation = new Reference<Continuation>(continuation); 310 this.continuation = new Reference<Continuation>(continuation);
301 311
312 InvokeMethod.byReference(this.receiver,
313 this.selector,
314 this.mask,
315 this.arguments,
316 this.continuation,
317 [this.sourceInformation]);
318
302 accept(Visitor visitor) => visitor.visitInvokeMethod(this); 319 accept(Visitor visitor) => visitor.visitInvokeMethod(this);
303 } 320 }
304 321
305 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. 322 /// Invoke [target] on [receiver], bypassing dispatch and override semantics.
306 /// 323 ///
307 /// That is, if [receiver] is an instance of a class that overrides [target] 324 /// That is, if [receiver] is an instance of a class that overrides [target]
308 /// with a different implementation, the overriding implementation is bypassed 325 /// with a different implementation, the overriding implementation is bypassed
309 /// and [target]'s implementation is invoked. 326 /// and [target]'s implementation is invoked.
310 /// 327 ///
311 /// As with [InvokeMethod], this can be used to invoke a method, operator, 328 /// As with [InvokeMethod], this can be used to invoke a method, operator,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 /// Otherwise the list is empty. 414 /// Otherwise the list is empty.
398 final List<Reference<Primitive>> typeArguments; 415 final List<Reference<Primitive>> typeArguments;
399 416
400 TypeTest(Primitive value, 417 TypeTest(Primitive value,
401 this.type, 418 this.type,
402 List<Primitive> typeArguments) 419 List<Primitive> typeArguments)
403 : this.value = new Reference<Primitive>(value), 420 : this.value = new Reference<Primitive>(value),
404 this.typeArguments = _referenceList(typeArguments); 421 this.typeArguments = _referenceList(typeArguments);
405 422
406 accept(Visitor visitor) => visitor.visitTypeTest(this); 423 accept(Visitor visitor) => visitor.visitTypeTest(this);
424
425 bool get isSafeForElimination => true;
426 bool get isSafeForReordering => true;
407 } 427 }
408 428
409 /// An "as" type cast. 429 /// An "as" type cast.
410 /// 430 ///
411 /// If [value] is `null` or is an instance of [type], [continuation] is invoked 431 /// If [value] is `null` or is an instance of [type], [continuation] is invoked
412 /// with [value] as argument. Otherwise, a [CastError] is thrown. 432 /// with [value] as argument. Otherwise, a [CastError] is thrown.
413 /// 433 ///
414 /// Discussion: 434 /// Discussion:
415 /// The parameter to [continuation] is redundant since it will always equal 435 /// The parameter to [continuation] is redundant since it will always equal
416 /// [value], which is typically in scope in the continuation. However, it might 436 /// [value], which is typically in scope in the continuation. However, it might
(...skipping 22 matching lines...) Expand all
439 /// 459 ///
440 /// It must be known that the arguments have the proper types. 460 /// It must be known that the arguments have the proper types.
441 class ApplyBuiltinOperator extends Primitive { 461 class ApplyBuiltinOperator extends Primitive {
442 BuiltinOperator operator; 462 BuiltinOperator operator;
443 List<Reference<Primitive>> arguments; 463 List<Reference<Primitive>> arguments;
444 464
445 ApplyBuiltinOperator(this.operator, List<Primitive> arguments) 465 ApplyBuiltinOperator(this.operator, List<Primitive> arguments)
446 : this.arguments = _referenceList(arguments); 466 : this.arguments = _referenceList(arguments);
447 467
448 accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this); 468 accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this);
469
470 bool get isSafeForElimination => true;
471 bool get isSafeForReordering => true;
449 } 472 }
450 473
451 /// Throw a value. 474 /// Throw a value.
452 /// 475 ///
453 /// Throw is an expression, i.e., it always occurs in tail position with 476 /// Throw is an expression, i.e., it always occurs in tail position with
454 /// respect to a body or expression. 477 /// respect to a body or expression.
455 class Throw extends Expression { 478 class Throw extends Expression {
456 Reference<Primitive> value; 479 Reference<Primitive> value;
457 480
458 Throw(Primitive value) : value = new Reference<Primitive>(value); 481 Throw(Primitive value) : value = new Reference<Primitive>(value);
(...skipping 15 matching lines...) Expand all
474 /// The CPS translation of an expression produces a primitive as the value 497 /// The CPS translation of an expression produces a primitive as the value
475 /// of the expression. For convenience in the implementation of the 498 /// of the expression. For convenience in the implementation of the
476 /// translation, a [NonTailThrow] is used as that value. A cleanup pass 499 /// translation, a [NonTailThrow] is used as that value. A cleanup pass
477 /// removes these and replaces them with [Throw] expressions. 500 /// removes these and replaces them with [Throw] expressions.
478 class NonTailThrow extends Primitive { 501 class NonTailThrow extends Primitive {
479 final Reference<Primitive> value; 502 final Reference<Primitive> value;
480 503
481 NonTailThrow(Primitive value) : value = new Reference<Primitive>(value); 504 NonTailThrow(Primitive value) : value = new Reference<Primitive>(value);
482 505
483 accept(Visitor visitor) => visitor.visitNonTailThrow(this); 506 accept(Visitor visitor) => visitor.visitNonTailThrow(this);
507
508 bool get isSafeForElimination => false;
509 bool get isSafeForReordering => false;
484 } 510 }
485 511
486 /// An expression that is known to be unreachable. 512 /// An expression that is known to be unreachable.
487 /// 513 ///
488 /// This can be placed as the body of a call continuation, when the caller is 514 /// This can be placed as the body of a call continuation, when the caller is
489 /// known never to invoke it, e.g. because the calling expression always throws. 515 /// known never to invoke it, e.g. because the calling expression always throws.
490 class Unreachable extends Expression { 516 class Unreachable extends Expression {
491 accept(Visitor visitor) => visitor.visitUnreachable(this); 517 accept(Visitor visitor) => visitor.visitUnreachable(this);
492 } 518 }
493 519
494 /// Gets the value from a [MutableVariable]. 520 /// Gets the value from a [MutableVariable].
495 /// 521 ///
496 /// [MutableVariable]s can be seen as ref cells that are not first-class 522 /// [MutableVariable]s can be seen as ref cells that are not first-class
497 /// values. A [LetPrim] with a [GetMutableVariable] can then be seen as: 523 /// values. A [LetPrim] with a [GetMutableVariable] can then be seen as:
498 /// 524 ///
499 /// let prim p = ![variable] in [body] 525 /// let prim p = ![variable] in [body]
500 /// 526 ///
501 class GetMutableVariable extends Primitive { 527 class GetMutableVariable extends Primitive {
502 final Reference<MutableVariable> variable; 528 final Reference<MutableVariable> variable;
503 529
504 GetMutableVariable(MutableVariable variable) 530 GetMutableVariable(MutableVariable variable)
505 : this.variable = new Reference<MutableVariable>(variable); 531 : this.variable = new Reference<MutableVariable>(variable);
506 532
507 accept(Visitor visitor) => visitor.visitGetMutableVariable(this); 533 accept(Visitor visitor) => visitor.visitGetMutableVariable(this);
534
535 bool get isSafeForElimination => true;
536 bool get isSafeForReordering => false;
508 } 537 }
509 538
510 /// Assign a [MutableVariable]. 539 /// Assign a [MutableVariable].
511 /// 540 ///
512 /// [MutableVariable]s can be seen as ref cells that are not first-class 541 /// [MutableVariable]s can be seen as ref cells that are not first-class
513 /// values. This can be seen as a dereferencing assignment: 542 /// values. This can be seen as a dereferencing assignment:
514 /// 543 ///
515 /// { [variable] := [value]; [body] } 544 /// { [variable] := [value]; [body] }
516 class SetMutableVariable extends Expression implements InteriorNode { 545 class SetMutableVariable extends Expression implements InteriorNode {
517 final Reference<MutableVariable> variable; 546 final Reference<MutableVariable> variable;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 /// True if the object is known not to be null. 644 /// True if the object is known not to be null.
616 // TODO(asgerf): This is a placeholder until we agree on how to track 645 // TODO(asgerf): This is a placeholder until we agree on how to track
617 // side effects. 646 // side effects.
618 bool objectIsNotNull = false; 647 bool objectIsNotNull = false;
619 648
620 GetField(Primitive object, this.field) 649 GetField(Primitive object, this.field)
621 : this.object = new Reference<Primitive>(object); 650 : this.object = new Reference<Primitive>(object);
622 651
623 accept(Visitor visitor) => visitor.visitGetField(this); 652 accept(Visitor visitor) => visitor.visitGetField(this);
624 653
625 @override
626 bool get isSafeForElimination => objectIsNotNull; 654 bool get isSafeForElimination => objectIsNotNull;
655 bool get isSafeForReordering => objectIsNotNull && field.isFinal;
627 } 656 }
628 657
629 /// Reads the value of a static field or tears off a static method. 658 /// Reads the value of a static field or tears off a static method.
659 ///
660 /// Note that lazily initialized fields should be read using GetLazyStatic.
630 class GetStatic extends Primitive { 661 class GetStatic extends Primitive {
631 /// Can be [FieldElement] or [FunctionElement]. 662 /// Can be [FieldElement] or [FunctionElement].
632 final Element element; 663 final Element element;
633 final SourceInformation sourceInformation; 664 final SourceInformation sourceInformation;
634 665
635 GetStatic(this.element, [this.sourceInformation]); 666 GetStatic(this.element, [this.sourceInformation]);
636 667
637 accept(Visitor visitor) => visitor.visitGetStatic(this); 668 accept(Visitor visitor) => visitor.visitGetStatic(this);
669
670 bool get isSafeForElimination {
671 return true;
672 }
673 bool get isSafeForReordering {
674 return element is FunctionElement || element.isFinal;
675 }
638 } 676 }
639 677
640 /// Sets the value of a static field. 678 /// Sets the value of a static field.
641 class SetStatic extends Expression implements InteriorNode { 679 class SetStatic extends Expression implements InteriorNode {
642 final FieldElement element; 680 final FieldElement element;
643 final Reference<Primitive> value; 681 final Reference<Primitive> value;
644 Expression body; 682 Expression body;
645 final SourceInformation sourceInformation; 683 final SourceInformation sourceInformation;
646 684
647 SetStatic(this.element, Primitive value, [this.sourceInformation]) 685 SetStatic(this.element, Primitive value, [this.sourceInformation])
(...skipping 22 matching lines...) Expand all
670 Continuation continuation, 708 Continuation continuation,
671 [this.sourceInformation]) 709 [this.sourceInformation])
672 : continuation = new Reference<Continuation>(continuation); 710 : continuation = new Reference<Continuation>(continuation);
673 711
674 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); 712 accept(Visitor visitor) => visitor.visitGetLazyStatic(this);
675 } 713 }
676 714
677 /// Creates an object for holding boxed variables captured by a closure. 715 /// Creates an object for holding boxed variables captured by a closure.
678 class CreateBox extends Primitive { 716 class CreateBox extends Primitive {
679 accept(Visitor visitor) => visitor.visitCreateBox(this); 717 accept(Visitor visitor) => visitor.visitCreateBox(this);
718
719 bool get isSafeForElimination => true;
720 bool get isSafeForReordering => true;
680 } 721 }
681 722
682 /// Creates an instance of a class and initializes its fields and runtime type 723 /// Creates an instance of a class and initializes its fields and runtime type
683 /// information. 724 /// information.
684 class CreateInstance extends Primitive { 725 class CreateInstance extends Primitive {
685 final ClassElement classElement; 726 final ClassElement classElement;
686 727
687 /// Initial values for the fields on the class. 728 /// Initial values for the fields on the class.
688 /// The order corresponds to the order of fields on the class. 729 /// The order corresponds to the order of fields on the class.
689 final List<Reference<Primitive>> arguments; 730 final List<Reference<Primitive>> arguments;
690 731
691 /// The runtime type information structure which contains the type arguments. 732 /// The runtime type information structure which contains the type arguments.
692 /// 733 ///
693 /// May be `null` to indicate that no type information is needed because the 734 /// May be `null` to indicate that no type information is needed because the
694 /// compiler determined that the type information for instances of this class 735 /// compiler determined that the type information for instances of this class
695 /// is not needed at runtime. 736 /// is not needed at runtime.
696 final List<Reference<Primitive>> typeInformation; 737 final List<Reference<Primitive>> typeInformation;
697 738
698 CreateInstance(this.classElement, List<Primitive> arguments, 739 CreateInstance(this.classElement, List<Primitive> arguments,
699 List<Primitive> typeInformation) 740 List<Primitive> typeInformation)
700 : this.arguments = _referenceList(arguments), 741 : this.arguments = _referenceList(arguments),
701 this.typeInformation = _referenceList(typeInformation); 742 this.typeInformation = _referenceList(typeInformation);
702 743
703 accept(Visitor visitor) => visitor.visitCreateInstance(this); 744 accept(Visitor visitor) => visitor.visitCreateInstance(this);
745
746 bool get isSafeForElimination => true;
747 bool get isSafeForReordering => true;
704 } 748 }
705 749
706 class Interceptor extends Primitive { 750 class Interceptor extends Primitive {
707 final Reference<Primitive> input; 751 final Reference<Primitive> input;
708 final Set<ClassElement> interceptedClasses; 752 final Set<ClassElement> interceptedClasses;
709 Interceptor(Primitive input, this.interceptedClasses) 753 Interceptor(Primitive input, this.interceptedClasses)
710 : this.input = new Reference<Primitive>(input); 754 : this.input = new Reference<Primitive>(input);
711 accept(Visitor visitor) => visitor.visitInterceptor(this); 755 accept(Visitor visitor) => visitor.visitInterceptor(this);
756
757 bool get isSafeForElimination => true;
758 bool get isSafeForReordering => true;
712 } 759 }
713 760
714 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`. 761 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`.
715 class CreateInvocationMirror extends Primitive { 762 class CreateInvocationMirror extends Primitive {
716 final Selector selector; 763 final Selector selector;
717 final List<Reference<Primitive>> arguments; 764 final List<Reference<Primitive>> arguments;
718 765
719 CreateInvocationMirror(this.selector, List<Primitive> arguments) 766 CreateInvocationMirror(this.selector, List<Primitive> arguments)
720 : this.arguments = _referenceList(arguments); 767 : this.arguments = _referenceList(arguments);
721 768
722 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); 769 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this);
770
771 bool get isSafeForElimination => true;
772 bool get isSafeForReordering => true;
723 } 773 }
724 774
725 class ForeignCode extends Expression { 775 class ForeignCode extends Expression {
726 final js.Template codeTemplate; 776 final js.Template codeTemplate;
727 final TypeMask type; 777 final TypeMask type;
728 final List<Reference<Primitive>> arguments; 778 final List<Reference<Primitive>> arguments;
729 final native.NativeBehavior nativeBehavior; 779 final native.NativeBehavior nativeBehavior;
730 final FunctionElement dependency; 780 final FunctionElement dependency;
731 781
732 /// The continuation, if the foreign code is not a JavaScript 'throw', 782 /// The continuation, if the foreign code is not a JavaScript 'throw',
733 /// otherwise null. 783 /// otherwise null.
734 final Reference<Continuation> continuation; 784 final Reference<Continuation> continuation;
735 785
736 ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments, 786 ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments,
737 this.nativeBehavior, {Continuation continuation, this.dependency}) 787 this.nativeBehavior, {Continuation continuation, this.dependency})
738 : arguments = _referenceList(arguments), 788 : arguments = _referenceList(arguments),
739 continuation = continuation == null ? null 789 continuation = continuation == null ? null
740 : new Reference<Continuation>(continuation); 790 : new Reference<Continuation>(continuation);
741 791
742 accept(Visitor visitor) => visitor.visitForeignCode(this); 792 accept(Visitor visitor) => visitor.visitForeignCode(this);
743 } 793 }
744 794
745 class Constant extends Primitive { 795 class Constant extends Primitive {
746 final values.ConstantValue value; 796 final values.ConstantValue value;
747 797
748 Constant(this.value); 798 Constant(this.value);
749 799
750 accept(Visitor visitor) => visitor.visitConstant(this); 800 accept(Visitor visitor) => visitor.visitConstant(this);
801
802 bool get isSafeForElimination => true;
803 bool get isSafeForReordering => true;
751 } 804 }
752 805
753 class LiteralList extends Primitive { 806 class LiteralList extends Primitive {
754 /// The List type being created; this is not the type argument. 807 /// The List type being created; this is not the type argument.
755 final InterfaceType type; 808 final InterfaceType type;
756 final List<Reference<Primitive>> values; 809 final List<Reference<Primitive>> values;
757 810
758 LiteralList(this.type, List<Primitive> values) 811 LiteralList(this.type, List<Primitive> values)
759 : this.values = _referenceList(values); 812 : this.values = _referenceList(values);
760 813
761 accept(Visitor visitor) => visitor.visitLiteralList(this); 814 accept(Visitor visitor) => visitor.visitLiteralList(this);
815
816 bool get isSafeForElimination => true;
817 bool get isSafeForReordering => true;
762 } 818 }
763 819
764 class LiteralMapEntry { 820 class LiteralMapEntry {
765 final Reference<Primitive> key; 821 final Reference<Primitive> key;
766 final Reference<Primitive> value; 822 final Reference<Primitive> value;
767 823
768 LiteralMapEntry(Primitive key, Primitive value) 824 LiteralMapEntry(Primitive key, Primitive value)
769 : this.key = new Reference<Primitive>(key), 825 : this.key = new Reference<Primitive>(key),
770 this.value = new Reference<Primitive>(value); 826 this.value = new Reference<Primitive>(value);
771 } 827 }
772 828
773 class LiteralMap extends Primitive { 829 class LiteralMap extends Primitive {
774 final InterfaceType type; 830 final InterfaceType type;
775 final List<LiteralMapEntry> entries; 831 final List<LiteralMapEntry> entries;
776 832
777 LiteralMap(this.type, this.entries); 833 LiteralMap(this.type, this.entries);
778 834
779 accept(Visitor visitor) => visitor.visitLiteralMap(this); 835 accept(Visitor visitor) => visitor.visitLiteralMap(this);
836
837 bool get isSafeForElimination => true;
838 bool get isSafeForReordering => true;
780 } 839 }
781 840
782 /// Currently unused. 841 /// Currently unused.
783 /// 842 ///
784 /// Nested functions (from Dart code) are translated to classes by closure 843 /// Nested functions (from Dart code) are translated to classes by closure
785 /// conversion, hence they are instantiated with [CreateInstance]. 844 /// conversion, hence they are instantiated with [CreateInstance].
786 /// 845 ///
787 /// We keep this around for now because it might come in handy when we 846 /// We keep this around for now because it might come in handy when we
788 /// handle async/await in the CPS IR. 847 /// handle async/await in the CPS IR.
789 /// 848 ///
790 /// Instantiates a nested function. [MutableVariable]s are in scope in the 849 /// Instantiates a nested function. [MutableVariable]s are in scope in the
791 /// inner function, but primitives are not shared across function boundaries. 850 /// inner function, but primitives are not shared across function boundaries.
792 class CreateFunction extends Primitive { 851 class CreateFunction extends Primitive {
793 final FunctionDefinition definition; 852 final FunctionDefinition definition;
794 853
795 CreateFunction(this.definition); 854 CreateFunction(this.definition);
796 855
797 accept(Visitor visitor) => visitor.visitCreateFunction(this); 856 accept(Visitor visitor) => visitor.visitCreateFunction(this);
857
858 bool get isSafeForElimination => true;
859 bool get isSafeForReordering => true;
798 } 860 }
799 861
800 class Parameter extends Primitive { 862 class Parameter extends Primitive {
801 Parameter(Entity hint) { 863 Parameter(Entity hint) {
802 super.hint = hint; 864 super.hint = hint;
803 } 865 }
804 866
805 // In addition to a parent pointer to the containing Continuation or 867 // In addition to a parent pointer to the containing Continuation or
806 // FunctionDefinition, parameters have an index into the list of parameters 868 // FunctionDefinition, parameters have an index into the list of parameters
807 // bound by the parent. This gives constant-time access to the continuation 869 // bound by the parent. This gives constant-time access to the continuation
808 // from the parent. 870 // from the parent.
809 int parentIndex; 871 int parentIndex;
810 872
811 accept(Visitor visitor) => visitor.visitParameter(this); 873 accept(Visitor visitor) => visitor.visitParameter(this);
812 874
813 String toString() => 'Parameter(${hint == null ? null : hint.name})'; 875 String toString() => 'Parameter(${hint == null ? null : hint.name})';
876
877 bool get isSafeForElimination => true;
878 bool get isSafeForReordering => true;
814 } 879 }
815 880
816 /// Continuations are normally bound by 'let cont'. A continuation with one 881 /// Continuations are normally bound by 'let cont'. A continuation with one
817 /// parameter and no body is used to represent a function's return continuation. 882 /// parameter and no body is used to represent a function's return continuation.
818 /// The return continuation is bound by the function, not by 'let cont'. 883 /// The return continuation is bound by the function, not by 'let cont'.
819 class Continuation extends Definition<Continuation> implements InteriorNode { 884 class Continuation extends Definition<Continuation> implements InteriorNode {
820 final List<Parameter> parameters; 885 final List<Parameter> parameters;
821 Expression body = null; 886 Expression body = null;
822 887
823 // In addition to a parent pointer to the containing LetCont, continuations 888 // In addition to a parent pointer to the containing LetCont, continuations
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 /// [Type]. 935 /// [Type].
871 class ReifyRuntimeType extends Primitive { 936 class ReifyRuntimeType extends Primitive {
872 /// Reference to the internal representation of a type (as produced, for 937 /// Reference to the internal representation of a type (as produced, for
873 /// example, by [ReadTypeVariable]). 938 /// example, by [ReadTypeVariable]).
874 final Reference<Primitive> value; 939 final Reference<Primitive> value;
875 ReifyRuntimeType(Primitive value) 940 ReifyRuntimeType(Primitive value)
876 : this.value = new Reference<Primitive>(value); 941 : this.value = new Reference<Primitive>(value);
877 942
878 @override 943 @override
879 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this); 944 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this);
945
946 bool get isSafeForElimination => true;
947 bool get isSafeForReordering => true;
880 } 948 }
881 949
882 /// Read the value the type variable [variable] from the target object. 950 /// Read the value the type variable [variable] from the target object.
883 /// 951 ///
884 /// The resulting value is an internal representation (and not neccessarily a 952 /// The resulting value is an internal representation (and not neccessarily a
885 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be 953 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be
886 /// used as a Dart value. 954 /// used as a Dart value.
887 class ReadTypeVariable extends Primitive { 955 class ReadTypeVariable extends Primitive {
888 final TypeVariableType variable; 956 final TypeVariableType variable;
889 final Reference<Primitive> target; 957 final Reference<Primitive> target;
890 958
891 ReadTypeVariable(this.variable, Primitive target) 959 ReadTypeVariable(this.variable, Primitive target)
892 : this.target = new Reference<Primitive>(target); 960 : this.target = new Reference<Primitive>(target);
893 961
894 @override 962 @override
895 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); 963 accept(Visitor visitor) => visitor.visitReadTypeVariable(this);
964
965 bool get isSafeForElimination => true;
966 bool get isSafeForReordering => true;
896 } 967 }
897 968
898 /// Representation of a closed type (that is, a type without type variables). 969 /// Representation of a closed type (that is, a type without type variables).
899 /// 970 ///
900 /// The resulting value is constructed from [dartType] by replacing the type 971 /// The resulting value is constructed from [dartType] by replacing the type
901 /// variables with consecutive values from [arguments], in the order generated 972 /// variables with consecutive values from [arguments], in the order generated
902 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are 973 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are
903 /// treated as 'holes' in the term, which means that it must be ensured at 974 /// treated as 'holes' in the term, which means that it must be ensured at
904 /// construction, that duplicate occurences of a type variable in [dartType] 975 /// construction, that duplicate occurences of a type variable in [dartType]
905 /// are assigned the same value. 976 /// are assigned the same value.
906 class TypeExpression extends Primitive { 977 class TypeExpression extends Primitive {
907 final DartType dartType; 978 final DartType dartType;
908 final List<Reference<Primitive>> arguments; 979 final List<Reference<Primitive>> arguments;
909 980
910 TypeExpression(this.dartType, 981 TypeExpression(this.dartType,
911 [List<Primitive> arguments = const <Primitive>[]]) 982 [List<Primitive> arguments = const <Primitive>[]])
912 : this.arguments = _referenceList(arguments); 983 : this.arguments = _referenceList(arguments);
913 984
914 @override 985 @override
915 accept(Visitor visitor) { 986 accept(Visitor visitor) {
916 return visitor.visitTypeExpression(this); 987 return visitor.visitTypeExpression(this);
917 } 988 }
989
990 bool get isSafeForElimination => true;
991 bool get isSafeForReordering => true;
918 } 992 }
919 993
920 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { 994 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
921 return definitions.map((e) => new Reference<Primitive>(e)).toList(); 995 return definitions.map((e) => new Reference<Primitive>(e)).toList();
922 } 996 }
923 997
924 abstract class Visitor<T> { 998 abstract class Visitor<T> {
925 const Visitor(); 999 const Visitor();
926 1000
927 T visit(Node node); 1001 T visit(Node node);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 const RemovalVisitor(); 1341 const RemovalVisitor();
1268 1342
1269 processReference(Reference reference) { 1343 processReference(Reference reference) {
1270 reference.unlink(); 1344 reference.unlink();
1271 } 1345 }
1272 1346
1273 static void remove(Node node) { 1347 static void remove(Node node) {
1274 (const RemovalVisitor()).visit(node); 1348 (const RemovalVisitor()).visit(node);
1275 } 1349 }
1276 } 1350 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/type_propagation.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698