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

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

Issue 759193005: Add support for fields to the new dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
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. Closure variables
53 /// are not subject to SSA, so at most one variable is used per local. 53 /// are not subject to SSA, so at most one variable is used per local.
54 final Map<Local, Variable> local2closure = <Local, Variable>{}; 54 final Map<Local, Variable> local2closure = <Local, 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 FunctionDefinition function; 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(Local local) {
76 if (local.executableContext != function.element) { 76 if (local.executableContext != currentElement) {
77 return parent.getClosureVariable(local); 77 return parent.getClosureVariable(local);
78 } 78 }
79 Variable variable = local2closure[local]; 79 Variable variable = local2closure[local];
80 if (variable == null) { 80 if (variable == null) {
81 variable = new Variable(function, local); 81 variable = new Variable(currentElement, local);
82 local2closure[local] = variable; 82 local2closure[local] = variable;
83 } 83 }
84 return variable; 84 return variable;
85 } 85 }
86 86
87 /// Obtains the variable representing the given primitive. Returns null for 87 /// Obtains the variable representing the given primitive. Returns null for
88 /// primitives that have no reference and do not need a variable. 88 /// primitives that have no reference and do not need a variable.
89 Variable getVariable(cps_ir.Primitive primitive) { 89 Variable getVariable(cps_ir.Primitive primitive) {
90 if (primitive.registerIndex == null) { 90 if (primitive.registerIndex == null) {
91 return null; // variable is unused 91 return null; // variable is unused
92 } 92 }
93 List<Variable> variables = element2variables[primitive.hint]; 93 List<Variable> variables = element2variables[primitive.hint];
94 if (variables == null) { 94 if (variables == null) {
95 variables = <Variable>[]; 95 variables = <Variable>[];
96 element2variables[primitive.hint] = variables; 96 element2variables[primitive.hint] = variables;
97 } 97 }
98 while (variables.length <= primitive.registerIndex) { 98 while (variables.length <= primitive.registerIndex) {
99 variables.add(new Variable(function, primitive.hint)); 99 variables.add(new Variable(currentElement, primitive.hint));
100 } 100 }
101 return variables[primitive.registerIndex]; 101 return variables[primitive.registerIndex];
102 } 102 }
103 103
104 /// Obtains a reference to the tree Variable corresponding to the IR primitive 104 /// Obtains a reference to the tree Variable corresponding to the IR primitive
105 /// referred to by [reference]. 105 /// referred to by [reference].
106 /// This increments the reference count for the given variable, so the 106 /// This increments the reference count for the given variable, so the
107 /// returned expression must be used in the tree. 107 /// returned expression must be used in the tree.
108 Expression getVariableReference(cps_ir.Reference reference) { 108 Expression getVariableReference(cps_ir.Reference reference) {
109 Variable variable = getVariable(reference.definition); 109 Variable variable = getVariable(reference.definition);
110 if (variable == null) { 110 if (variable == null) {
111 compiler.internalError( 111 compiler.internalError(
112 compiler.currentElement, 112 compiler.currentElement,
113 "Reference to ${reference.definition} has no register"); 113 "Reference to ${reference.definition} has no register");
114 } 114 }
115 ++variable.readCount; 115 ++variable.readCount;
116 return variable; 116 return variable;
117 } 117 }
118 118
119 FunctionDefinition build(cps_ir.FunctionDefinition node) { 119 ExecutableDefinition build(cps_ir.ExecutableDefinition node) {
120 visit(node); 120 if (node is cps_ir.FieldDefinition) {
121 return function; 121 return buildField(node);
122 } else if (node is cps_ir.FunctionDefinition) {
123 return buildFunction(node);
124 }
125 assert(false);
126 }
127
128 FieldDefinition buildField(cps_ir.FieldDefinition node) {
129 currentElement = node.element;
130 returnContinuation = node.returnContinuation;
131
132 phiTempVar = new Variable(node.element, null);
133
134 return new FieldDefinition(node.element, visit(node.body));
135 }
136
137 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
138 currentElement = node.element;
139 List<Variable> parameters = <Variable>[];
140 for (cps_ir.Parameter p in node.parameters) {
141 Variable parameter = getVariable(p);
142 assert(parameter != null);
143 ++parameter.writeCount; // Being a parameter counts as a write.
144 parameters.add(parameter);
145 }
146 returnContinuation = node.returnContinuation;
147
148 Statement body;
149 if (!node.isAbstract) {
150 phiTempVar = new Variable(node.element, null);
151 body = visit(node.body);
152 }
153
154 return new FunctionDefinition(node.element, parameters,
155 body, node.localConstants, node.defaultParameterValues);
122 } 156 }
123 157
124 List<Expression> translateArguments(List<cps_ir.Reference> args) { 158 List<Expression> translateArguments(List<cps_ir.Reference> args) {
125 return new List<Expression>.generate(args.length, 159 return new List<Expression>.generate(args.length,
126 (int index) => getVariableReference(args[index])); 160 (int index) => getVariableReference(args[index]));
127 } 161 }
128 162
129 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) { 163 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) {
130 return new List<Variable>.generate(args.length, 164 return new List<Variable>.generate(args.length,
131 (int index) => getVariableReference(args[index])); 165 (int index) => getVariableReference(args[index]));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 if (first == null) { 259 if (first == null) {
226 first = buildRest(); 260 first = buildRest();
227 } else { 261 } else {
228 current.next = buildRest(); 262 current.next = buildRest();
229 } 263 }
230 return first; 264 return first;
231 } 265 }
232 266
233 visitNode(cps_ir.Node node) => throw "Unhandled node: $node"; 267 visitNode(cps_ir.Node node) => throw "Unhandled node: $node";
234 268
235 Expression visitFunctionDefinition(cps_ir.FunctionDefinition node) {
236 List<Variable> parameters = <Variable>[];
237 function = new FunctionDefinition(node.element, parameters,
238 null, node.localConstants, node.defaultParameterValues);
239 returnContinuation = node.returnContinuation;
240 for (cps_ir.Parameter p in node.parameters) {
241 Variable parameter = getVariable(p);
242 assert(parameter != null);
243 ++parameter.writeCount; // Being a parameter counts as a write.
244 parameters.add(parameter);
245 }
246 if (!node.isAbstract) {
247 phiTempVar = new Variable(function, null);
248 function.body = visit(node.body);
249 }
250 return null;
251 }
252
253 Statement visitLetPrim(cps_ir.LetPrim node) { 269 Statement visitLetPrim(cps_ir.LetPrim node) {
254 Variable variable = getVariable(node.primitive); 270 Variable variable = getVariable(node.primitive);
255 271
256 // Don't translate unused primitives. 272 // Don't translate unused primitives.
257 if (variable == null) return visit(node.body); 273 if (variable == null) return visit(node.body);
258 274
259 Node definition = visit(node.primitive); 275 Node definition = visit(node.primitive);
260 276
261 // visitPrimitive returns a Statement without successor if it cannot occur 277 // visitPrimitive returns a Statement without successor if it cannot occur
262 // in expression context (currently only the case for FunctionDeclarations). 278 // in expression context (currently only the case for FunctionDeclarations).
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 node.type, 449 node.type,
434 new List<LiteralMapEntry>.generate(node.entries.length, (int index) { 450 new List<LiteralMapEntry>.generate(node.entries.length, (int index) {
435 return new LiteralMapEntry( 451 return new LiteralMapEntry(
436 getVariableReference(node.entries[index].key), 452 getVariableReference(node.entries[index].key),
437 getVariableReference(node.entries[index].value)); 453 getVariableReference(node.entries[index].value));
438 }) 454 })
439 ); 455 );
440 } 456 }
441 457
442 FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) { 458 FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) {
443 return new Builder.inner(this).build(function); 459 return new Builder.inner(this).buildFunction(function);
444 } 460 }
445 461
446 Node visitCreateFunction(cps_ir.CreateFunction node) { 462 Node visitCreateFunction(cps_ir.CreateFunction node) {
447 FunctionDefinition def = makeSubFunction(node.definition); 463 FunctionDefinition def = makeSubFunction(node.definition);
448 FunctionType type = node.definition.element.type; 464 FunctionType type = node.definition.element.type;
449 bool hasReturnType = !type.returnType.treatAsDynamic; 465 bool hasReturnType = !type.returnType.treatAsDynamic;
450 if (hasReturnType) { 466 if (hasReturnType) {
451 // This function cannot occur in expression context. 467 // This function cannot occur in expression context.
452 // The successor will be filled in by visitLetPrim. 468 // The successor will be filled in by visitLetPrim.
453 return new FunctionDeclaration(getVariable(node), def, null); 469 return new FunctionDeclaration(getVariable(node), def, null);
(...skipping 26 matching lines...) Expand all
480 496
481 Expression visitIdentical(cps_ir.Identical node) { 497 Expression visitIdentical(cps_ir.Identical node) {
482 return new InvokeStatic( 498 return new InvokeStatic(
483 compiler.identicalFunction, 499 compiler.identicalFunction,
484 identicalSelector, 500 identicalSelector,
485 <Expression>[getVariableReference(node.left), 501 <Expression>[getVariableReference(node.left),
486 getVariableReference(node.right)]); 502 getVariableReference(node.right)]);
487 } 503 }
488 } 504 }
489 505
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698