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

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

Issue 898463002: Rename ClosureVariable, use separate IR forms for declaration and assignment. (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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 extends cps_ir.Visitor<Node> { 46 class Builder extends 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 /// Maps variable/parameter elements to the Tree variables that represent it.
50 final Map<Local, List<Variable>> local2variables = <Local, List<Variable>>{}; 50 final Map<Local, List<Variable>> local2variables = <Local, List<Variable>>{};
51 51
52 /// Like [local2variables], except for closure variables. 52 /// Like [local2variables], except for mutable variables.
53 final Map<cps_ir.ClosureVariable, Variable> local2closure = 53 final Map<cps_ir.MutableVariable, Variable> local2mutable =
karlklose 2015/02/03 09:56:16 I would really like to get rid of this naming conv
Kevin Millikin (Google) 2015/02/03 14:11:49 Concrete suggestions for naming maps? Name them a
54 <cps_ir.ClosureVariable, Variable>{}; 54 <cps_ir.MutableVariable, Variable>{};
55 55
56 // Continuations with more than one use are replaced with Tree labels. This 56 // Continuations with more than one use are replaced with Tree labels. This
57 // is the mapping from continuations to labels. 57 // is the mapping from continuations to labels.
58 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{}; 58 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
59 59
60 ExecutableElement currentElement; 60 ExecutableElement currentElement;
61 cps_ir.Continuation returnContinuation; 61 cps_ir.Continuation returnContinuation;
62 62
63 Builder parent; 63 Builder parent;
64 64
65 Builder(this.internalError, [this.parent]); 65 Builder(this.internalError, [this.parent]);
66 66
67 Builder createInnerBuilder() { 67 Builder createInnerBuilder() {
68 return new Builder(internalError, this); 68 return new Builder(internalError, this);
69 } 69 }
70 70
71 /// Variable used in [buildPhiAssignments] as a temporary when swapping 71 /// Variable used in [buildPhiAssignments] as a temporary when swapping
72 /// variables. 72 /// variables.
73 Variable phiTempVar; 73 Variable phiTempVar;
74 74
75 Variable getClosureVariable(cps_ir.ClosureVariable irVariable) { 75 Variable addMutableVariable(cps_ir.MutableVariable irVariable) {
76 if (irVariable.host != currentElement) { 76 if (irVariable.host != currentElement) {
77 return parent.getClosureVariable(irVariable); 77 return parent.addMutableVariable(irVariable);
78 } 78 }
79 return local2closure.putIfAbsent(irVariable, 79 assert(!local2mutable.containsKey(irVariable));
80 () => new Variable(currentElement, irVariable.hint)); 80 Variable variable = new Variable(currentElement, irVariable.hint);
81 local2mutable[irVariable] = variable;
82 return variable;
83 }
84
85 Variable getMutableVariableReference(
86 cps_ir.Reference<cps_ir.MutableVariable> reference) {
87 if (reference.definition.host != currentElement) {
88 return parent.getMutableVariableReference(reference);
89 }
90 return local2mutable[reference.definition];
81 } 91 }
82 92
83 /// Obtains the variable representing the given primitive. Returns null for 93 /// Obtains the variable representing the given primitive. Returns null for
84 /// primitives that have no reference and do not need a variable. 94 /// primitives that have no reference and do not need a variable.
85 Variable getVariable(cps_ir.Primitive primitive) { 95 Variable getVariable(cps_ir.Primitive primitive) {
86 if (primitive.registerIndex == null) { 96 if (primitive.registerIndex == null) {
87 return null; // variable is unused 97 return null; // variable is unused
88 } 98 }
89 List<Variable> variables = local2variables.putIfAbsent(primitive.hint, 99 List<Variable> variables = local2variables.putIfAbsent(primitive.hint,
90 () => <Variable>[]); 100 () => <Variable>[]);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 currentElement = node.element; 140 currentElement = node.element;
131 returnContinuation = node.body.returnContinuation; 141 returnContinuation = node.body.returnContinuation;
132 142
133 phiTempVar = new Variable(node.element, null); 143 phiTempVar = new Variable(node.element, null);
134 144
135 body = visit(node.body); 145 body = visit(node.body);
136 } 146 }
137 return new FieldDefinition(node.element, body); 147 return new FieldDefinition(node.element, body);
138 } 148 }
139 149
140 Variable getFunctionParameter(cps_ir.Definition variable) { 150 Variable addFunctionParameter(cps_ir.Definition variable) {
141 if (variable is cps_ir.Parameter) { 151 if (variable is cps_ir.Parameter) {
142 return getVariable(variable); 152 return getVariable(variable);
143 } else { 153 } else {
144 return getClosureVariable(variable as cps_ir.ClosureVariable); 154 return addMutableVariable(variable as cps_ir.MutableVariable);
145 } 155 }
146 } 156 }
147 157
148 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { 158 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
149 currentElement = node.element; 159 currentElement = node.element;
150 List<Variable> parameters = <Variable>[]; 160 List<Variable> parameters = <Variable>[];
151 for (cps_ir.Definition p in node.parameters) { 161 for (cps_ir.Definition p in node.parameters) {
152 Variable parameter = getFunctionParameter(p); 162 Variable parameter = addFunctionParameter(p);
153 assert(parameter != null); 163 assert(parameter != null);
154 ++parameter.writeCount; // Being a parameter counts as a write. 164 ++parameter.writeCount; // Being a parameter counts as a write.
155 parameters.add(parameter); 165 parameters.add(parameter);
156 } 166 }
157 167
158 Statement body; 168 Statement body;
159 if (!node.isAbstract) { 169 if (!node.isAbstract) {
160 returnContinuation = node.body.returnContinuation; 170 returnContinuation = node.body.returnContinuation;
161 phiTempVar = new Variable(node.element, null); 171 phiTempVar = new Variable(node.element, null);
162 body = visit(node.body); 172 body = visit(node.body);
163 } 173 }
164 174
165 return new FunctionDefinition(node.element, parameters, 175 return new FunctionDefinition(node.element, parameters,
166 body, node.localConstants, node.defaultParameterValues); 176 body, node.localConstants, node.defaultParameterValues);
167 } 177 }
168 178
169 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { 179 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) {
170 currentElement = node.element; 180 currentElement = node.element;
171 List<Variable> parameters = <Variable>[]; 181 List<Variable> parameters = <Variable>[];
172 for (cps_ir.Definition p in node.parameters) { 182 for (cps_ir.Definition p in node.parameters) {
173 Variable parameter = getFunctionParameter(p); 183 Variable parameter = addFunctionParameter(p);
174 assert(parameter != null); 184 assert(parameter != null);
175 ++parameter.writeCount; // Being a parameter counts as a write. 185 ++parameter.writeCount; // Being a parameter counts as a write.
176 parameters.add(parameter); 186 parameters.add(parameter);
177 } 187 }
178 List<Initializer> initializers; 188 List<Initializer> initializers;
179 Statement body; 189 Statement body;
180 if (!node.isAbstract) { 190 if (!node.isAbstract) {
181 initializers = node.initializers.map(visit).toList(); 191 initializers = node.initializers.map(visit).toList();
182 returnContinuation = node.body.returnContinuation; 192 returnContinuation = node.body.returnContinuation;
183 193
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 return new Return(expression); 434 return new Return(expression);
425 } else { 435 } else {
426 assert(cont.parameters.length == 1); 436 assert(cont.parameters.length == 1);
427 Function nextBuilder = cont.hasExactlyOneUse ? 437 Function nextBuilder = cont.hasExactlyOneUse ?
428 () => visit(cont.body) : () => new Break(labels[cont]); 438 () => visit(cont.body) : () => new Break(labels[cont]);
429 return buildContinuationAssignment(cont.parameters.single, expression, 439 return buildContinuationAssignment(cont.parameters.single, expression,
430 nextBuilder); 440 nextBuilder);
431 } 441 }
432 } 442 }
433 443
434 Expression visitGetClosureVariable(cps_ir.GetClosureVariable node) { 444 Statement visitLetMutable(cps_ir.LetMutable node) {
435 return getClosureVariable(node.variable.definition); 445 Variable variable = addMutableVariable(node.variable);
446 Expression value = getVariableReference(node.value);
447 return new Assign(variable, value, visit(node.body), isDeclaration: true);
436 } 448 }
437 449
438 Statement visitSetClosureVariable(cps_ir.SetClosureVariable node) { 450 Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) {
439 Variable variable = getClosureVariable(node.variable.definition); 451 return getMutableVariableReference(node.variable);
452 }
453
454 Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) {
455 Variable variable = getMutableVariableReference(node.variable);
440 Expression value = getVariableReference(node.value); 456 Expression value = getVariableReference(node.value);
441 return new Assign(variable, value, visit(node.body), 457 return new Assign(variable, value, visit(node.body));
442 isDeclaration: node.isDeclaration);
443 } 458 }
444 459
445 Statement visitDeclareFunction(cps_ir.DeclareFunction node) { 460 Statement visitDeclareFunction(cps_ir.DeclareFunction node) {
446 Variable variable = getClosureVariable(node.variable.definition); 461 Variable variable = addMutableVariable(node.variable);
447 FunctionDefinition function = makeSubFunction(node.definition); 462 FunctionDefinition function = makeSubFunction(node.definition);
448 return new FunctionDeclaration(variable, function, visit(node.body)); 463 return new FunctionDeclaration(variable, function, visit(node.body));
449 } 464 }
450 465
451 Statement visitTypeOperator(cps_ir.TypeOperator node) { 466 Statement visitTypeOperator(cps_ir.TypeOperator node) {
452 Expression receiver = getVariableReference(node.receiver); 467 Expression receiver = getVariableReference(node.receiver);
453 Expression concat = 468 Expression concat =
454 new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest); 469 new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest);
455 return continueWithExpression(node.continuation, concat); 470 return continueWithExpression(node.continuation, concat);
456 } 471 }
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 // visited. 587 // visited.
573 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); 588 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.');
574 return null; 589 return null;
575 } 590 }
576 591
577 Expression visitIsTrue(cps_ir.IsTrue node) { 592 Expression visitIsTrue(cps_ir.IsTrue node) {
578 return getVariableReference(node.value); 593 return getVariableReference(node.value);
579 } 594 }
580 } 595 }
581 596
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698