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

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

Issue 756383004: Refactored treatment of closure variables in dart2js CPS. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comments Created 6 years 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 * particular, intermediate values and blocks used for local control flow are 42 * particular, intermediate values and blocks used for local control flow are
43 * still all named. 43 * still all named.
44 */ 44 */
45 class Builder extends cps_ir.Visitor<Node> { 45 class Builder extends cps_ir.Visitor<Node> {
46 final dart2js.Compiler compiler; 46 final dart2js.Compiler compiler;
47 47
48 /// Maps variable/parameter elements to the Tree variables that represent it. 48 /// Maps variable/parameter elements to the Tree variables that represent it.
49 final Map<Element, List<Variable>> element2variables = 49 final Map<Element, List<Variable>> element2variables =
50 <Element,List<Variable>>{}; 50 <Element,List<Variable>>{};
51 51
52 /// Like [element2variables], except for closure variables. Closure variables 52 /// Like [element2variables], except for closure variables.
53 /// are not subject to SSA, so at most one variable is used per local. 53 final Map<cps_ir.ClosureVariable, Variable> local2closure =
54 final Map<Local, Variable> local2closure = <Local, Variable>{}; 54 <cps_ir.ClosureVariable, 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.compiler); 65 Builder(this.compiler);
66 66
67 Builder.inner(Builder parent) 67 Builder.inner(Builder parent)
68 : this.parent = parent, 68 : this.parent = parent,
69 compiler = parent.compiler; 69 compiler = parent.compiler;
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(Local local) { 75 Variable getClosureVariable(cps_ir.ClosureVariable irVariable) {
76 if (local.executableContext != currentElement) { 76 if (irVariable.host != currentElement) {
77 return parent.getClosureVariable(local); 77 return parent.getClosureVariable(irVariable);
78 } 78 }
79 Variable variable = local2closure[local]; 79 return local2closure.putIfAbsent(irVariable,
80 if (variable == null) { 80 () => new Variable(currentElement, irVariable.hint));
81 variable = new Variable(currentElement, local);
82 local2closure[local] = variable;
83 }
84 return variable;
85 } 81 }
86 82
87 /// Obtains the variable representing the given primitive. Returns null for 83 /// Obtains the variable representing the given primitive. Returns null for
88 /// primitives that have no reference and do not need a variable. 84 /// primitives that have no reference and do not need a variable.
89 Variable getVariable(cps_ir.Primitive primitive) { 85 Variable getVariable(cps_ir.Primitive primitive) {
90 if (primitive.registerIndex == null) { 86 if (primitive.registerIndex == null) {
91 return null; // variable is unused 87 return null; // variable is unused
92 } 88 }
93 List<Variable> variables = element2variables[primitive.hint]; 89 List<Variable> variables = element2variables.putIfAbsent(primitive.hint,
94 if (variables == null) { 90 () => <Variable>[]);
95 variables = <Variable>[];
96 element2variables[primitive.hint] = variables;
97 }
98 while (variables.length <= primitive.registerIndex) { 91 while (variables.length <= primitive.registerIndex) {
99 variables.add(new Variable(currentElement, primitive.hint)); 92 variables.add(new Variable(currentElement, primitive.hint));
100 } 93 }
101 return variables[primitive.registerIndex]; 94 return variables[primitive.registerIndex];
102 } 95 }
103 96
104 /// Obtains a reference to the tree Variable corresponding to the IR primitive 97 /// Obtains a reference to the tree Variable corresponding to the IR primitive
105 /// referred to by [reference]. 98 /// referred to by [reference].
106 /// This increments the reference count for the given variable, so the 99 /// This increments the reference count for the given variable, so the
107 /// returned expression must be used in the tree. 100 /// returned expression must be used in the tree.
(...skipping 23 matching lines...) Expand all
131 currentElement = node.element; 124 currentElement = node.element;
132 returnContinuation = node.returnContinuation; 125 returnContinuation = node.returnContinuation;
133 126
134 phiTempVar = new Variable(node.element, null); 127 phiTempVar = new Variable(node.element, null);
135 128
136 body = visit(node.body); 129 body = visit(node.body);
137 } 130 }
138 return new FieldDefinition(node.element, body); 131 return new FieldDefinition(node.element, body);
139 } 132 }
140 133
134 Variable getFunctionParameter(cps_ir.Definition variable) {
135 if (variable is cps_ir.Parameter) {
136 return getVariable(variable);
137 } else {
138 return getClosureVariable(variable as cps_ir.ClosureVariable);
139 }
140 }
141
141 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { 142 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
142 currentElement = node.element; 143 currentElement = node.element;
143 List<Variable> parameters = <Variable>[]; 144 List<Variable> parameters = <Variable>[];
144 for (cps_ir.Parameter p in node.parameters) { 145 for (cps_ir.Definition p in node.parameters) {
145 Variable parameter = getVariable(p); 146 Variable parameter = getFunctionParameter(p);
146 assert(parameter != null); 147 assert(parameter != null);
147 ++parameter.writeCount; // Being a parameter counts as a write. 148 ++parameter.writeCount; // Being a parameter counts as a write.
148 parameters.add(parameter); 149 parameters.add(parameter);
149 } 150 }
150 returnContinuation = node.returnContinuation; 151 returnContinuation = node.returnContinuation;
151 152
152 Statement body; 153 Statement body;
153 if (!node.isAbstract) { 154 if (!node.isAbstract) {
154 phiTempVar = new Variable(node.element, null); 155 phiTempVar = new Variable(node.element, null);
155 body = visit(node.body); 156 body = visit(node.body);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } else { 342 } else {
342 assert(cont.parameters.length == 1); 343 assert(cont.parameters.length == 1);
343 Function nextBuilder = cont.hasExactlyOneUse ? 344 Function nextBuilder = cont.hasExactlyOneUse ?
344 () => visit(cont.body) : () => new Break(labels[cont]); 345 () => visit(cont.body) : () => new Break(labels[cont]);
345 return buildContinuationAssignment(cont.parameters.single, expression, 346 return buildContinuationAssignment(cont.parameters.single, expression,
346 nextBuilder); 347 nextBuilder);
347 } 348 }
348 } 349 }
349 350
350 Expression visitGetClosureVariable(cps_ir.GetClosureVariable node) { 351 Expression visitGetClosureVariable(cps_ir.GetClosureVariable node) {
351 return getClosureVariable(node.variable); 352 return getClosureVariable(node.variable.definition);
352 } 353 }
353 354
354 Statement visitSetClosureVariable(cps_ir.SetClosureVariable node) { 355 Statement visitSetClosureVariable(cps_ir.SetClosureVariable node) {
355 Variable variable = getClosureVariable(node.variable); 356 Variable variable = getClosureVariable(node.variable.definition);
356 Expression value = getVariableReference(node.value); 357 Expression value = getVariableReference(node.value);
357 return new Assign(variable, value, visit(node.body), 358 return new Assign(variable, value, visit(node.body),
358 isDeclaration: node.isDeclaration); 359 isDeclaration: node.isDeclaration);
359 } 360 }
360 361
361 Statement visitDeclareFunction(cps_ir.DeclareFunction node) { 362 Statement visitDeclareFunction(cps_ir.DeclareFunction node) {
362 Variable variable = getClosureVariable(node.variable); 363 Variable variable = getClosureVariable(node.variable.definition);
363 FunctionDefinition function = makeSubFunction(node.definition); 364 FunctionDefinition function = makeSubFunction(node.definition);
364 return new FunctionDeclaration(variable, function, visit(node.body)); 365 return new FunctionDeclaration(variable, function, visit(node.body));
365 } 366 }
366 367
367 Statement visitTypeOperator(cps_ir.TypeOperator node) { 368 Statement visitTypeOperator(cps_ir.TypeOperator node) {
368 Expression receiver = getVariableReference(node.receiver); 369 Expression receiver = getVariableReference(node.receiver);
369 Expression concat = 370 Expression concat =
370 new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest); 371 new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest);
371 return continueWithExpression(node.continuation, concat); 372 return continueWithExpression(node.continuation, concat);
372 } 373 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 501
501 Expression visitIdentical(cps_ir.Identical node) { 502 Expression visitIdentical(cps_ir.Identical node) {
502 return new InvokeStatic( 503 return new InvokeStatic(
503 compiler.identicalFunction, 504 compiler.identicalFunction,
504 identicalSelector, 505 identicalSelector,
505 <Expression>[getVariableReference(node.left), 506 <Expression>[getVariableReference(node.left),
506 getVariableReference(node.right)]); 507 getVariableReference(node.right)]);
507 } 508 }
508 } 509 }
509 510
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698