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

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

Issue 1220123004: dart2js cps: Ensure definitions are specialized before their uses. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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
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 '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
10 import '../util/util.dart' show CURRENT_ELEMENT_SPANNABLE; 10 import '../util/util.dart' show CURRENT_ELEMENT_SPANNABLE;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 final Map<cps_ir.Primitive, Variable> primitive2variable = 48 final Map<cps_ir.Primitive, Variable> primitive2variable =
49 <cps_ir.Primitive, Variable>{}; 49 <cps_ir.Primitive, Variable>{};
50 final Map<cps_ir.MutableVariable, Variable> mutable2variable = 50 final Map<cps_ir.MutableVariable, Variable> mutable2variable =
51 <cps_ir.MutableVariable, Variable>{}; 51 <cps_ir.MutableVariable, Variable>{};
52 52
53 // Continuations with more than one use are replaced with Tree labels. This 53 // Continuations with more than one use are replaced with Tree labels. This
54 // is the mapping from continuations to labels. 54 // is the mapping from continuations to labels.
55 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{}; 55 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
56 56
57 /// A stack of singly-used labels that can be safely inlined at their use
58 /// site.
59 ///
60 /// Code for continuations with exactly one use is inlined at the use site.
61 /// This is not safe if the code is moved inside the scope of an exception
62 /// handler (i.e., into a try block). We keep a stack of singly-referenced
63 /// continuations that are in scope without crossing a binding for a handler.
64 List<cps_ir.Continuation> safeForInlining = <cps_ir.Continuation>[];
65
66 ExecutableElement currentElement; 57 ExecutableElement currentElement;
67 /// The 'this' Parameter for currentElement or the enclosing method. 58 /// The 'this' Parameter for currentElement or the enclosing method.
68 cps_ir.Parameter thisParameter; 59 cps_ir.Parameter thisParameter;
69 cps_ir.Continuation returnContinuation; 60 cps_ir.Continuation returnContinuation;
70 61
71 Builder parent; 62 Builder parent;
72 63
73 Builder(this.internalError, [this.parent]); 64 Builder(this.internalError, [this.parent]);
74 65
75 Builder createInnerBuilder() { 66 Builder createInnerBuilder() {
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 302
312 // Don't translate unused primitives. 303 // Don't translate unused primitives.
313 if (variable == null) return visit(node.body); 304 if (variable == null) return visit(node.body);
314 305
315 Expression value = visit(node.primitive); 306 Expression value = visit(node.primitive);
316 return Assign.makeStatement(variable, value, visit(node.body)); 307 return Assign.makeStatement(variable, value, visit(node.body));
317 } 308 }
318 309
319 Statement visitLetCont(cps_ir.LetCont node) { 310 Statement visitLetCont(cps_ir.LetCont node) {
320 // Introduce labels for continuations that need them. 311 // Introduce labels for continuations that need them.
321 int safeForInliningLengthOnEntry = safeForInlining.length;
322 for (cps_ir.Continuation continuation in node.continuations) { 312 for (cps_ir.Continuation continuation in node.continuations) {
323 if (continuation.hasMultipleUses || continuation.isRecursive) { 313 if (continuation.hasMultipleUses || continuation.isRecursive) {
324 labels[continuation] = new Label(); 314 labels[continuation] = new Label();
325 } else {
326 safeForInlining.add(continuation);
327 } 315 }
328 } 316 }
329 Statement body = visit(node.body); 317 Statement body = visit(node.body);
330 safeForInlining.length = safeForInliningLengthOnEntry;
331 // Continuations are bound at the same level, but they have to be 318 // Continuations are bound at the same level, but they have to be
332 // translated as if nested. This is because the body can invoke any 319 // translated as if nested. This is because the body can invoke any
333 // of them from anywhere, so it must be nested inside all of them. 320 // of them from anywhere, so it must be nested inside all of them.
334 // 321 //
335 // The continuation bodies are not always translated directly here because 322 // The continuation bodies are not always translated directly here because
336 // they may have been already translated: 323 // they may have been already translated:
337 // * For singly-used continuations, the continuation's body is 324 // * For singly-used continuations, the continuation's body is
338 // translated at the site of the continuation invocation. 325 // translated at the site of the continuation invocation.
339 // * For recursive continuations, there is a single non-recursive 326 // * For recursive continuations, there is a single non-recursive
340 // invocation. The continuation's body is translated at the site 327 // invocation. The continuation's body is translated at the site
341 // of the non-recursive continuation invocation. 328 // of the non-recursive continuation invocation.
342 // See visitInvokeContinuation for the implementation. 329 // See visitInvokeContinuation for the implementation.
343 Statement current = body; 330 Statement current = body;
344 for (cps_ir.Continuation continuation in node.continuations.reversed) { 331 for (cps_ir.Continuation continuation in node.continuations.reversed) {
345 Label label = labels[continuation]; 332 Label label = labels[continuation];
346 if (label != null && !continuation.isRecursive) { 333 if (label != null && !continuation.isRecursive) {
347 current = 334 current =
348 new LabeledStatement(label, current, visit(continuation.body)); 335 new LabeledStatement(label, current, visit(continuation.body));
349 } 336 }
350 } 337 }
351 return current; 338 return current;
352 } 339 }
353 340
354 Statement visitLetHandler(cps_ir.LetHandler node) { 341 Statement visitLetHandler(cps_ir.LetHandler node) {
355 List<cps_ir.Continuation> saved = safeForInlining;
356 safeForInlining = <cps_ir.Continuation>[];
357 Statement tryBody = visit(node.body); 342 Statement tryBody = visit(node.body);
358 safeForInlining = saved;
359 List<Variable> catchParameters = 343 List<Variable> catchParameters =
360 node.handler.parameters.map(getVariable).toList(); 344 node.handler.parameters.map(getVariable).toList();
361 Statement catchBody = visit(node.handler.body); 345 Statement catchBody = visit(node.handler.body);
362 return new Try(tryBody, catchParameters, catchBody); 346 return new Try(tryBody, catchParameters, catchBody);
363 } 347 }
364 348
365 Statement visitInvokeStatic(cps_ir.InvokeStatic node) { 349 Statement visitInvokeStatic(cps_ir.InvokeStatic node) {
366 // Calls are translated to direct style. 350 // Calls are translated to direct style.
367 List<Expression> arguments = translateArguments(node.arguments); 351 List<Expression> arguments = translateArguments(node.arguments);
368 Expression invoke = new InvokeStatic(node.target, node.selector, arguments, 352 Expression invoke = new InvokeStatic(node.target, node.selector, arguments,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 // - There is a single non-recursive invocation. Translate 467 // - There is a single non-recursive invocation. Translate
484 // the continuation body inline as a labeled loop at the 468 // the continuation body inline as a labeled loop at the
485 // invocation site. 469 // invocation site.
486 // - Translate the recursive invocations to Continue. 470 // - Translate the recursive invocations to Continue.
487 if (cont.isRecursive) { 471 if (cont.isRecursive) {
488 return node.isRecursive 472 return node.isRecursive
489 ? new Continue(labels[cont]) 473 ? new Continue(labels[cont])
490 : new WhileTrue(labels[cont], visit(cont.body)); 474 : new WhileTrue(labels[cont], visit(cont.body));
491 } else { 475 } else {
492 if (cont.hasExactlyOneUse) { 476 if (cont.hasExactlyOneUse) {
493 if (safeForInlining.contains(cont)) { 477 if (!node.isEscapingTry) {
494 return visit(cont.body); 478 return visit(cont.body);
495 } 479 }
496 labels[cont] = new Label(); 480 labels[cont] = new Label();
497 } 481 }
498 return new Break(labels[cont]); 482 return new Break(labels[cont]);
499 } 483 }
500 }); 484 });
501 } 485 }
502 } 486 }
503 487
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 return new ForeignStatement( 607 return new ForeignStatement(
624 node.codeTemplate, 608 node.codeTemplate,
625 node.type, 609 node.type,
626 node.arguments.map(getVariableUse).toList(growable: false), 610 node.arguments.map(getVariableUse).toList(growable: false),
627 node.nativeBehavior, 611 node.nativeBehavior,
628 node.dependency); 612 node.dependency);
629 } 613 }
630 } 614 }
631 } 615 }
632 616
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698