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

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

Issue 1088493002: Assignment expressions in tree IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comments Created 5 years, 8 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 /// This is not safe if the code is moved inside the scope of an exception 62 /// This is not safe if the code is moved inside the scope of an exception
63 /// handler (i.e., into a try block). We keep a stack of singly-referenced 63 /// handler (i.e., into a try block). We keep a stack of singly-referenced
64 /// continuations that are in scope without crossing a binding for a handler. 64 /// continuations that are in scope without crossing a binding for a handler.
65 List<cps_ir.Continuation> safeForInlining = <cps_ir.Continuation>[]; 65 List<cps_ir.Continuation> safeForInlining = <cps_ir.Continuation>[];
66 66
67 ExecutableElement currentElement; 67 ExecutableElement currentElement;
68 /// The 'this' Parameter for currentElement or the enclosing method. 68 /// The 'this' Parameter for currentElement or the enclosing method.
69 cps_ir.Parameter thisParameter; 69 cps_ir.Parameter thisParameter;
70 cps_ir.Continuation returnContinuation; 70 cps_ir.Continuation returnContinuation;
71 71
72 /// Number of loops enclosing the currently visited node.
73 int enclosingLoops = 0;
74
72 Builder parent; 75 Builder parent;
73 76
74 Builder(this.internalError, [this.parent]); 77 Builder(this.internalError, [this.parent]);
75 78
76 Builder createInnerBuilder() { 79 Builder createInnerBuilder() {
77 return new Builder(internalError, this); 80 return new Builder(internalError, this);
78 } 81 }
79 82
80 /// Variable used in [buildPhiAssignments] as a temporary when swapping 83 /// Variable used in [buildPhiAssignments] as a temporary when swapping
81 /// variables. 84 /// variables.
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 List<Expression> translateArguments(List<cps_ir.Reference> args) { 210 List<Expression> translateArguments(List<cps_ir.Reference> args) {
208 return new List<Expression>.generate(args.length, 211 return new List<Expression>.generate(args.length,
209 (int index) => getVariableUse(args[index]), 212 (int index) => getVariableUse(args[index]),
210 growable: false); 213 growable: false);
211 } 214 }
212 215
213 Statement buildContinuationAssignment( 216 Statement buildContinuationAssignment(
214 cps_ir.Parameter parameter, 217 cps_ir.Parameter parameter,
215 Expression argument, 218 Expression argument,
216 Statement buildRest()) { 219 Statement buildRest()) {
217 Statement assignment; 220 Expression expr;
218 if (parameter.hasAtLeastOneUse) { 221 if (parameter.hasAtLeastOneUse) {
219 Variable variable = getVariable(parameter); 222 expr = new Assign(getVariable(parameter), argument);
220 assignment = new Assign(variable, argument, null);
221 } else { 223 } else {
222 assignment = new ExpressionStatement(argument, null); 224 expr = argument;
223 } 225 }
224 assignment.next = buildRest(); 226 return new ExpressionStatement(expr, buildRest());
225 return assignment;
226 } 227 }
227 228
228 /// Simultaneously assigns each argument to the corresponding parameter, 229 /// Simultaneously assigns each argument to the corresponding parameter,
229 /// then continues at the statement created by [buildRest]. 230 /// then continues at the statement created by [buildRest].
230 Statement buildPhiAssignments( 231 Statement buildPhiAssignments(
231 List<cps_ir.Parameter> parameters, 232 List<cps_ir.Parameter> parameters,
232 List<Expression> arguments, 233 List<Expression> arguments,
233 Statement buildRest()) { 234 Statement buildRest()) {
234 assert(parameters.length == arguments.length); 235 assert(parameters.length == arguments.length);
235 // We want a parallel assignment to all parameters simultaneously. 236 // We want a parallel assignment to all parameters simultaneously.
(...skipping 21 matching lines...) Expand all
257 } 258 }
258 list.add(i); 259 list.add(i);
259 } else { 260 } else {
260 // v1 = this; 261 // v1 = this;
261 } 262 }
262 } 263 }
263 264
264 Statement first, current; 265 Statement first, current;
265 void addAssignment(Variable dst, Expression src) { 266 void addAssignment(Variable dst, Expression src) {
266 if (first == null) { 267 if (first == null) {
267 first = current = new Assign(dst, src, null); 268 first = current = Assign.makeStatement(dst, src);
268 } else { 269 } else {
269 current = current.next = new Assign(dst, src, null); 270 current = current.next = Assign.makeStatement(dst, src);
270 } 271 }
271 } 272 }
272 273
273 List<Expression> assignmentSrc = new List<Expression>(parameters.length); 274 List<Expression> assignmentSrc = new List<Expression>(parameters.length);
274 List<bool> done = new List<bool>.filled(parameters.length, false); 275 List<bool> done = new List<bool>.filled(parameters.length, false);
275 void visitAssignment(int i) { 276 void visitAssignment(int i) {
276 if (done[i]) { 277 if (done[i]) {
277 return; 278 return;
278 } 279 }
279 Variable param = getVariable(parameters[i]); 280 Variable param = getVariable(parameters[i]);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 if (variable == null) return visit(node.body); 365 if (variable == null) return visit(node.body);
365 366
366 Node definition = visit(node.primitive); 367 Node definition = visit(node.primitive);
367 368
368 // visitPrimitive returns a Statement without successor if it cannot occur 369 // visitPrimitive returns a Statement without successor if it cannot occur
369 // in expression context (currently only the case for FunctionDeclarations). 370 // in expression context (currently only the case for FunctionDeclarations).
370 if (definition is Statement) { 371 if (definition is Statement) {
371 definition.next = visit(node.body); 372 definition.next = visit(node.body);
372 return definition; 373 return definition;
373 } else { 374 } else {
374 return new Assign(variable, definition, visit(node.body)); 375 return Assign.makeStatement(variable, definition, visit(node.body));
375 } 376 }
376 } 377 }
377 378
378 Statement visitBody(cps_ir.Body node) { 379 Statement visitBody(cps_ir.Body node) {
379 return visit(node.body); 380 return visit(node.body);
380 } 381 }
381 382
382 Statement visitLetCont(cps_ir.LetCont node) { 383 Statement visitLetCont(cps_ir.LetCont node) {
383 // Introduce labels for continuations that need them. 384 // Introduce labels for continuations that need them.
384 int safeForInliningLengthOnEntry = safeForInlining.length; 385 int safeForInliningLengthOnEntry = safeForInlining.length;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 nextBuilder); 468 nextBuilder);
468 } 469 }
469 } 470 }
470 471
471 Statement visitLetMutable(cps_ir.LetMutable node) { 472 Statement visitLetMutable(cps_ir.LetMutable node) {
472 Variable variable = addMutableVariable(node.variable); 473 Variable variable = addMutableVariable(node.variable);
473 Expression value = getVariableUse(node.value); 474 Expression value = getVariableUse(node.value);
474 Statement body = visit(node.body); 475 Statement body = visit(node.body);
475 // If the variable was captured by an inner function in the body, this 476 // If the variable was captured by an inner function in the body, this
476 // must be declared here so we assign to a fresh copy of the variable. 477 // must be declared here so we assign to a fresh copy of the variable.
477 bool needsDeclaration = variable.isCaptured; 478 if (variable.isCaptured && enclosingLoops > 0) {
478 return new Assign(variable, value, body, isDeclaration: needsDeclaration); 479 return new VariableDeclaration(variable, value, body);
480 }
481 return Assign.makeStatement(variable, value, body);
479 } 482 }
480 483
481 Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) { 484 Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) {
482 return getMutableVariableUse(node.variable); 485 return getMutableVariableUse(node.variable);
483 } 486 }
484 487
485 Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) { 488 Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) {
486 Variable variable = getMutableVariable(node.variable.definition); 489 Variable variable = getMutableVariable(node.variable.definition);
487 Expression value = getVariableUse(node.value); 490 Expression value = getVariableUse(node.value);
488 return new Assign(variable, value, visit(node.body)); 491 return Assign.makeStatement(variable, value, visit(node.body));
489 } 492 }
490 493
491 Statement visitDeclareFunction(cps_ir.DeclareFunction node) { 494 Statement visitDeclareFunction(cps_ir.DeclareFunction node) {
492 Variable variable = addMutableVariable(node.variable); 495 Variable variable = addMutableVariable(node.variable);
493 FunctionDefinition function = makeSubFunction(node.definition); 496 FunctionDefinition function = makeSubFunction(node.definition);
494 return new FunctionDeclaration(variable, function, visit(node.body)); 497 return new FunctionDeclaration(variable, function, visit(node.body));
495 } 498 }
496 499
497 Statement visitTypeOperator(cps_ir.TypeOperator node) { 500 Statement visitTypeOperator(cps_ir.TypeOperator node) {
498 Expression receiver = getVariableUse(node.receiver); 501 Expression receiver = getVariableUse(node.receiver);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 // inline at the invocation site. 535 // inline at the invocation site.
533 // - If there are multiple uses, translate to Break. 536 // - If there are multiple uses, translate to Break.
534 // * Recursive continuations 537 // * Recursive continuations
535 // - There is a single non-recursive invocation. Translate 538 // - There is a single non-recursive invocation. Translate
536 // the continuation body inline as a labeled loop at the 539 // the continuation body inline as a labeled loop at the
537 // invocation site. 540 // invocation site.
538 // - Translate the recursive invocations to Continue. 541 // - Translate the recursive invocations to Continue.
539 if (cont.isRecursive) { 542 if (cont.isRecursive) {
540 return node.isRecursive 543 return node.isRecursive
541 ? new Continue(labels[cont]) 544 ? new Continue(labels[cont])
542 : new WhileTrue(labels[cont], visit(cont.body)); 545 : new WhileTrue(labels[cont], makeLoopBody(cont.body));
543 } else { 546 } else {
544 if (cont.hasExactlyOneUse) { 547 if (cont.hasExactlyOneUse) {
545 if (safeForInlining.contains(cont)) { 548 if (safeForInlining.contains(cont)) {
546 return visit(cont.body); 549 return visit(cont.body);
547 } 550 }
548 labels[cont] = new Label(); 551 labels[cont] = new Label();
549 } 552 }
550 return new Break(labels[cont]); 553 return new Break(labels[cont]);
551 } 554 }
552 }); 555 });
553 } 556 }
554 } 557 }
555 558
559 Statement makeLoopBody(cps_ir.Expression body) {
560 ++enclosingLoops;
561 Statement result = visit(body);
562 --enclosingLoops;
563 return result;
564 }
565
556 Statement visitBranch(cps_ir.Branch node) { 566 Statement visitBranch(cps_ir.Branch node) {
557 Expression condition = visit(node.condition); 567 Expression condition = visit(node.condition);
558 Statement thenStatement, elseStatement; 568 Statement thenStatement, elseStatement;
559 cps_ir.Continuation cont = node.trueContinuation.definition; 569 cps_ir.Continuation cont = node.trueContinuation.definition;
560 assert(cont.parameters.isEmpty); 570 assert(cont.parameters.isEmpty);
561 thenStatement = 571 thenStatement =
562 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]); 572 cont.hasExactlyOneUse ? visit(cont.body) : new Break(labels[cont]);
563 cont = node.falseContinuation.definition; 573 cont = node.falseContinuation.definition;
564 assert(cont.parameters.isEmpty); 574 assert(cont.parameters.isEmpty);
565 elseStatement = 575 elseStatement =
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 } 650 }
641 651
642 @override 652 @override
643 Node visitTypeExpression(cps_ir.TypeExpression node) { 653 Node visitTypeExpression(cps_ir.TypeExpression node) {
644 return new TypeExpression( 654 return new TypeExpression(
645 node.dartType, 655 node.dartType,
646 node.arguments.map(getVariableUse).toList()); 656 node.arguments.map(getVariableUse).toList());
647 } 657 }
648 } 658 }
649 659
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698