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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart

Issue 312793002: dart2dart: Preserve variable names throughout the IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: SVN rebase Created 6 years, 6 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import 'ir_nodes.dart' as ir; 7 import 'ir_nodes.dart' as ir;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../dart2jslib.dart'; 9 import '../dart2jslib.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 // list of references. When the delimited subexpression is plugged into the 185 // list of references. When the delimited subexpression is plugged into the
186 // surrounding context, the free occurrences can be captured or become free 186 // surrounding context, the free occurrences can be captured or become free
187 // occurrences in the next outer delimited subexpression. 187 // occurrences in the next outer delimited subexpression.
188 // 188 //
189 // Each nested visitor maintains a list that maps indexes of variables 189 // Each nested visitor maintains a list that maps indexes of variables
190 // assigned in the delimited subexpression to their reaching definition --- 190 // assigned in the delimited subexpression to their reaching definition ---
191 // that is, the definition in effect at the hole in 'current'. These are 191 // that is, the definition in effect at the hole in 'current'. These are
192 // used to determine if a join-point continuation needs to be passed 192 // used to determine if a join-point continuation needs to be passed
193 // arguments, and what the arguments are. 193 // arguments, and what the arguments are.
194 final Map<Element, int> variableIndex; 194 final Map<Element, int> variableIndex;
195 final List<Element> index2variable;
195 final List<ir.Parameter> freeVars; 196 final List<ir.Parameter> freeVars;
196 final List<ir.Primitive> assignedVars; 197 final List<ir.Primitive> assignedVars;
197 198
198 /// Construct a top-level visitor. 199 /// Construct a top-level visitor.
199 IrBuilder(TreeElements elements, Compiler compiler, this.sourceFile) 200 IrBuilder(TreeElements elements, Compiler compiler, this.sourceFile)
200 : returnContinuation = new ir.Continuation.retrn(), 201 : returnContinuation = new ir.Continuation.retrn(),
201 parameters = <ir.Parameter>[], 202 parameters = <ir.Parameter>[],
202 variableIndex = <Element, int>{}, 203 variableIndex = <Element, int>{},
203 freeVars = null, 204 freeVars = null,
204 assignedVars = <ir.Primitive>[], 205 assignedVars = <ir.Primitive>[],
206 index2variable = <Element>[],
205 super(elements, compiler); 207 super(elements, compiler);
206 208
207 /// Construct a delimited visitor. 209 /// Construct a delimited visitor.
208 IrBuilder.delimited(IrBuilder parent) 210 IrBuilder.delimited(IrBuilder parent)
209 : sourceFile = parent.sourceFile, 211 : sourceFile = parent.sourceFile,
210 returnContinuation = parent.returnContinuation, 212 returnContinuation = parent.returnContinuation,
211 parameters = parent.parameters, 213 parameters = parent.parameters,
212 variableIndex = parent.variableIndex, 214 variableIndex = parent.variableIndex,
213 freeVars = new List<ir.Parameter>.generate( 215 freeVars = new List<ir.Parameter>.generate(
214 parent.assignedVars.length, (_) => new ir.Parameter(null), 216 parent.assignedVars.length, (_) => new ir.Parameter(null),
215 growable: false), 217 growable: false),
216 assignedVars = new List<ir.Primitive>.generate( 218 assignedVars = new List<ir.Primitive>.generate(
217 parent.assignedVars.length, (_) => null), 219 parent.assignedVars.length, (_) => null),
220 index2variable = new List<Element>.from(parent.index2variable),
218 super(parent.elements, parent.compiler); 221 super(parent.elements, parent.compiler);
219 222
220 /** 223 /**
221 * Builds the [ir.FunctionDefinition] for a function element. In case the 224 * Builds the [ir.FunctionDefinition] for a function element. In case the
222 * function uses features that cannot be expressed in the IR, this function 225 * function uses features that cannot be expressed in the IR, this function
223 * returns `null`. 226 * returns `null`.
224 */ 227 */
225 ir.FunctionDefinition buildFunction(FunctionElement functionElement) { 228 ir.FunctionDefinition buildFunction(FunctionElement functionElement) {
226 return nullIfGiveup(() => buildFunctionInternal(functionElement)); 229 return nullIfGiveup(() => buildFunctionInternal(functionElement));
227 } 230 }
228 231
229 ir.FunctionDefinition buildFunctionInternal(FunctionElement element) { 232 ir.FunctionDefinition buildFunctionInternal(FunctionElement element) {
230 assert(invariant(element, element.isImplementation)); 233 assert(invariant(element, element.isImplementation));
231 ast.FunctionExpression function = element.node; 234 ast.FunctionExpression function = element.node;
232 assert(function != null); 235 assert(function != null);
233 assert(!function.modifiers.isExternal); 236 assert(!function.modifiers.isExternal);
234 assert(elements[function] != null); 237 assert(elements[function] != null);
235 238
236 root = current = null; 239 root = current = null;
237 240
238 FunctionSignature signature = element.functionSignature; 241 FunctionSignature signature = element.functionSignature;
239 signature.orderedForEachParameter((parameterElement) { 242 signature.orderedForEachParameter((parameterElement) {
240 ir.Parameter parameter = new ir.Parameter(parameterElement); 243 ir.Parameter parameter = new ir.Parameter(parameterElement);
241 parameters.add(parameter); 244 parameters.add(parameter);
242 variableIndex[parameterElement] = assignedVars.length; 245 variableIndex[parameterElement] = assignedVars.length;
243 assignedVars.add(parameter); 246 assignedVars.add(parameter);
247 index2variable.add(parameterElement);
244 }); 248 });
245 249
246 visit(function.body); 250 visit(function.body);
247 ensureReturn(function); 251 ensureReturn(function);
248 return new ir.FunctionDefinition(returnContinuation, parameters, root); 252 return new ir.FunctionDefinition(returnContinuation, parameters, root);
249 } 253 }
250 254
251 ConstantSystem get constantSystem => compiler.backend.constantSystem; 255 ConstantSystem get constantSystem => compiler.backend.constantSystem;
252 256
253 bool get isOpen => root == null || current != null; 257 bool get isOpen => root == null || current != null;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 // The last assignments, if any, reaching the end of the two subterms. 343 // The last assignments, if any, reaching the end of the two subterms.
340 ir.Primitive leftAssignment = leftBuilder.assignedVars[i]; 344 ir.Primitive leftAssignment = leftBuilder.assignedVars[i];
341 ir.Primitive rightAssignment = rightBuilder.assignedVars[i]; 345 ir.Primitive rightAssignment = rightBuilder.assignedVars[i];
342 346
343 if (leftAssignment != null || rightAssignment != null) { 347 if (leftAssignment != null || rightAssignment != null) {
344 // The corresponsing argument is the reaching definition if any, or a 348 // The corresponsing argument is the reaching definition if any, or a
345 // free occurrence. In the case that control does not reach both the 349 // free occurrence. In the case that control does not reach both the
346 // left and right subterms we will still have a join continuation with 350 // left and right subterms we will still have a join continuation with
347 // possibly arguments passed to it. Such singly-used continuations 351 // possibly arguments passed to it. Such singly-used continuations
348 // are eliminated by the shrinking conversions. 352 // are eliminated by the shrinking conversions.
349 parameters.add(new ir.Parameter(null)); 353 parameters.add(new ir.Parameter(index2variable[i]));
350 ir.Primitive reachingDefinition = 354 ir.Primitive reachingDefinition =
351 assignedVars[i] == null ? freeVars[i] : assignedVars[i]; 355 assignedVars[i] == null ? freeVars[i] : assignedVars[i];
352 leftArguments.add( 356 leftArguments.add(
353 leftAssignment == null ? reachingDefinition : leftAssignment); 357 leftAssignment == null ? reachingDefinition : leftAssignment);
354 rightArguments.add( 358 rightArguments.add(
355 rightAssignment == null ? reachingDefinition : rightAssignment); 359 rightAssignment == null ? reachingDefinition : rightAssignment);
356 } 360 }
357 } 361 }
358 return parameters; 362 return parameters;
359 } 363 }
(...skipping 29 matching lines...) Expand all
389 for (int i = 0; i < assignedVars.length; ++i) { 393 for (int i = 0; i < assignedVars.length; ++i) {
390 // Was there an assignment in the body? 394 // Was there an assignment in the body?
391 ir.Definition reachingAssignment = bodyBuilder.assignedVars[i]; 395 ir.Definition reachingAssignment = bodyBuilder.assignedVars[i];
392 // If not, was there an assignment in the condition? 396 // If not, was there an assignment in the condition?
393 if (reachingAssignment == null) { 397 if (reachingAssignment == null) {
394 reachingAssignment = condBuilder.assignedVars[i]; 398 reachingAssignment = condBuilder.assignedVars[i];
395 } 399 }
396 // If not, no value needs to be passed to the join point. 400 // If not, no value needs to be passed to the join point.
397 if (reachingAssignment == null) continue; 401 if (reachingAssignment == null) continue;
398 402
399 parameters.add(new ir.Parameter(null)); 403 parameters.add(new ir.Parameter(index2variable[i]));
400 ir.Definition entryAssignment = assignedVars[i]; 404 ir.Definition entryAssignment = assignedVars[i];
401 entryArguments.add( 405 entryArguments.add(
402 entryAssignment == null ? freeVars[i] : entryAssignment); 406 entryAssignment == null ? freeVars[i] : entryAssignment);
403 loopArguments.add(reachingAssignment); 407 loopArguments.add(reachingAssignment);
404 } 408 }
405 return parameters; 409 return parameters;
406 } 410 }
407 411
408 /// Capture free variables in the arms of a branch. 412 /// Capture free variables in the arms of a branch.
409 /// 413 ///
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) { 626 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
623 assert(isOpen); 627 assert(isOpen);
624 for (ast.Node definition in node.definitions.nodes) { 628 for (ast.Node definition in node.definitions.nodes) {
625 Element element = elements[definition]; 629 Element element = elements[definition];
626 // Definitions are either SendSets if there is an initializer, or 630 // Definitions are either SendSets if there is an initializer, or
627 // Identifiers if there is no initializer. 631 // Identifiers if there is no initializer.
628 if (definition is ast.SendSet) { 632 if (definition is ast.SendSet) {
629 assert(!definition.arguments.isEmpty); 633 assert(!definition.arguments.isEmpty);
630 assert(definition.arguments.tail.isEmpty); 634 assert(definition.arguments.tail.isEmpty);
631 ir.Primitive initialValue = visit(definition.arguments.head); 635 ir.Primitive initialValue = visit(definition.arguments.head);
636 // In case a primitive was introduced for the initializer expression,
637 // use this variable element to help derive a good name for it.
638 initialValue.useElementAsHint(element);
632 variableIndex[element] = assignedVars.length; 639 variableIndex[element] = assignedVars.length;
633 assignedVars.add(initialValue); 640 assignedVars.add(initialValue);
641 index2variable.add(element);
634 } else { 642 } else {
635 assert(definition is ast.Identifier); 643 assert(definition is ast.Identifier);
636 // The initial value is null. 644 // The initial value is null.
637 // TODO(kmillikin): Consider pooling constants. 645 // TODO(kmillikin): Consider pooling constants.
638 ir.Constant constant = new ir.Constant(constantSystem.createNull()); 646 ir.Constant constant = new ir.Constant(constantSystem.createNull());
647 constant.useElementAsHint(element);
639 add(new ir.LetPrim(constant)); 648 add(new ir.LetPrim(constant));
640 variableIndex[element] = assignedVars.length; 649 variableIndex[element] = assignedVars.length;
641 assignedVars.add(constant); 650 assignedVars.add(constant);
651 index2variable.add(element);
642 } 652 }
643 } 653 }
644 return null; 654 return null;
645 } 655 }
646 656
647 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] 657 // Build(Return(e), C) = C'[InvokeContinuation(return, x)]
648 // where (C', x) = Build(e, C) 658 // where (C', x) = Build(e, C)
649 // 659 //
650 // Return without a subexpression is translated as if it were return null. 660 // Return without a subexpression is translated as if it were return null.
651 ir.Primitive visitReturn(ast.Return node) { 661 ir.Primitive visitReturn(ast.Return node) {
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 Element element = elements[node]; 1097 Element element = elements[node];
1088 ast.Operator op = node.assignmentOperator; 1098 ast.Operator op = node.assignmentOperator;
1089 ir.Primitive result; 1099 ir.Primitive result;
1090 ir.Primitive getter; 1100 ir.Primitive getter;
1091 if (op.source == '=') { 1101 if (op.source == '=') {
1092 if (Elements.isLocal(element)) { 1102 if (Elements.isLocal(element)) {
1093 // Exactly one argument expected for a simple assignment. 1103 // Exactly one argument expected for a simple assignment.
1094 assert(!node.arguments.isEmpty); 1104 assert(!node.arguments.isEmpty);
1095 assert(node.arguments.tail.isEmpty); 1105 assert(node.arguments.tail.isEmpty);
1096 result = visit(node.arguments.head); 1106 result = visit(node.arguments.head);
1107 result.useElementAsHint(element);
1097 assignedVars[variableIndex[element]] = result; 1108 assignedVars[variableIndex[element]] = result;
1098 return result; 1109 return result;
1099 } else if (Elements.isStaticOrTopLevel(element)) { 1110 } else if (Elements.isStaticOrTopLevel(element)) {
1100 assert(element.isField || element.isSetter); 1111 assert(element.isField || element.isSetter);
1101 assert(!node.arguments.isEmpty && node.arguments.tail.isEmpty); 1112 assert(!node.arguments.isEmpty && node.arguments.tail.isEmpty);
1102 ir.Parameter v = new ir.Parameter(null); 1113 ir.Parameter v = new ir.Parameter(null);
1103 ir.Continuation k = new ir.Continuation([v]); 1114 ir.Continuation k = new ir.Continuation([v]);
1104 Selector selector = elements.getSelector(node); 1115 Selector selector = elements.getSelector(node);
1105 ir.Definition arg = visit(node.arguments.head); 1116 ir.Definition arg = visit(node.arguments.head);
1106 ir.InvokeStatic invoke = 1117 ir.InvokeStatic invoke =
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 ir.Primitive arg; 1154 ir.Primitive arg;
1144 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) { 1155 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) {
1145 assert(node.arguments.isEmpty); 1156 assert(node.arguments.isEmpty);
1146 arg = new ir.Constant(constantSystem.createInt(1)); 1157 arg = new ir.Constant(constantSystem.createInt(1));
1147 add(new ir.LetPrim(arg)); 1158 add(new ir.LetPrim(arg));
1148 } else { 1159 } else {
1149 assert(!node.arguments.isEmpty); 1160 assert(!node.arguments.isEmpty);
1150 assert(node.arguments.tail.isEmpty); 1161 assert(node.arguments.tail.isEmpty);
1151 arg = visit(node.arguments.head); 1162 arg = visit(node.arguments.head);
1152 } 1163 }
1164 arg.useElementAsHint(element);
1153 result = new ir.Parameter(null); 1165 result = new ir.Parameter(null);
1154 ir.Continuation k = new ir.Continuation([result]); 1166 ir.Continuation k = new ir.Continuation([result]);
1155 ir.Expression invoke = new ir.InvokeMethod(getter, selector, k, [arg]); 1167 ir.Expression invoke = new ir.InvokeMethod(getter, selector, k, [arg]);
1156 add(new ir.LetCont(k, invoke)); 1168 add(new ir.LetCont(k, invoke));
1157 1169
1158 assignedVars[variableIndex[element]] = result; 1170 assignedVars[variableIndex[element]] = result;
1159 1171
1160 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source) && 1172 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source) &&
1161 !node.isPrefix) { 1173 !node.isPrefix) {
1162 assert(getter != null); 1174 assert(getter != null);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 bool visitType(DartType type, Null _) => false; 1293 bool visitType(DartType type, Null _) => false;
1282 1294
1283 bool visitDynamicType(DynamicType type, Null _) => true; 1295 bool visitDynamicType(DynamicType type, Null _) => true;
1284 1296
1285 bool visitVoidType(VoidType type, Null _) => true; 1297 bool visitVoidType(VoidType type, Null _) => true;
1286 1298
1287 // Currently, InterfaceType and TypedefType are supported so long as they 1299 // Currently, InterfaceType and TypedefType are supported so long as they
1288 // do not have type parameters. They are subclasses of GenericType. 1300 // do not have type parameters. They are subclasses of GenericType.
1289 bool visitGenericType(GenericType type, Null _) => !type.isGeneric; 1301 bool visitGenericType(GenericType type, Null _) => !type.isGeneric;
1290 } 1302 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698