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

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

Issue 958603002: Added VariableUse expression to tree IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 Variable addMutableVariable(cps_ir.MutableVariable irVariable) { 75 Variable addMutableVariable(cps_ir.MutableVariable irVariable) {
76 if (irVariable.host != currentElement) { 76 if (irVariable.host != currentElement) {
77 return parent.addMutableVariable(irVariable); 77 return parent.addMutableVariable(irVariable);
78 } 78 }
79 assert(!local2mutable.containsKey(irVariable)); 79 assert(!local2mutable.containsKey(irVariable));
80 Variable variable = new Variable(currentElement, irVariable.hint); 80 Variable variable = new Variable(currentElement, irVariable.hint);
81 local2mutable[irVariable] = variable; 81 local2mutable[irVariable] = variable;
82 return variable; 82 return variable;
83 } 83 }
84 84
85 Variable getMutableVariableReference( 85 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) {
86 if (mutableVariable.host != currentElement) {
87 return parent.getMutableVariable(mutableVariable);
88 }
89 return local2mutable[mutableVariable];
90 }
91
92 VariableUse getMutableVariableReference(
Kevin Millikin (Google) 2015/02/26 12:43:18 There's probably no good reason to use Reference i
asgerf 2015/02/27 12:05:19 Done.
86 cps_ir.Reference<cps_ir.MutableVariable> reference) { 93 cps_ir.Reference<cps_ir.MutableVariable> reference) {
87 if (reference.definition.host != currentElement) { 94 Variable variable = getMutableVariable(reference.definition);
88 return parent.getMutableVariableReference(reference); 95 return new VariableUse(variable);
89 }
90 Variable variable = local2mutable[reference.definition];
91 ++variable.readCount;
92 return variable;
93 } 96 }
94 97
95 /// Obtains the variable representing the given primitive. Returns null for 98 /// Obtains the variable representing the given primitive. Returns null for
96 /// primitives that have no reference and do not need a variable. 99 /// primitives that have no reference and do not need a variable.
97 Variable getVariable(cps_ir.Primitive primitive) { 100 Variable getVariable(cps_ir.Primitive primitive) {
98 if (primitive.registerIndex == null) { 101 if (primitive.registerIndex == null) {
99 return null; // variable is unused 102 return null; // variable is unused
100 } 103 }
101 List<Variable> variables = local2variables.putIfAbsent(primitive.hint, 104 List<Variable> variables = local2variables.putIfAbsent(primitive.hint,
102 () => <Variable>[]); 105 () => <Variable>[]);
103 while (variables.length <= primitive.registerIndex) { 106 while (variables.length <= primitive.registerIndex) {
104 variables.add(new Variable(currentElement, primitive.hint)); 107 variables.add(new Variable(currentElement, primitive.hint));
105 } 108 }
106 return variables[primitive.registerIndex]; 109 return variables[primitive.registerIndex];
107 } 110 }
108 111
109 /// Obtains a reference to the tree Variable corresponding to the IR primitive 112 /// Obtains a reference to the tree Variable corresponding to the IR primitive
110 /// referred to by [reference]. 113 /// referred to by [reference].
111 /// This increments the reference count for the given variable, so the 114 /// This increments the reference count for the given variable, so the
112 /// returned expression must be used in the tree. 115 /// returned expression must be used in the tree.
113 Expression getVariableReference(cps_ir.Reference reference) { 116 Expression getVariableReference(cps_ir.Reference reference) {
114 Variable variable = getVariable(reference.definition); 117 Variable variable = getVariable(reference.definition);
115 if (variable == null) { 118 if (variable == null) {
116 internalError( 119 internalError(
117 CURRENT_ELEMENT_SPANNABLE, 120 CURRENT_ELEMENT_SPANNABLE,
118 "Reference to ${reference.definition} has no register"); 121 "Reference to ${reference.definition} has no register");
119 } 122 }
120 ++variable.readCount; 123 return new VariableUse(variable);
121 return variable;
122 } 124 }
123 125
124 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { 126 ExecutableDefinition build(cps_ir.ExecutableDefinition node) {
125 if (node is cps_ir.FieldDefinition) { 127 if (node is cps_ir.FieldDefinition) {
126 return buildField(node); 128 return buildField(node);
127 } else if (node is cps_ir.ConstructorDefinition) { 129 } else if (node is cps_ir.ConstructorDefinition) {
128 return buildConstructor(node); 130 return buildConstructor(node);
129 } else { 131 } else {
130 assert(dart2js.invariant( 132 assert(dart2js.invariant(
131 CURRENT_ELEMENT_SPANNABLE, 133 CURRENT_ELEMENT_SPANNABLE,
(...skipping 20 matching lines...) Expand all
152 Variable addFunctionParameter(cps_ir.Definition variable) { 154 Variable addFunctionParameter(cps_ir.Definition variable) {
153 if (variable is cps_ir.Parameter) { 155 if (variable is cps_ir.Parameter) {
154 return getVariable(variable); 156 return getVariable(variable);
155 } else { 157 } else {
156 return addMutableVariable(variable as cps_ir.MutableVariable); 158 return addMutableVariable(variable as cps_ir.MutableVariable);
157 } 159 }
158 } 160 }
159 161
160 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { 162 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
161 currentElement = node.element; 163 currentElement = node.element;
162 List<Variable> parameters = <Variable>[]; 164 List<Variable> parameters =
163 for (cps_ir.Definition p in node.parameters) { 165 node.parameters.map(addFunctionParameter).toList();
164 Variable parameter = addFunctionParameter(p);
165 assert(parameter != null);
166 ++parameter.writeCount; // Being a parameter counts as a write.
167 parameters.add(parameter);
168 }
169
170 Statement body; 166 Statement body;
171 if (!node.isAbstract) { 167 if (!node.isAbstract) {
172 returnContinuation = node.body.returnContinuation; 168 returnContinuation = node.body.returnContinuation;
173 phiTempVar = new Variable(node.element, null); 169 phiTempVar = new Variable(node.element, null);
174 body = visit(node.body); 170 body = visit(node.body);
175 } 171 }
176 172
177 return new FunctionDefinition(node.element, parameters, 173 return new FunctionDefinition(node.element, parameters,
178 body, node.localConstants, node.defaultParameterValues); 174 body, node.localConstants, node.defaultParameterValues);
179 } 175 }
180 176
181 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { 177 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) {
182 currentElement = node.element; 178 currentElement = node.element;
183 List<Variable> parameters = <Variable>[]; 179 List<Variable> parameters =
184 for (cps_ir.Definition p in node.parameters) { 180 node.parameters.map(addFunctionParameter).toList();
185 Variable parameter = addFunctionParameter(p);
186 assert(parameter != null);
187 ++parameter.writeCount; // Being a parameter counts as a write.
188 parameters.add(parameter);
189 }
190 List<Initializer> initializers; 181 List<Initializer> initializers;
191 Statement body; 182 Statement body;
192 if (!node.isAbstract) { 183 if (!node.isAbstract) {
193 initializers = node.initializers.map(visit).toList(); 184 initializers = node.initializers.map(visit).toList();
194 returnContinuation = node.body.returnContinuation; 185 returnContinuation = node.body.returnContinuation;
195 186
196 phiTempVar = new Variable(node.element, null); 187 phiTempVar = new Variable(node.element, null);
197 body = visit(node.body); 188 body = visit(node.body);
198 } 189 }
199 190
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 } 255 }
265 List<int> list = rightHand[arg]; 256 List<int> list = rightHand[arg];
266 if (list == null) { 257 if (list == null) {
267 rightHand[arg] = list = <int>[]; 258 rightHand[arg] = list = <int>[];
268 } 259 }
269 list.add(i); 260 list.add(i);
270 } 261 }
271 262
272 Statement first, current; 263 Statement first, current;
273 void addAssignment(Variable dst, Variable src) { 264 void addAssignment(Variable dst, Variable src) {
274 ++src.readCount;
275 // `dst.writeCount` will be updated by the Assign constructor.
276 if (first == null) { 265 if (first == null) {
277 first = current = new Assign(dst, src, null); 266 first = current = new Assign(dst, new VariableUse(src), null);
278 } else { 267 } else {
279 current = current.next = new Assign(dst, src, null); 268 current = current.next = new Assign(dst, new VariableUse(src), null);
280 } 269 }
281 } 270 }
282 271
283 List<Variable> assignmentSrc = new List<Variable>(parameters.length); 272 List<Variable> assignmentSrc = new List<Variable>(parameters.length);
284 List<bool> done = new List<bool>(parameters.length); 273 List<bool> done = new List<bool>(parameters.length);
285 void visitAssignment(int i) { 274 void visitAssignment(int i) {
286 if (done[i] == true) { 275 if (done[i] == true) {
287 return; 276 return;
288 } 277 }
289 Variable param = getVariable(parameters[i]); 278 Variable param = getVariable(parameters[i]);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 Variable variable = addMutableVariable(node.variable); 436 Variable variable = addMutableVariable(node.variable);
448 Expression value = getVariableReference(node.value); 437 Expression value = getVariableReference(node.value);
449 return new Assign(variable, value, visit(node.body), isDeclaration: true); 438 return new Assign(variable, value, visit(node.body), isDeclaration: true);
450 } 439 }
451 440
452 Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) { 441 Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) {
453 return getMutableVariableReference(node.variable); 442 return getMutableVariableReference(node.variable);
454 } 443 }
455 444
456 Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) { 445 Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) {
457 Variable variable = getMutableVariableReference(node.variable); 446 Variable variable = getMutableVariable(node.variable.definition);
458 Expression value = getVariableReference(node.value); 447 Expression value = getVariableReference(node.value);
459 return new Assign(variable, value, visit(node.body)); 448 return new Assign(variable, value, visit(node.body));
460 } 449 }
461 450
462 Statement visitDeclareFunction(cps_ir.DeclareFunction node) { 451 Statement visitDeclareFunction(cps_ir.DeclareFunction node) {
463 Variable variable = addMutableVariable(node.variable); 452 Variable variable = addMutableVariable(node.variable);
464 FunctionDefinition function = makeSubFunction(node.definition); 453 FunctionDefinition function = makeSubFunction(node.definition);
465 return new FunctionDeclaration(variable, function, visit(node.body)); 454 return new FunctionDeclaration(variable, function, visit(node.body));
466 } 455 }
467 456
(...skipping 15 matching lines...) Expand all
483 // Invocations of the return continuation are translated to returns. 472 // Invocations of the return continuation are translated to returns.
484 // Other continuation invocations are replaced with assignments of the 473 // Other continuation invocations are replaced with assignments of the
485 // arguments to formal parameter variables, followed by the body if 474 // arguments to formal parameter variables, followed by the body if
486 // the continuation is singly reference or a break if it is multiply 475 // the continuation is singly reference or a break if it is multiply
487 // referenced. 476 // referenced.
488 cps_ir.Continuation cont = node.continuation.definition; 477 cps_ir.Continuation cont = node.continuation.definition;
489 if (cont == returnContinuation) { 478 if (cont == returnContinuation) {
490 assert(node.arguments.length == 1); 479 assert(node.arguments.length == 1);
491 return new Return(getVariableReference(node.arguments.single)); 480 return new Return(getVariableReference(node.arguments.single));
492 } else { 481 } else {
493 List<Expression> arguments = translatePhiArguments(node.arguments); 482 List<Variable> arguments = translatePhiArguments(node.arguments);
494 return buildPhiAssignments(cont.parameters, arguments, 483 return buildPhiAssignments(cont.parameters, arguments,
495 () { 484 () {
496 // Translate invocations of recursive and non-recursive 485 // Translate invocations of recursive and non-recursive
497 // continuations differently. 486 // continuations differently.
498 // * Non-recursive continuations 487 // * Non-recursive continuations
499 // - If there is one use, translate the continuation body 488 // - If there is one use, translate the continuation body
500 // inline at the invocation site. 489 // inline at the invocation site.
501 // - If there are multiple uses, translate to Break. 490 // - If there are multiple uses, translate to Break.
502 // * Recursive continuations 491 // * Recursive continuations
503 // - There is a single non-recursive invocation. Translate 492 // - There is a single non-recursive invocation. Translate
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 // visited. 578 // visited.
590 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); 579 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.');
591 return null; 580 return null;
592 } 581 }
593 582
594 Expression visitIsTrue(cps_ir.IsTrue node) { 583 Expression visitIsTrue(cps_ir.IsTrue node) {
595 return getVariableReference(node.value); 584 return getVariableReference(node.value);
596 } 585 }
597 } 586 }
598 587
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698