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

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: Removed Definition.binding 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';
(...skipping 16 matching lines...) Expand all
40 do { 42 do {
41 current.definition = this; 43 current.definition = this;
42 previous = current; 44 previous = current;
43 current = current.nextRef; 45 current = current.nextRef;
44 } while (current != null); 46 } while (current != null);
45 previous.nextRef = firstRef; 47 previous.nextRef = firstRef;
46 firstRef = other.firstRef; 48 firstRef = other.firstRef;
47 } 49 }
48 } 50 }
49 51
52 /// A pure expression that cannot throw or diverge.
53 /// All primitives are named using the identity of the [Primitive] object.
50 abstract class Primitive extends Definition { 54 abstract class Primitive extends Definition {
55 /// The [VariableElement] or [ParameterElement] from which the primitive
56 /// binding originated.
57 Element element;
58
59 /// Register in which the variable binding this primitive can be allocated.
60 /// Separate register spaces are used for primitives with different [element].
61 /// Assigned by [RegisterAllocator], is null before that phase.
62 int registerIndex;
51 } 63 }
52 64
53 /// Operands to invocations and primitives are always variables. They point to 65 /// Operands to invocations and primitives are always variables. They point to
54 /// their definition and are linked into a list of occurrences. 66 /// their definition and are linked into a list of occurrences.
55 class Reference { 67 class Reference {
56 Definition definition; 68 Definition definition;
57 Reference nextRef = null; 69 Reference nextRef = null;
58 70
59 Reference(this.definition) { 71 Reference(this.definition) {
60 nextRef = definition.firstRef; 72 nextRef = definition.firstRef;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 List<Reference> values; 303 List<Reference> values;
292 304
293 LiteralMap(List<Primitive> keys, List<Primitive> values) 305 LiteralMap(List<Primitive> keys, List<Primitive> values)
294 : this.keys = _referenceList(keys), 306 : this.keys = _referenceList(keys),
295 this.values = _referenceList(values); 307 this.values = _referenceList(values);
296 308
297 accept(Visitor visitor) => visitor.visitLiteralMap(this); 309 accept(Visitor visitor) => visitor.visitLiteralMap(this);
298 } 310 }
299 311
300 class Parameter extends Primitive { 312 class Parameter extends Primitive {
301 final ParameterElement element; 313 Parameter(Element element) {
302 314 super.element = element;
303 Parameter(this.element); 315 }
304 316
305 accept(Visitor visitor) => visitor.visitParameter(this); 317 accept(Visitor visitor) => visitor.visitParameter(this);
306 } 318 }
307 319
308 /// Continuations are normally bound by 'let cont'. A continuation with no 320 /// Continuations are normally bound by 'let cont'. A continuation with no
309 /// parameter (or body) is used to represent a function's return continuation. 321 /// parameter (or body) is used to represent a function's return continuation.
310 /// The return continuation is bound by the Function, not by 'let cont'. 322 /// The return continuation is bound by the Function, not by 'let cont'.
311 class Continuation extends Definition { 323 class Continuation extends Definition {
312 final List<Parameter> parameters; 324 final List<Parameter> parameters;
313 Expression body = null; 325 Expression body = null;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 String visitContinuation(Continuation node) { 506 String visitContinuation(Continuation node) {
495 // Continuations are visited directly in visitLetCont. 507 // Continuations are visited directly in visitLetCont.
496 return '(Unexpected Continuation)'; 508 return '(Unexpected Continuation)';
497 } 509 }
498 510
499 String visitIsTrue(IsTrue node) { 511 String visitIsTrue(IsTrue node) {
500 String value = names[node.value.definition]; 512 String value = names[node.value.definition];
501 return '(IsTrue $value)'; 513 return '(IsTrue $value)';
502 } 514 }
503 } 515 }
516
517 /// Keeps track of currently unused register indices.
518 class RegisterArray {
519 int nextIndex = 0;
520 final List<int> freeStack = <int>[];
521
522 int makeIndex() {
523 if (freeStack.isEmpty) {
524 return nextIndex++;
525 } else {
526 return freeStack.removeLast();
527 }
528 }
529
530 void releaseIndex(int index) {
531 freeStack.add(index);
532 }
533 }
534
535 /// Assigns indices to each primitive in the IR such that primitives that are
536 /// live simultaneously never get assigned the same index.
537 /// This information is used by the dart tree builder to generate fewer
538 /// redundant variables.
539 /// Currently, the liveness analysis is very simple and is often inadequate
540 /// for removing all of the redundant variables.
541 class RegisterAllocator extends Visitor {
542 /// Separate register spaces for each source-level variable/parameter.
543 /// Note that null is used as key for primitives without elements.
544 final Map<Element, RegisterArray> elementRegisters =
545 <Element, RegisterArray>{};
546
547 RegisterArray getRegisterArray(Element element) {
548 RegisterArray registers = elementRegisters[element];
549 if (registers == null) {
550 registers = new RegisterArray();
551 elementRegisters[element] = registers;
552 }
553 return registers;
554 }
555
556 void allocate(Primitive primitive) {
557 if (primitive.registerIndex == null) {
558 primitive.registerIndex = getRegisterArray(primitive.element).makeIndex();
559 }
560 }
561
562 void release(Primitive primitive) {
563 // Do not share indices for temporaries as this may obstruct inlining.
564 if (primitive.element == null) return;
565 if (primitive.registerIndex != null) {
566 getRegisterArray(primitive.element).releaseIndex(primitive.registerIndex);
567 }
568 }
569
570 void visitReference(Reference reference) {
571 allocate(reference.definition);
572 }
573
574 void visitFunctionDefinition(FunctionDefinition node) {
575 visit(node.body);
576 node.parameters.forEach(allocate); // Assign indices to unused parameters.
577 elementRegisters.clear();
578 }
579
580 void visitLetPrim(LetPrim node) {
581 visit(node.body);
582 release(node.primitive);
583 visit(node.primitive);
584 }
585
586 void visitLetCont(LetCont node) {
587 visit(node.continuation);
588 visit(node.body);
589 }
590
591 void visitInvokeStatic(InvokeStatic node) {
592 node.arguments.forEach(visitReference);
593 }
594
595 void visitInvokeContinuation(InvokeContinuation node) {
596 node.arguments.forEach(visitReference);
597 }
598
599 void visitInvokeMethod(InvokeMethod node) {
600 visitReference(node.receiver);
601 node.arguments.forEach(visitReference);
602 }
603
604 void visitInvokeConstructor(InvokeConstructor node) {
605 node.arguments.forEach(visitReference);
606 }
607
608 void visitConcatenateStrings(ConcatenateStrings node) {
609 node.arguments.forEach(visitReference);
610 }
611
612 void visitBranch(Branch node) {
613 visit(node.condition);
614 }
615
616 void visitInvokeConstConstructor(InvokeConstConstructor node) {
617 node.arguments.forEach(visitReference);
618 }
619
620 void visitLiteralList(LiteralList node) {
621 node.values.forEach(visitReference);
622 }
623
624 void visitLiteralMap(LiteralMap node) {
625 for (int i = 0; i < node.keys.length; ++i) {
626 visitReference(node.keys[i]);
627 visitReference(node.values[i]);
628 }
629 }
630
631 void visitConstant(Constant node) {
632 }
633
634 void visitParameter(Parameter node) {
635 throw "Parameters should not be visited by RegisterAllocator";
636 }
637
638 void visitContinuation(Continuation node) {
639 visit(node.body);
640
641 // Arguments get allocated left-to-right, so we release parameters
642 // right-to-left. This increases the likelihood that arguments can be
643 // transferred without intermediate assignments.
644 for (int i = node.parameters.length - 1; i >= 0; --i) {
645 release(node.parameters[i]);
646 }
647 }
648
649 void visitIsTrue(IsTrue node) {
650 visitReference(node.value);
651 }
652
653 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698