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

Unified Diff: pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart

Issue 1094433003: tree-ir: Move labeled statements outside loops. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
index e2b70119a72044ba1435bf9f99c8926b99fb4c69..0129c0df5665451418042ff9789725d27866d54d 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
@@ -4,9 +4,31 @@
part of tree_ir.optimization;
-/// Rewrites [WhileTrue] statements with an [If] body into a [WhileCondition],
-/// in situations where only one of the branches contains a [Continue] to the
-/// loop. Schematically:
+/// Rewrites [WhileTrue] statements.
+///
+/// Before this phase, loops usually contain a lot of "exit code", that is,
+/// code that happens at a point where a [Continue] can no longer be reached,
+/// and is therefore not really part of the loop.
+/// Exit code is moved down after the loop using the following rewrites rules:
+///
+/// EXTRACT LABELED STATEMENT:
+///
+/// L:
+/// while (true) {
+/// L2: {
+/// S1 (has references to L)
+/// }
+/// S2 (has no references to L)
+/// }
+///
+/// ==>
+///
+/// L2: {
+/// L: while (true) S1
+/// }
+/// S2
+///
+/// INTRODUCE CONDITIONAL LOOP:
///
/// L:
/// while (true) {
@@ -25,8 +47,10 @@ part of tree_ir.optimization;
///
/// A similar transformation is used when S2 occurs in the 'then' position.
///
-/// Note that the above pattern needs no iteration since nested ifs
+/// Note that the last pattern above needs no iteration since nested ifs
/// have been collapsed previously in the [StatementRewriter] phase.
+///
+/// [WhileCondition] statements exist only after this phase.
class LoopRewriter extends RecursiveTransformer
implements Pass {
String get passName => 'Loop rewriter';
@@ -49,6 +73,28 @@ class LoopRewriter extends RecursiveTransformer
Statement visitWhileTrue(WhileTrue node) {
assert(!usedContinueLabels.contains(node.label));
+
+ // Pull labeled statements outside the loop when possible.
+ // [head] and [tail] are the first and last labeled statements that were
+ // pulled out, and null when none have been pulled out.
+ LabeledStatement head, tail;
+ while (node.body is LabeledStatement) {
+ LabeledStatement inner = node.body;
+ inner.next = visitStatement(inner.next);
+ bool nextHasContinue = usedContinueLabels.remove(node.label);
+ if (nextHasContinue) break;
+ node.body = inner.body;
+ inner.body = node;
+ if (head == null) {
+ head = tail = inner;
+ } else {
+ tail.body = inner;
+ tail = inner;
+ }
+ }
+
+ // Rewrite while(true) to while(condition).
+ Statement loop = node;
if (node.body is If) {
If body = node.body;
body.thenStatement = visitStatement(body.thenStatement);
@@ -57,23 +103,31 @@ class LoopRewriter extends RecursiveTransformer
bool elseHasContinue = usedContinueLabels.remove(node.label);
if (thenHasContinue && !elseHasContinue) {
node.label.binding = null; // Prepare to rebind the label.
- return new WhileCondition(
+ loop = new WhileCondition(
node.label,
body.condition,
body.thenStatement,
body.elseStatement);
} else if (!thenHasContinue && elseHasContinue) {
node.label.binding = null;
- return new WhileCondition(
+ loop = new WhileCondition(
node.label,
new Not(body.condition),
body.elseStatement,
body.thenStatement);
}
+ } else if (node.body is LabeledStatement) {
+ // If the body is a labeled statement, its .next has already been visited.
+ LabeledStatement body = node.body;
+ body.body = visitStatement(body.body);
+ usedContinueLabels.remove(node.label);
} else {
node.body = visitStatement(node.body);
usedContinueLabels.remove(node.label);
}
- return node;
+
+ if (head == null) return loop;
+ tail.body = loop;
+ return head;
}
}
« no previous file with comments | « no previous file | tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698