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

Side by Side 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, 7 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
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 part of tree_ir.optimization; 5 part of tree_ir.optimization;
6 6
7 /// Rewrites [WhileTrue] statements with an [If] body into a [WhileCondition], 7 /// Rewrites [WhileTrue] statements.
8 /// in situations where only one of the branches contains a [Continue] to the 8 ///
9 /// loop. Schematically: 9 /// Before this phase, loops usually contain a lot of "exit code", that is,
10 /// code that happens at a point where a [Continue] can no longer be reached,
11 /// and is therefore not really part of the loop.
12 /// Exit code is moved down after the loop using the following rewrites rules:
13 ///
14 /// EXTRACT LABELED STATEMENT:
10 /// 15 ///
11 /// L: 16 /// L:
12 /// while (true) { 17 /// while (true) {
18 /// L2: {
19 /// S1 (has references to L)
20 /// }
21 /// S2 (has no references to L)
22 /// }
23 ///
24 /// ==>
25 ///
26 /// L2: {
27 /// L: while (true) S1
28 /// }
29 /// S2
30 ///
31 /// INTRODUCE CONDITIONAL LOOP:
32 ///
33 /// L:
34 /// while (true) {
13 /// if (E) { 35 /// if (E) {
14 /// S1 (has references to L) 36 /// S1 (has references to L)
15 /// } else { 37 /// } else {
16 /// S2 (has no references to L) 38 /// S2 (has no references to L)
17 /// } 39 /// }
18 /// } 40 /// }
19 /// ==> 41 /// ==>
20 /// L: 42 /// L:
21 /// while (E) { 43 /// while (E) {
22 /// S1 44 /// S1
23 /// }; 45 /// };
24 /// S2 46 /// S2
25 /// 47 ///
26 /// A similar transformation is used when S2 occurs in the 'then' position. 48 /// A similar transformation is used when S2 occurs in the 'then' position.
27 /// 49 ///
28 /// Note that the above pattern needs no iteration since nested ifs 50 /// Note that the last pattern above needs no iteration since nested ifs
29 /// have been collapsed previously in the [StatementRewriter] phase. 51 /// have been collapsed previously in the [StatementRewriter] phase.
52 ///
53 /// [WhileCondition] statements exist only after this phase.
30 class LoopRewriter extends RecursiveTransformer 54 class LoopRewriter extends RecursiveTransformer
31 implements Pass { 55 implements Pass {
32 String get passName => 'Loop rewriter'; 56 String get passName => 'Loop rewriter';
33 57
34 Set<Label> usedContinueLabels = new Set<Label>(); 58 Set<Label> usedContinueLabels = new Set<Label>();
35 59
36 void rewrite(RootNode root) { 60 void rewrite(RootNode root) {
37 root.replaceEachBody(visitStatement); 61 root.replaceEachBody(visitStatement);
38 } 62 }
39 63
40 @override 64 @override
41 void visitInnerFunction(FunctionDefinition node) { 65 void visitInnerFunction(FunctionDefinition node) {
42 node.body = new LoopRewriter().visitStatement(node.body); 66 node.body = new LoopRewriter().visitStatement(node.body);
43 } 67 }
44 68
45 Statement visitContinue(Continue node) { 69 Statement visitContinue(Continue node) {
46 usedContinueLabels.add(node.target); 70 usedContinueLabels.add(node.target);
47 return node; 71 return node;
48 } 72 }
49 73
50 Statement visitWhileTrue(WhileTrue node) { 74 Statement visitWhileTrue(WhileTrue node) {
51 assert(!usedContinueLabels.contains(node.label)); 75 assert(!usedContinueLabels.contains(node.label));
76
77 // Pull labeled statements outside the loop when possible.
78 // [head] and [tail] are the first and last labeled statements that were
79 // pulled out, and null when none have been pulled out.
80 LabeledStatement head, tail;
81 while (node.body is LabeledStatement) {
82 LabeledStatement inner = node.body;
83 inner.next = visitStatement(inner.next);
84 bool nextHasContinue = usedContinueLabels.remove(node.label);
85 if (nextHasContinue) break;
86 node.body = inner.body;
87 inner.body = node;
88 if (head == null) {
89 head = tail = inner;
90 } else {
91 tail.body = inner;
92 tail = inner;
93 }
94 }
95
96 // Rewrite while(true) to while(condition).
97 Statement loop = node;
52 if (node.body is If) { 98 if (node.body is If) {
53 If body = node.body; 99 If body = node.body;
54 body.thenStatement = visitStatement(body.thenStatement); 100 body.thenStatement = visitStatement(body.thenStatement);
55 bool thenHasContinue = usedContinueLabels.remove(node.label); 101 bool thenHasContinue = usedContinueLabels.remove(node.label);
56 body.elseStatement = visitStatement(body.elseStatement); 102 body.elseStatement = visitStatement(body.elseStatement);
57 bool elseHasContinue = usedContinueLabels.remove(node.label); 103 bool elseHasContinue = usedContinueLabels.remove(node.label);
58 if (thenHasContinue && !elseHasContinue) { 104 if (thenHasContinue && !elseHasContinue) {
59 node.label.binding = null; // Prepare to rebind the label. 105 node.label.binding = null; // Prepare to rebind the label.
60 return new WhileCondition( 106 loop = new WhileCondition(
61 node.label, 107 node.label,
62 body.condition, 108 body.condition,
63 body.thenStatement, 109 body.thenStatement,
64 body.elseStatement); 110 body.elseStatement);
65 } else if (!thenHasContinue && elseHasContinue) { 111 } else if (!thenHasContinue && elseHasContinue) {
66 node.label.binding = null; 112 node.label.binding = null;
67 return new WhileCondition( 113 loop = new WhileCondition(
68 node.label, 114 node.label,
69 new Not(body.condition), 115 new Not(body.condition),
70 body.elseStatement, 116 body.elseStatement,
71 body.thenStatement); 117 body.thenStatement);
72 } 118 }
119 } else if (node.body is LabeledStatement) {
120 // If the body is a labeled statement, its .next has already been visited.
121 LabeledStatement body = node.body;
122 body.body = visitStatement(body.body);
123 usedContinueLabels.remove(node.label);
73 } else { 124 } else {
74 node.body = visitStatement(node.body); 125 node.body = visitStatement(node.body);
75 usedContinueLabels.remove(node.label); 126 usedContinueLabels.remove(node.label);
76 } 127 }
77 return node; 128
129 if (head == null) return loop;
130 tail.body = loop;
131 return head;
78 } 132 }
79 } 133 }
OLDNEW
« 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