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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_nodes.dart

Issue 312793002: dart2dart: Preserve variable names throughout the IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
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 // IrNodes are kept in a separate library to have precise control over their 5 // IrNodes are kept in a separate library to have precise control over their
6 // dependencies on other parts of the system. 6 // dependencies on other parts of the system.
7 library dart2js.ir_nodes; 7 library dart2js.ir_nodes;
8 8
9 import '../dart2jslib.dart' as dart2js show Constant; 9 import '../dart2jslib.dart' as dart2js show Constant;
10 import '../elements/elements.dart' 10 import '../elements/elements.dart'
11 show FunctionElement, LibraryElement, ParameterElement, ClassElement; 11 show FunctionElement, LibraryElement, ParameterElement, ClassElement,
12 Element, VariableElement;
12 import '../universe/universe.dart' show Selector, SelectorKind; 13 import '../universe/universe.dart' show Selector, SelectorKind;
13 import '../dart_types.dart' show DartType, GenericType; 14 import '../dart_types.dart' show DartType, GenericType;
15 import '../helpers/helpers.dart';
14 16
15 abstract class Node { 17 abstract class Node {
16 static int hashCount = 0; 18 static int hashCount = 0;
17 final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff; 19 final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff;
18 20
19 accept(Visitor visitor); 21 accept(Visitor visitor);
20 } 22 }
21 23
22 abstract class Expression extends Node { 24 abstract class Expression extends Node {
23 Expression plug(Expression expr) => throw 'impossible'; 25 Expression plug(Expression expr) => throw 'impossible';
24 } 26 }
25 27
26 /// The base class of things that variables can refer to: primitives, 28 /// The base class of things that variables can refer to: primitives,
27 /// continuations, function and continuation parameters, etc. 29 /// continuations, function and continuation parameters, etc.
28 abstract class Definition extends Node { 30 abstract class Definition extends Node {
29 // The head of a linked-list of occurrences, in no particular order. 31 // The head of a linked-list of occurrences, in no particular order.
30 Reference firstRef = null; 32 Reference firstRef = null;
31 33
34 /// The [LetCont], [LetPrim], [Continuation] or [FunctionDefinition] binding
35 /// this definition.
36 Node binding;
37
32 bool get hasAtMostOneUse => firstRef == null || firstRef.nextRef == null; 38 bool get hasAtMostOneUse => firstRef == null || firstRef.nextRef == null;
33 bool get hasExactlyOneUse => firstRef != null && firstRef.nextRef == null; 39 bool get hasExactlyOneUse => firstRef != null && firstRef.nextRef == null;
34 bool get hasAtLeastOneUse => firstRef != null; 40 bool get hasAtLeastOneUse => firstRef != null;
35 bool get hasMultipleUses => !hasAtMostOneUse; 41 bool get hasMultipleUses => !hasAtMostOneUse;
36 42
37 void substituteFor(Definition other) { 43 void substituteFor(Definition other) {
38 if (other.firstRef == null) return; 44 if (other.firstRef == null) return;
39 Reference previous, current = other.firstRef; 45 Reference previous, current = other.firstRef;
40 do { 46 do {
41 current.definition = this; 47 current.definition = this;
42 previous = current; 48 previous = current;
43 current = current.nextRef; 49 current = current.nextRef;
44 } while (current != null); 50 } while (current != null);
45 previous.nextRef = firstRef; 51 previous.nextRef = firstRef;
46 firstRef = other.firstRef; 52 firstRef = other.firstRef;
47 } 53 }
48 } 54 }
49 55
56 /// An pure expression that cannot throw or diverge.
sigurdm 2014/06/04 07:51:56 An -> A
57 /// All primitives are named using the identity of the [Primitive] object.
50 abstract class Primitive extends Definition { 58 abstract class Primitive extends Definition {
59 /// The [VariableElement] or [ParameterElement] from which the primitive
60 /// binding originated.
61 Element element;
62
63 /// Register in which the variable binding this primitive can be allocated.
64 /// Separate register spaces are used for primitives with different [element].
65 /// Assigned by [RegisterAllocator], is null before that phase.
66 int registerIndex;
51 } 67 }
52 68
53 /// Operands to invocations and primitives are always variables. They point to 69 /// Operands to invocations and primitives are always variables. They point to
54 /// their definition and are linked into a list of occurrences. 70 /// their definition and are linked into a list of occurrences.
55 class Reference { 71 class Reference {
56 Definition definition; 72 Definition definition;
57 Reference nextRef = null; 73 Reference nextRef = null;
58 74
59 Reference(this.definition) { 75 Reference(this.definition) {
60 nextRef = definition.firstRef; 76 nextRef = definition.firstRef;
61 definition.firstRef = this; 77 definition.firstRef = this;
62 } 78 }
63 } 79 }
64 80
65 /// Binding a value (primitive or constant): 'let val x = V in E'. The bound 81 /// Binding a value (primitive or constant): 'let val x = V in E'. The bound
66 /// value is in scope in the body. 82 /// value is in scope in the body.
67 /// During one-pass construction a LetVal with an empty body is used to 83 /// During one-pass construction a LetVal with an empty body is used to
68 /// represent one-level context 'let val x = V in []'. 84 /// represent one-level context 'let val x = V in []'.
69 class LetPrim extends Expression { 85 class LetPrim extends Expression {
70 final Primitive primitive; 86 final Primitive primitive;
71 Expression body = null; 87 Expression body = null;
72 88
73 LetPrim(this.primitive); 89 LetPrim(this.primitive) {
90 primitive.binding = this;
91 }
74 92
75 Expression plug(Expression expr) { 93 Expression plug(Expression expr) {
76 assert(body == null); 94 assert(body == null);
77 return body = expr; 95 return body = expr;
78 } 96 }
79 97
80 accept(Visitor visitor) => visitor.visitLetPrim(this); 98 accept(Visitor visitor) => visitor.visitLetPrim(this);
81 } 99 }
82 100
83 101
84 /// Binding a continuation: 'let cont k(v) = E in E'. The bound continuation 102 /// Binding a continuation: 'let cont k(v) = E in E'. The bound continuation
85 /// is in scope in the body and the continuation parameter is in scope in the 103 /// is in scope in the body and the continuation parameter is in scope in the
86 /// continuation body. 104 /// continuation body.
87 /// During one-pass construction a LetCont with an empty continuation body is 105 /// During one-pass construction a LetCont with an empty continuation body is
88 /// used to represent the one-level context 'let cont k(v) = [] in E'. 106 /// used to represent the one-level context 'let cont k(v) = [] in E'.
89 class LetCont extends Expression { 107 class LetCont extends Expression {
90 final Continuation continuation; 108 final Continuation continuation;
91 final Expression body; 109 final Expression body;
92 110
93 LetCont(this.continuation, this.body); 111 LetCont(this.continuation, this.body) {
112 continuation.binding = this;
113 }
94 114
95 Expression plug(Expression expr) { 115 Expression plug(Expression expr) {
96 assert(continuation.body == null); 116 assert(continuation.body == null);
97 return continuation.body = expr; 117 return continuation.body = expr;
98 } 118 }
99 119
100 accept(Visitor visitor) => visitor.visitLetCont(this); 120 accept(Visitor visitor) => visitor.visitLetCont(this);
101 } 121 }
102 122
103 abstract class Invoke { 123 abstract class Invoke {
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 List<Reference> values; 286 List<Reference> values;
267 287
268 LiteralMap(List<Primitive> keys, List<Primitive> values) 288 LiteralMap(List<Primitive> keys, List<Primitive> values)
269 : this.keys = _referenceList(keys), 289 : this.keys = _referenceList(keys),
270 this.values = _referenceList(values); 290 this.values = _referenceList(values);
271 291
272 accept(Visitor visitor) => visitor.visitLiteralMap(this); 292 accept(Visitor visitor) => visitor.visitLiteralMap(this);
273 } 293 }
274 294
275 class Parameter extends Primitive { 295 class Parameter extends Primitive {
276 final ParameterElement element; 296 Parameter(Element element) {
277 297 super.element = element;
278 Parameter(this.element); 298 }
279 299
280 accept(Visitor visitor) => visitor.visitParameter(this); 300 accept(Visitor visitor) => visitor.visitParameter(this);
281 } 301 }
282 302
283 /// Continuations are normally bound by 'let cont'. A continuation with no 303 /// Continuations are normally bound by 'let cont'. A continuation with no
284 /// parameter (or body) is used to represent a function's return continuation. 304 /// parameter (or body) is used to represent a function's return continuation.
285 /// The return continuation is bound by the Function, not by 'let cont'. 305 /// The return continuation is bound by the Function, not by 'let cont'.
286 class Continuation extends Definition { 306 class Continuation extends Definition {
287 final List<Parameter> parameters; 307 final List<Parameter> parameters;
288 Expression body = null; 308 Expression body = null;
289 309
290 // A continuation is recursive if it has any recursive invocations. 310 // A continuation is recursive if it has any recursive invocations.
291 bool isRecursive = false; 311 bool isRecursive = false;
292 312
293 Continuation(this.parameters); 313 Continuation(this.parameters) {
314 for (Parameter param in parameters) {
315 param.binding = this;
316 }
317 }
294 318
295 Continuation.retrn() : parameters = null; 319 Continuation.retrn() : parameters = null;
296 320
297 accept(Visitor visitor) => visitor.visitContinuation(this); 321 accept(Visitor visitor) => visitor.visitContinuation(this);
298 } 322 }
299 323
300 /// A function definition, consisting of parameters and a body. The parameters 324 /// A function definition, consisting of parameters and a body. The parameters
301 /// include a distinguished continuation parameter. 325 /// include a distinguished continuation parameter.
302 class FunctionDefinition extends Node { 326 class FunctionDefinition extends Node {
303 final Continuation returnContinuation; 327 final Continuation returnContinuation;
304 final List<Parameter> parameters; 328 final List<Parameter> parameters;
305 final Expression body; 329 final Expression body;
306 330
307 FunctionDefinition(this.returnContinuation, this.parameters, this.body); 331 FunctionDefinition(this.returnContinuation, this.parameters, this.body) {
332 for (Parameter param in parameters) {
333 param.binding = this;
334 }
335 returnContinuation.binding = this;
336 }
308 337
309 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); 338 accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
310 } 339 }
311 340
312 List<Reference> _referenceList(List<Definition> definitions) { 341 List<Reference> _referenceList(List<Definition> definitions) {
313 return definitions.map((e) => new Reference(e)).toList(growable: false); 342 return definitions.map((e) => new Reference(e)).toList(growable: false);
314 } 343 }
315 344
316 abstract class Visitor<T> { 345 abstract class Visitor<T> {
317 T visit(Node node) => node.accept(this); 346 T visit(Node node) => node.accept(this);
(...skipping 21 matching lines...) Expand all
339 T visitLiteralList(LiteralList node) => visitPrimitive(node); 368 T visitLiteralList(LiteralList node) => visitPrimitive(node);
340 T visitLiteralMap(LiteralMap node) => visitPrimitive(node); 369 T visitLiteralMap(LiteralMap node) => visitPrimitive(node);
341 T visitConstant(Constant node) => visitPrimitive(node); 370 T visitConstant(Constant node) => visitPrimitive(node);
342 T visitParameter(Parameter node) => visitPrimitive(node); 371 T visitParameter(Parameter node) => visitPrimitive(node);
343 T visitContinuation(Continuation node) => visitDefinition(node); 372 T visitContinuation(Continuation node) => visitDefinition(node);
344 373
345 // Conditions. 374 // Conditions.
346 T visitIsTrue(IsTrue node) => visitCondition(node); 375 T visitIsTrue(IsTrue node) => visitCondition(node);
347 } 376 }
348 377
378
sigurdm 2014/06/04 07:51:56 Extra newline
349 /// Generate a Lisp-like S-expression representation of an IR node as a string. 379 /// Generate a Lisp-like S-expression representation of an IR node as a string.
350 /// The representation is not pretty-printed, but it can easily be quoted and 380 /// The representation is not pretty-printed, but it can easily be quoted and
351 /// dropped into the REPL of one's favorite Lisp or Scheme implementation to be 381 /// dropped into the REPL of one's favorite Lisp or Scheme implementation to be
352 /// pretty-printed. 382 /// pretty-printed.
353 class SExpressionStringifier extends Visitor<String> { 383 class SExpressionStringifier extends Visitor<String> {
354 final Map<Definition, String> names = <Definition, String>{}; 384 final Map<Definition, String> names = <Definition, String>{};
355 385
356 int _valueCounter = 0; 386 int _valueCounter = 0;
357 int _continuationCounter = 0; 387 int _continuationCounter = 0;
358 388
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 String visitContinuation(Continuation node) { 498 String visitContinuation(Continuation node) {
469 // Continuations are visited directly in visitLetCont. 499 // Continuations are visited directly in visitLetCont.
470 return '(Unexpected Continuation)'; 500 return '(Unexpected Continuation)';
471 } 501 }
472 502
473 String visitIsTrue(IsTrue node) { 503 String visitIsTrue(IsTrue node) {
474 String value = names[node.value.definition]; 504 String value = names[node.value.definition];
475 return '(IsTrue $value)'; 505 return '(IsTrue $value)';
476 } 506 }
477 } 507 }
508
509 /// Determines for each continuations the highest scope to which it can be
510 /// lifted without moving a reference out of scope.
511 /// A scope is a [LetPrim], [Continuation], or top-level (represented as null).
512 /// Does not mutate the IR.
513 class FindLiftableContinuations extends Visitor {
514 final Map<Node, int> scope2depth = <Node, int>{};
515
516 /// Maps a scope to its enclosing continuation (prior to lifting) or null
517 /// if not inside a continuation.
518 final Map<Node, Continuation> enclosingContinuation = <Node, Continuation>{};
519
520 /// Maps a continuation to the outermost scope to which it can be lifted,
521 /// or null or absent if it can be lifted all the way to top-level.
522 final Map<Continuation, Node> liftTarget = <Continuation, Node>{};
523
524 /// Inverse of [liftTarget].
525 final Map<Node, List<Continuation>> liftedContinuations =
526 <Node, List<Continuation>>{};
527
528 Continuation currentContinuation;
529 int currentDepth = 0;
530
531 /// Restricts [child] so that it cannot be lifted outside of [ancestor].
532 void requireAncestor(Node child, Node ancestor) {
533 // Only continuations are lifted, but in doing so, all let bindings inside
534 // the continuation are also lifted with it. we therefore restrict the
535 // lifting of the continuation that encloses [child].
536 Continuation cont = enclosingContinuation[child];
537
538 // If [child] is in the top-level it cannot be lifted, hence no restrictions
539 // are necessary
540 if (cont == null) return;
541
542 // If [child] and [ancestor] are in the same continuation, their nesting
543 // order is unaffected by lifting, so no restrictions are necessary.
544 if (enclosingContinuation[ancestor] == cont) return;
545
546 // The continuation may not be lifted further than [ancestor].
547 liftTarget[cont] = join(liftTarget[cont], ancestor);
548
549 assert(liftTarget[cont] != cont);
550 }
551
552 /// Returns the deepest of the two given scopes. The nesting order of scopes
553 /// may be affected by lifting, but this function will restrict lifting of
554 /// continuations to ensure that the returned scope remains the most deeply
555 /// nested scope also after lifting.
556 Node join(Node s1, Node s2) {
557 if (s1 == null) return s2;
558 if (s2 == null) return s1;
559 if (s1 == s2) return s1;
560 int d1 = scope2depth[s1];
561 int d2 = scope2depth[s2];
562 assert(d1 != d2);
563 if (d1 < d2) { // s1 is ancestor of s2?
564 requireAncestor(s2, s1); // ensure that s2 remains inside of s1
565 return s2;
566 } else {
567 requireAncestor(s1, s2); // ensure that s1 remains inside of s2
568 return s1;
569 }
570 }
571
572 /// Returns the continuations that could be lifted to the given scope.
573 Iterable<Continuation> getContinuationsLiftedTo(Node scope) {
574 List list = liftedContinuations[scope];
575 if (list != null)
576 return list;
577 return const [];
578 }
579
580 void visitFunctionDefinition(FunctionDefinition node) {
581 scope2depth[node] = 0;
582 ++currentDepth;
583 visit(node.body);
584 --currentDepth;
585
586 // Build inverse of liftTarget
587 for (Continuation cont in liftTarget.keys) {
588 Node target = liftTarget[cont];
589 List<Continuation> list = liftedContinuations[target];
590 if (list == null) {
591 list = <Continuation>[];
592 liftedContinuations[target] = list;
593 }
594 list.add(cont);
595 }
596 }
597
598 // visit returns the outermost scope to which the given expression
599 // can be lifted without breaking scope.
600
601 Node visitReference(Reference ref) {
602 Definition definition = ref.definition;
603 if (definition is Continuation) {
604 // Non-recursive reference to a continuation. Its lift target has been
605 // completely resolved by now since we are inside the LetCont binding.
606 // This reference can be lifted as far as the continuation.
607 return liftTarget[definition];
608 } else {
609 return ref.definition.binding;
sigurdm 2014/06/04 07:51:56 You can use return definition.binding
asgerf 2014/06/04 09:40:51 Thanks
610 }
611 }
612
613 Node visitReferenceList(List<Reference> refs) {
sigurdm 2014/06/04 07:51:56 Could be a fold
614 Node scope = null;
615 for (Reference ref in refs) {
616 scope = join(scope, visitReference(ref));
617 }
618 return scope;
619 }
620
621 Node visitRecursiveReference(Reference ref) {
622 // A recursive self-reference inside a continuation can be lifted to the
623 // body of the continuation, not the body of the LetCont.
624 return ref.definition as Continuation;
625 }
626
627 Node visitLetPrim(LetPrim node) {
628 Node primScope = visit(node.primitive);
629 scope2depth[node] = currentDepth;
630 enclosingContinuation[node] = currentContinuation;
631 ++currentDepth;
632 Node bodyScope = visit(node.body);
633 --currentDepth;
634 return join(primScope, bodyScope);
635 }
636
637 Node visitLetCont(LetCont node) {
638 scope2depth[node] = currentDepth;
639 enclosingContinuation[node] = currentContinuation;
640 ++currentDepth;
641 visit(node.continuation);
642 Node bodyScope = visit(node.body);
643 --currentDepth;
644 return bodyScope;
645 }
646
647 Node visitInvokeStatic(InvokeStatic node) {
648 Node argScope = visitReferenceList(node.arguments);
649 Node contScope = visitReference(node.continuation);
650 return join(argScope, contScope);
651 }
652
653 Node visitInvokeContinuation(InvokeContinuation node) {
654 Node argScope = visitReferenceList(node.arguments);
655 Node contScope = node.isRecursive
656 ? visitRecursiveReference(node.continuation)
657 : visitReference(node.continuation);
658 return join(argScope, contScope);
659 }
660
661 Node visitInvokeMethod(InvokeMethod node) {
662 Node receiverScope = visitReference(node.receiver);
663 Node argScope = visitReferenceList(node.arguments);
664 Node contScope = visitReference(node.continuation);
665 return join(receiverScope, join(argScope, contScope));
666 }
667
668 Node visitInvokeConstructor(InvokeConstructor node) {
669 Node argScope = visitReferenceList(node.arguments);
670 Node contScope = visitReference(node.continuation);
671 return join(argScope, contScope);
672 }
673
674 Node visitConcatenateStrings(ConcatenateStrings node) {
675 Node argScope = visitReferenceList(node.arguments);
676 Node contScope = visitReference(node.continuation);
677 return join(argScope, contScope);
678 }
679
680 Node visitBranch(Branch node) {
681 Node condScope = visit(node.condition);
682 Node thenScope = visitReference(node.trueContinuation);
683 Node elseScope = visitReference(node.falseContinuation);
684 return join(condScope, join(thenScope, elseScope));
685 }
686
687 Node visitLiteralList(LiteralList node) {
688 return visitReferenceList(node.values);
689 }
690
691 Node visitLiteralMap(LiteralMap node) {
692 Node keyScope = visitReferenceList(node.keys);
693 Node valueScope = visitReferenceList(node.values);
694 return join(keyScope, valueScope);
695 }
696
697 Node visitConstant(Constant node) {
698 return null;
699 }
700
701 Node visitParameter(Parameter node) {
702 throw "Parameters should not be visited";
703 }
704
705 void visitContinuation(Continuation node) {
706 enclosingContinuation[node] = node;
707 liftTarget[node] = null;
708 scope2depth[node] = currentDepth;
709 Continuation oldCont = currentContinuation;
710 currentContinuation = node;
711 ++currentDepth;
712 Node bodyScope = visit(node.body);
713 --currentDepth;
714 // If the body contains a reference to one of the continuation parameters,
715 // then the scope will be the continuation itself, and the nesting
716 // restrictions on the continuation will have been added by join().
717 // In other cases we must add the nesting restrictions here.
718 if (bodyScope != node) {
719 requireAncestor(node, bodyScope);
720 }
721 currentContinuation = oldCont;
722 }
723
724 Node visitIsTrue(IsTrue node) {
725 return visitReference(node.value);
726 }
727
728 }
729
730 /// Keeps track of currently unused register indices.
731 class RegisterArray {
732 int nextIndex = 0;
733 final List<int> freeStack = <int>[];
734
735 int makeIndex() {
736 if (freeStack.isEmpty) {
737 return nextIndex++;
738 } else {
739 return freeStack.removeLast();
740 }
741 }
742
743 void releaseIndex(int index) {
744 freeStack.add(index);
745 }
746 }
747
748 /// Assigns indices to each primitive in the IR such that primitives that are
749 /// live simultaneously never get assigned the same index.
750 /// This information is used by the dart tree builder to generate fewer
751 /// redundant variables.
752 /// Currently, the liveness analysis is very simple and is often inadequate
753 /// for removing all of the redundant variables.
754 class RegisterAllocator extends Visitor {
755 final FindLiftableContinuations lifts = new FindLiftableContinuations();
756
757 /// Separate register spaces for each source-level variable/parameter.
758 /// Note that null is used as key for primitives without elements.
759 final Map<Element, RegisterArray> elementRegisters =
760 <Element, RegisterArray>{};
761
762 RegisterArray getRegisterArray(Element element) {
763 RegisterArray registers = elementRegisters[element];
764 if (registers == null) {
765 registers = new RegisterArray();
766 elementRegisters[element] = registers;
767 }
768 return registers;
769 }
770
771 void allocate(Primitive primitive) {
772 if (primitive.registerIndex == null) {
773 primitive.registerIndex = getRegisterArray(primitive.element).makeIndex();
774 }
775 }
776
777 void release(Primitive primitive) {
778 // Do not share indices for temporaries as this may obstruct inlining.
779 if (primitive.element == null) return;
780 if (primitive.registerIndex != null) {
781 getRegisterArray(primitive.element).releaseIndex(primitive.registerIndex);
782 }
783 }
784
785 void visitLiftedContinuations(Node scope) {
786 for (Continuation cont in lifts.getContinuationsLiftedTo(scope)) {
787 assert(cont != scope);
788 visit(cont);
789 }
790 }
791
792 void visitReference(Reference reference) {
793 allocate(reference.definition);
794 }
795
796 void visitFunctionDefinition(FunctionDefinition node) {
797 lifts.visit(node);
798 visitLiftedContinuations(node);
799 visitLiftedContinuations(null);
800 visit(node.body);
801 node.parameters.forEach(allocate); // Assign indices to unused parameters.
802 elementRegisters.clear();
803 }
804
805 void visitLetPrim(LetPrim node) {
806 visitLiftedContinuations(node);
807 visit(node.body);
808 release(node.primitive);
809 visit(node.primitive);
810 }
811
812 void visitLetCont(LetCont node) {
813 assert(lifts.liftTarget.containsKey(node.continuation));
814 visit(node.body);
815 }
816
817 void visitInvokeStatic(InvokeStatic node) {
818 node.arguments.forEach(visitReference);
819 }
820
821 void visitInvokeContinuation(InvokeContinuation node) {
822 node.arguments.forEach(visitReference);
823 }
824
825 void visitInvokeMethod(InvokeMethod node) {
826 visitReference(node.receiver);
827 node.arguments.forEach(visitReference);
828 }
829
830 void visitInvokeConstructor(InvokeConstructor node) {
831 node.arguments.forEach(visitReference);
832 }
833
834 void visitConcatenateStrings(ConcatenateStrings node) {
835 node.arguments.forEach(visitReference);
836 }
837
838 void visitBranch(Branch node) {
839 visit(node.condition);
840 }
841
842 void visitLiteralList(LiteralList node) {
843 node.values.forEach(visitReference);
844 }
845
846 void visitLiteralMap(LiteralMap node) {
847 for (int i = 0; i < node.keys.length; ++i) {
848 visitReference(node.keys[i]);
849 visitReference(node.values[i]);
850 }
851 }
852
853 void visitConstant(Constant node) {
854 }
855
856 void visitParameter(Parameter node) {
857 throw "Parameters should not be visited by RegisterAllocator";
858 }
859
860 void visitContinuation(Continuation node) {
861 visitLiftedContinuations(node);
862 visit(node.body);
863
864 // Arguments get allocated left-to-right, so we release parameters
865 // right-to-left. This increases the likelihood that arguments can be
866 // transferred without intermediate assignments.
867 for (int i = node.parameters.length - 1; i >= 0; --i) {
868 release(node.parameters[i]);
869 }
870 }
871
872 void visitIsTrue(IsTrue node) {
873 visitReference(node.value);
874 }
875
876 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698