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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart_backend/tree_tracer.dart

Issue 318723002: dart2dart: Restore loops with conditions and updates in backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Kevin's comments + bugfix 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) 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 dart_backend.tracer; 5 library dart_backend.tracer;
6 6
7 import 'dart:async' show EventSink; 7 import 'dart:async' show EventSink;
8 import '../tracer.dart'; 8 import '../tracer.dart';
9 import 'dart_tree.dart'; 9 import 'dart_tree.dart';
10 10
11 class Block { 11 class Block {
12 int index; 12 int index;
13 final List<Statement> statements = <Statement>[]; 13 final Label label;
14 /// Mixed list of [Statement] and [Block].
15 /// A [Block] represents a synthetic goto statement.
16 final List statements = [];
14 final List<Block> predecessors = <Block>[]; 17 final List<Block> predecessors = <Block>[];
15 final List<Block> successors = <Block>[]; 18 final List<Block> successors = <Block>[];
16 19
17 String get name => 'B$index'; 20 String get name => 'B$index';
18 21
22 Block([this.label]);
23
19 void addEdgeTo(Block successor) { 24 void addEdgeTo(Block successor) {
20 successors.add(successor); 25 successors.add(successor);
21 successor.predecessors.add(this); 26 successor.predecessors.add(this);
22 } 27 }
23 } 28 }
24 29
25 class BlockCollector extends Visitor { 30 class BlockCollector extends Visitor {
26 // Accumulate a list of blocks. The current block is the last block in 31 // Accumulate a list of blocks. The current block is the last block in
27 // the list. 32 // the list.
28 final List<Block> blocks = [new Block()..index = 0]; 33 final List<Block> blocks = [new Block()..index = 0];
29 34
30 // Map tree [Label]s (break or continue targets) and [Statement]s 35 // Map tree [Label]s (break or continue targets) and [Statement]s
31 // (if targets) to blocks. 36 // (if targets) to blocks.
32 final Map<Label, Block> breakTargets = <Label, Block>{}; 37 final Map<Label, Block> breakTargets = <Label, Block>{};
33 final Map<Label, Block> continueTargets = <Label, Block>{}; 38 final Map<Label, Block> continueTargets = <Label, Block>{};
34 final Map<Statement, Block> ifTargets = <Statement, Block>{}; 39 final Map<Statement, Block> ifTargets = <Statement, Block>{};
35 40
36 void _addStatement(Statement statement) { 41 void _addStatement(Statement statement) {
37 blocks.last.statements.add(statement); 42 blocks.last.statements.add(statement);
38 } 43 }
44 void _addGotoStatement(Block target) {
45 blocks.last.statements.add(target);
46 }
39 47
40 void _addBlock(Block block) { 48 void _addBlock(Block block) {
41 block.index = blocks.length; 49 block.index = blocks.length;
42 blocks.add(block); 50 blocks.add(block);
43 } 51 }
44 52
45 void collect(FunctionDefinition function) { 53 void collect(FunctionDefinition function) {
46 visitStatement(function.body); 54 visitStatement(function.body);
47 } 55 }
48 56
49 visitVariable(Variable node) {} 57 visitVariable(Variable node) {}
50 visitInvokeStatic(InvokeStatic node) {} 58 visitInvokeStatic(InvokeStatic node) {}
51 visitInvokeMethod(InvokeMethod node) {} 59 visitInvokeMethod(InvokeMethod node) {}
52 visitInvokeConstructor(InvokeConstructor node) {} 60 visitInvokeConstructor(InvokeConstructor node) {}
53 visitConcatenateStrings(ConcatenateStrings node) {} 61 visitConcatenateStrings(ConcatenateStrings node) {}
54 visitLiteralList(LiteralList node) {} 62 visitLiteralList(LiteralList node) {}
55 visitLiteralMap(LiteralMap node) {} 63 visitLiteralMap(LiteralMap node) {}
56 visitInvokeConstConstructor(InvokeConstConstructor node) {} 64 visitInvokeConstConstructor(InvokeConstConstructor node) {}
57 visitConstant(Constant node) {} 65 visitConstant(Constant node) {}
58 visitConditional(Conditional node) {} 66 visitConditional(Conditional node) {}
59 visitLogicalOperator(LogicalOperator node) {} 67 visitLogicalOperator(LogicalOperator node) {}
60 visitNot(Not node) {} 68 visitNot(Not node) {}
61 69
62 visitLabeledStatement(LabeledStatement node) { 70 visitLabeledStatement(LabeledStatement node) {
63 Block target = new Block(); 71 Block target = new Block(node.label);
64 breakTargets[node.label] = target; 72 breakTargets[node.label] = target;
65 visitStatement(node.body); 73 visitStatement(node.body);
66 _addBlock(target); 74 _addBlock(target);
67 visitStatement(node.next); 75 visitStatement(node.next);
68 } 76 }
69 77
70 visitAssign(Assign node) { 78 visitAssign(Assign node) {
71 _addStatement(node); 79 _addStatement(node);
72 visitStatement(node.next); 80 visitStatement(node.next);
73 } 81 }
(...skipping 19 matching lines...) Expand all
93 ifTargets[node.thenStatement] = thenTarget; 101 ifTargets[node.thenStatement] = thenTarget;
94 ifTargets[node.elseStatement] = elseTarget; 102 ifTargets[node.elseStatement] = elseTarget;
95 blocks.last.addEdgeTo(thenTarget); 103 blocks.last.addEdgeTo(thenTarget);
96 blocks.last.addEdgeTo(elseTarget); 104 blocks.last.addEdgeTo(elseTarget);
97 _addBlock(thenTarget); 105 _addBlock(thenTarget);
98 visitStatement(node.thenStatement); 106 visitStatement(node.thenStatement);
99 _addBlock(elseTarget); 107 _addBlock(elseTarget);
100 visitStatement(node.elseStatement); 108 visitStatement(node.elseStatement);
101 } 109 }
102 110
103 visitWhile(While node) { 111 visitWhileTrue(WhileTrue node) {
104 Block continueTarget = new Block(); 112 Block continueTarget = new Block();
113 _addGotoStatement(continueTarget);
114
105 continueTargets[node.label] = continueTarget; 115 continueTargets[node.label] = continueTarget;
106 blocks.last.addEdgeTo(continueTarget); 116 blocks.last.addEdgeTo(continueTarget);
107 _addBlock(continueTarget); 117 _addBlock(continueTarget);
108 _addStatement(node); 118 _addStatement(node);
109 visitStatement(node.body); 119 visitStatement(node.body);
110 } 120 }
111 121
122 visitWhileCondition(WhileCondition node) {
123 Block whileBlock = new Block();
124 _addGotoStatement(whileBlock);
125
126 _addBlock(whileBlock);
127 _addStatement(node);
128 whileBlock.statements.add(node);
129 blocks.last.addEdgeTo(whileBlock);
130
131 Block bodyBlock = new Block();
132 Block nextBlock = new Block();
133 whileBlock.addEdgeTo(bodyBlock);
134 whileBlock.addEdgeTo(nextBlock);
135
136 continueTargets[node.label] = bodyBlock;
137 _addBlock(bodyBlock);
138 visitStatement(node.body);
139
140 _addBlock(nextBlock);
141 visitStatement(node.next);
142
143 ifTargets[node.body] = bodyBlock;
144 ifTargets[node.next] = nextBlock;
145 }
146
112 visitExpressionStatement(ExpressionStatement node) { 147 visitExpressionStatement(ExpressionStatement node) {
113 _addStatement(node); 148 _addStatement(node);
114 visitStatement(node.next); 149 visitStatement(node.next);
115 } 150 }
116 } 151 }
117 152
118 class TreeTracer extends TracerUtil with Visitor { 153 class TreeTracer extends TracerUtil with StatementVisitor {
119 final EventSink<String> output; 154 final EventSink<String> output;
120 155
121 TreeTracer(this.output); 156 TreeTracer(this.output);
122 157
123 Names names; 158 Names names;
124 BlockCollector collector; 159 BlockCollector collector;
125 int statementCounter; 160 int statementCounter;
126 161
127 void traceGraph(String name, FunctionDefinition function) { 162 void traceGraph(String name, FunctionDefinition function) {
128 names = new Names(); 163 names = new Names();
(...skipping 17 matching lines...) Expand all
146 printProperty("successors", block.successors.map((b) => b.name)); 181 printProperty("successors", block.successors.map((b) => b.name));
147 printEmptyProperty("xhandlers"); 182 printEmptyProperty("xhandlers");
148 printEmptyProperty("flags"); 183 printEmptyProperty("flags");
149 tag("states", () { 184 tag("states", () {
150 tag("locals", () { 185 tag("locals", () {
151 printProperty("size", 0); 186 printProperty("size", 0);
152 printProperty("method", "None"); 187 printProperty("method", "None");
153 }); 188 });
154 }); 189 });
155 tag("HIR", () { 190 tag("HIR", () {
156 block.statements.forEach(visitStatement); 191 if (block.label != null) {
192 printStatement(null,
193 "Label ${block.name}, useCount=${block.label.useCount}");
194 }
195 block.statements.forEach(visitBlockMember);
157 }); 196 });
158 }); 197 });
159 } 198 }
160 199
200 void visitBlockMember(member) {
201 if (member is Block) {
202 printStatement(null, "goto block B${member.name}");
203 } else {
204 assert(member is Statement);
205 visitStatement(member);
206 }
207 }
208
161 void printStatement(String name, String contents) { 209 void printStatement(String name, String contents) {
162 int bci = 0; 210 int bci = 0;
163 int uses = 0; 211 int uses = 0;
164 if (name == null) { 212 if (name == null) {
165 name = 'x${statementCounter++}'; 213 name = 'x${statementCounter++}';
166 } 214 }
167 addIndent(); 215 addIndent();
168 add("$bci $uses $name $contents <|@\n"); 216 add("$bci $uses $name $contents <|@\n");
169 } 217 }
170 218
171 visitVariable(Variable node) {
172 printStatement(null, "dead-use ${names.varName(node)}");
173 }
174
175 visitInvokeStatic(InvokeStatic node) {
176 printStatement(null, expr(node));
177 }
178
179 visitConstant(Constant node) {
180 printStatement(null, "dead-use ${node.value}");
181 }
182
183 visitLabeledStatement(LabeledStatement node) { 219 visitLabeledStatement(LabeledStatement node) {
184 // These do not get added to a block's list of statements. 220 // These do not get added to a block's list of statements.
185 } 221 }
186 222
187 visitAssign(Assign node) { 223 visitAssign(Assign node) {
188 String name = names.varName(node.variable); 224 String name = names.varName(node.variable);
189 String rhs = expr(node.definition); 225 String rhs = expr(node.definition);
190 printStatement(name, "let $name = $rhs"); 226 printStatement(name, "let $name = $rhs");
191 } 227 }
192 228
193 visitInvokeMethod(InvokeMethod node) {
194 printStatement(null, expr(node));
195 }
196
197 visitInvokeConstructor(InvokeConstructor node) {
198 printStatement(null, expr(node));
199 }
200
201 visitConcatenateStrings(ConcatenateStrings node) {
202 printStatement(null, expr(node));
203 }
204
205 visitLiteralList(LiteralList node) {
206 printStatement(null, expr(node));
207 }
208
209 visitLiteralMap(LiteralMap node) {
210 printStatement(null, expr(node));
211 }
212
213 visitInvokeConstConstructor(InvokeConstConstructor node) {
214 printStatement(null, expr(node));
215 }
216
217 visitConditional(Conditional node) {
218 printStatement(null, expr(node));
219 }
220
221 visitLogicalOperator(LogicalOperator node) {
222 printStatement(null, expr(node));
223 }
224
225 visitNot(Not node) {
226 printStatement(null, expr(node));
227 }
228
229 visitReturn(Return node) { 229 visitReturn(Return node) {
230 printStatement(null, "return ${expr(node.value)}"); 230 printStatement(null, "return ${expr(node.value)}");
231 } 231 }
232 232
233 visitBreak(Break node) { 233 visitBreak(Break node) {
234 printStatement(null, "break ${collector.breakTargets[node.target].name}"); 234 printStatement(null, "break ${collector.breakTargets[node.target].name}");
235 } 235 }
236 236
237 visitContinue(Continue node) { 237 visitContinue(Continue node) {
238 printStatement(null, 238 printStatement(null,
239 "continue ${collector.breakTargets[node.target].name}"); 239 "continue ${collector.breakTargets[node.target].name}");
240 } 240 }
241 241
242 visitIf(If node) { 242 visitIf(If node) {
243 String condition = expr(node.condition); 243 String condition = expr(node.condition);
244 String thenTarget = collector.ifTargets[node.thenStatement].name; 244 String thenTarget = collector.ifTargets[node.thenStatement].name;
245 String elseTarget = collector.ifTargets[node.elseStatement].name; 245 String elseTarget = collector.ifTargets[node.elseStatement].name;
246 printStatement(null, "if $condition then $thenTarget else $elseTarget"); 246 printStatement(null, "if $condition then $thenTarget else $elseTarget");
247 } 247 }
248 248
249 visitWhile(While node) { 249 visitWhileTrue(WhileTrue node) {
250 printStatement(null, "while true do"); 250 printStatement(null, "while true do");
251 } 251 }
252 252
253 visitWhileCondition(WhileCondition node) {
254 String bodyTarget = collector.ifTargets[node.body].name;
255 String nextTarget = collector.ifTargets[node.next].name;
256 printStatement(null, "while ${expr(node.condition)}");
257 printStatement(null, "do $bodyTarget");
258 printStatement(null, "then $nextTarget" );
259 }
260
253 visitExpressionStatement(ExpressionStatement node) { 261 visitExpressionStatement(ExpressionStatement node) {
254 visitExpression(node.expression); 262 printStatement(null, expr(node.expression));
255 } 263 }
256 264
257 String expr(Expression e) { 265 String expr(Expression e) {
258 return e.accept(new SubexpressionVisitor(names)); 266 return e.accept(new SubexpressionVisitor(names));
259 } 267 }
260 } 268 }
261 269
262 class SubexpressionVisitor extends Visitor<String, String> { 270 class SubexpressionVisitor extends ExpressionVisitor<String> {
263 Names names; 271 Names names;
264 272
265 SubexpressionVisitor(this.names); 273 SubexpressionVisitor(this.names);
266 274
267 String visitVariable(Variable node) { 275 String visitVariable(Variable node) {
268 return names.varName(node); 276 return names.varName(node);
269 } 277 }
270 278
271 String formatArguments(Invoke node) { 279 String formatArguments(Invoke node) {
272 List<String> args = new List<String>(); 280 List<String> args = new List<String>();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 373 }
366 374
367 String visitNot(Not node) { 375 String visitNot(Not node) {
368 String operand = visitExpression(node.operand); 376 String operand = visitExpression(node.operand);
369 if (usesInfixNotation(node.operand)) { 377 if (usesInfixNotation(node.operand)) {
370 operand = '($operand)'; 378 operand = '($operand)';
371 } 379 }
372 return '!$operand'; 380 return '!$operand';
373 } 381 }
374 382
375 // Note: There should not be statements in the context of expressions.
376 String visitStatement(Statement node) {
377 return "$node statement in expression context";
378 }
379
380 String visitLabeledStatement(LabeledStatement node) => visitStatement(node);
381 String visitAssign(Assign node) => visitStatement(node);
382 String visitReturn(Return node) => visitStatement(node);
383 String visitBreak(Break node) => visitStatement(node);
384 String visitContinue(Continue node) => visitStatement(node);
385 String visitIf(If node) => visitStatement(node);
386 String visitWhile(While node) => visitStatement(node);
387 String visitExpressionStatement(ExpressionStatement node) {
388 return visitStatement(node);
389 }
390 } 383 }
391 384
392 /** 385 /**
393 * Invents (and remembers) names for Variables that do not have an associated 386 * Invents (and remembers) names for Variables that do not have an associated
394 * identifier. 387 * identifier.
395 * 388 *
396 * In case a variable is named v0, v1, etc, it may be assigned a different 389 * In case a variable is named v0, v1, etc, it may be assigned a different
397 * name to avoid clashing with a previously synthesized variable name. 390 * name to avoid clashing with a previously synthesized variable name.
398 */ 391 */
399 class Names { 392 class Names {
(...skipping 10 matching lines...) Expand all
410 } 403 }
411 while (name == null || _usedNames.contains(name)) { 404 while (name == null || _usedNames.contains(name)) {
412 name = "v${_counter++}"; 405 name = "v${_counter++}";
413 } 406 }
414 _names[v] = name; 407 _names[v] = name;
415 _usedNames.add(name); 408 _usedNames.add(name);
416 } 409 }
417 return name; 410 return name;
418 } 411 }
419 } 412 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698