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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart

Issue 1007103003: cps-ir: Merge variables based on set-based liveness and graph coloring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Missed a few comments Created 5 years, 8 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library tree_ir_builder; 5 library tree_ir_builder;
6 6
7 import '../dart2jslib.dart' as dart2js; 7 import '../dart2jslib.dart' as dart2js;
8 import '../dart_types.dart'; 8 import '../dart_types.dart';
9 import '../elements/elements.dart'; 9 import '../elements/elements.dart';
10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; 10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
(...skipping 28 matching lines...) Expand all
39 * translation out of SSA. Jumps are eliminated during the Tree-to-Tree 39 * translation out of SSA. Jumps are eliminated during the Tree-to-Tree
40 * control-flow recognition. 40 * control-flow recognition.
41 * 41 *
42 * Otherwise, the output of Builder looks very much like the input. In 42 * Otherwise, the output of Builder looks very much like the input. In
43 * particular, intermediate values and blocks used for local control flow are 43 * particular, intermediate values and blocks used for local control flow are
44 * still all named. 44 * still all named.
45 */ 45 */
46 class Builder implements cps_ir.Visitor<Node> { 46 class Builder implements cps_ir.Visitor<Node> {
47 final dart2js.InternalErrorFunction internalError; 47 final dart2js.InternalErrorFunction internalError;
48 48
49 /// Maps variable/parameter elements to the Tree variables that represent it. 49 final Map<cps_ir.Primitive, Variable> primitive2variable =
50 final Map<Local, List<Variable>> local2variables = <Local, List<Variable>>{}; 50 <cps_ir.Primitive, Variable>{};
51 51 final Map<cps_ir.MutableVariable, Variable> mutable2variable =
52 /// Like [local2variables], except for mutable variables.
53 final Map<cps_ir.MutableVariable, Variable> local2mutable =
54 <cps_ir.MutableVariable, Variable>{}; 52 <cps_ir.MutableVariable, Variable>{};
55 53
56 // Continuations with more than one use are replaced with Tree labels. This 54 // Continuations with more than one use are replaced with Tree labels. This
57 // is the mapping from continuations to labels. 55 // is the mapping from continuations to labels.
58 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{}; 56 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
59 57
60 /// A stack of singly-used labels that can be safely inlined at their use 58 /// A stack of singly-used labels that can be safely inlined at their use
61 /// site. 59 /// site.
62 /// 60 ///
63 /// Code for continuations with exactly one use is inlined at the use site. 61 /// Code for continuations with exactly one use is inlined at the use site.
(...skipping 12 matching lines...) Expand all
76 Builder createInnerBuilder() { 74 Builder createInnerBuilder() {
77 return new Builder(internalError, this); 75 return new Builder(internalError, this);
78 } 76 }
79 77
80 /// Variable used in [buildPhiAssignments] as a temporary when swapping 78 /// Variable used in [buildPhiAssignments] as a temporary when swapping
81 /// variables. 79 /// variables.
82 Variable phiTempVar; 80 Variable phiTempVar;
83 81
84 Variable addMutableVariable(cps_ir.MutableVariable irVariable) { 82 Variable addMutableVariable(cps_ir.MutableVariable irVariable) {
85 assert(irVariable.host == currentElement); 83 assert(irVariable.host == currentElement);
86 assert(!local2mutable.containsKey(irVariable)); 84 assert(!mutable2variable.containsKey(irVariable));
87 Variable variable = new Variable(currentElement, irVariable.hint); 85 Variable variable = new Variable(currentElement, irVariable.hint);
88 local2mutable[irVariable] = variable; 86 mutable2variable[irVariable] = variable;
89 return variable; 87 return variable;
90 } 88 }
91 89
92 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) { 90 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) {
93 if (mutableVariable.host != currentElement) { 91 if (mutableVariable.host != currentElement) {
94 return parent.getMutableVariable(mutableVariable)..isCaptured = true; 92 return parent.getMutableVariable(mutableVariable)..isCaptured = true;
95 } 93 }
96 return local2mutable[mutableVariable]; 94 return mutable2variable[mutableVariable];
97 } 95 }
98 96
99 VariableUse getMutableVariableUse( 97 VariableUse getMutableVariableUse(
100 cps_ir.Reference<cps_ir.MutableVariable> reference) { 98 cps_ir.Reference<cps_ir.MutableVariable> reference) {
101 Variable variable = getMutableVariable(reference.definition); 99 Variable variable = getMutableVariable(reference.definition);
102 return new VariableUse(variable); 100 return new VariableUse(variable);
103 } 101 }
104 102
105 /// Obtains the variable representing the given primitive. Returns null for 103 /// Obtains the variable representing the given primitive. Returns null for
106 /// primitives that have no reference and do not need a variable. 104 /// primitives that have no reference and do not need a variable.
107 Variable getVariable(cps_ir.Primitive primitive) { 105 Variable getVariable(cps_ir.Primitive primitive) {
108 if (primitive.registerIndex == null) { 106 return primitive2variable.putIfAbsent(primitive,
109 return null; // variable is unused 107 () => new Variable(currentElement, primitive.hint));
110 }
111 List<Variable> variables = local2variables.putIfAbsent(primitive.hint,
112 () => <Variable>[]);
113 while (variables.length <= primitive.registerIndex) {
114 variables.add(new Variable(currentElement, primitive.hint));
115 }
116 return variables[primitive.registerIndex];
117 } 108 }
118 109
119 /// Obtains a reference to the tree Variable corresponding to the IR primitive 110 /// Obtains a reference to the tree Variable corresponding to the IR primitive
120 /// referred to by [reference]. 111 /// referred to by [reference].
121 /// This increments the reference count for the given variable, so the 112 /// This increments the reference count for the given variable, so the
122 /// returned expression must be used in the tree. 113 /// returned expression must be used in the tree.
123 VariableUse getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { 114 VariableUse getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) {
124 Variable variable = getVariable(reference.definition); 115 return new VariableUse(getVariable(reference.definition));
125 if (variable == null) {
126 // Note: this may fail because you forgot to implement a visit-function
127 // in the RegisterAllocator.
128 internalError(
129 CURRENT_ELEMENT_SPANNABLE,
130 "Reference to ${reference.definition} has no register");
131 }
132 return new VariableUse(variable);
133 } 116 }
134 117
135 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { 118 ExecutableDefinition build(cps_ir.ExecutableDefinition node) {
119 // TODO(asgerf): Don't have build AND buildXXX as public API.
136 if (node is cps_ir.FieldDefinition) { 120 if (node is cps_ir.FieldDefinition) {
137 return buildField(node); 121 return buildField(node);
138 } else if (node is cps_ir.ConstructorDefinition) { 122 } else if (node is cps_ir.ConstructorDefinition) {
139 return buildConstructor(node); 123 return buildConstructor(node);
140 } else { 124 } else {
141 assert(dart2js.invariant( 125 assert(dart2js.invariant(
142 CURRENT_ELEMENT_SPANNABLE, 126 CURRENT_ELEMENT_SPANNABLE,
143 node is cps_ir.FunctionDefinition, 127 node is cps_ir.FunctionDefinition,
144 message: 'expected FunctionDefinition or FieldDefinition, ' 128 message: 'expected FunctionDefinition or FieldDefinition, '
145 ' found $node')); 129 ' found $node'));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) { 206 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) {
223 return new List<Variable>.generate(args.length, 207 return new List<Variable>.generate(args.length,
224 (int index) => getVariable(args[index].definition), 208 (int index) => getVariable(args[index].definition),
225 growable: false); 209 growable: false);
226 } 210 }
227 211
228 Statement buildContinuationAssignment( 212 Statement buildContinuationAssignment(
229 cps_ir.Parameter parameter, 213 cps_ir.Parameter parameter,
230 Expression argument, 214 Expression argument,
231 Statement buildRest()) { 215 Statement buildRest()) {
232 Variable variable = getVariable(parameter);
233 Statement assignment; 216 Statement assignment;
234 if (variable == null) { 217 if (parameter.hasAtLeastOneUse) {
218 Variable variable = getVariable(parameter);
219 assignment = new Assign(variable, argument, null);
220 } else {
235 assignment = new ExpressionStatement(argument, null); 221 assignment = new ExpressionStatement(argument, null);
236 } else {
237 assignment = new Assign(variable, argument, null);
238 } 222 }
239 assignment.next = buildRest(); 223 assignment.next = buildRest();
240 return assignment; 224 return assignment;
241 } 225 }
242 226
243 /// Simultaneously assigns each argument to the corresponding parameter, 227 /// Simultaneously assigns each argument to the corresponding parameter,
244 /// then continues at the statement created by [buildRest]. 228 /// then continues at the statement created by [buildRest].
245 Statement buildPhiAssignments( 229 Statement buildPhiAssignments(
246 List<cps_ir.Parameter> parameters, 230 List<cps_ir.Parameter> parameters,
247 List<Variable> arguments, 231 List<Variable> arguments,
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 } 624 }
641 625
642 Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) { 626 Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
643 return new ReifyRuntimeType(getVariableUse(node.value)); 627 return new ReifyRuntimeType(getVariableUse(node.value));
644 } 628 }
645 629
646 Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) { 630 Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
647 return new ReadTypeVariable(node.variable, getVariableUse(node.target)); 631 return new ReadTypeVariable(node.variable, getVariableUse(node.target));
648 } 632 }
649 } 633 }
634
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698