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

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

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library tree_ir_tracer;
6
7 import 'dart:async' show EventSink;
8 import '../tracer.dart';
9 import 'tree_ir_nodes.dart';
10
11 class Block {
12 Label label;
13 int index;
14 /// Mixed list of [Statement] and [Block].
15 /// A [Block] represents a synthetic goto statement.
16 final List statements = [];
17 final List<Block> predecessors = <Block>[];
18 final List<Block> successors = <Block>[];
19
20 String get name => 'B$index';
21
22 Block([this.label]);
23
24 void addEdgeTo(Block successor) {
25 successors.add(successor);
26 successor.predecessors.add(this);
27 }
28 }
29
30 class BlockCollector extends StatementVisitor {
31 // Accumulate a list of blocks. The current block is the last block in
32 // the list.
33 final List<Block> blocks = [new Block()..index = 0];
34
35 // Map tree [Label]s (break or continue targets) and [Statement]s
36 // (if targets) to blocks.
37 final Map<Label, Block> breakTargets = <Label, Block>{};
38 final Map<Label, Block> continueTargets = <Label, Block>{};
39 final Map<Statement, Block> ifTargets = <Statement, Block>{};
40
41 void _addStatement(Statement statement) {
42 blocks.last.statements.add(statement);
43 }
44 void _addGotoStatement(Block target) {
45 blocks.last.statements.add(target);
46 }
47
48 void _addBlock(Block block) {
49 block.index = blocks.length;
50 blocks.add(block);
51 }
52
53 void collect(FunctionDefinition function) {
54 visitStatement(function.body);
55 }
56
57 visitLabeledStatement(LabeledStatement node) {
58 Block target = new Block(node.label);
59 breakTargets[node.label] = target;
60 visitStatement(node.body);
61 _addBlock(target);
62 visitStatement(node.next);
63 }
64
65 visitAssign(Assign node) {
66 _addStatement(node);
67 visitStatement(node.next);
68 }
69
70 visitReturn(Return node) {
71 _addStatement(node);
72 }
73
74 visitBreak(Break node) {
75 _addStatement(node);
76 blocks.last.addEdgeTo(breakTargets[node.target]);
77 }
78
79 visitContinue(Continue node) {
80 _addStatement(node);
81 blocks.last.addEdgeTo(continueTargets[node.target]);
82 }
83
84 visitIf(If node) {
85 _addStatement(node);
86 Block thenTarget = new Block();
87 Block elseTarget = new Block();
88 ifTargets[node.thenStatement] = thenTarget;
89 ifTargets[node.elseStatement] = elseTarget;
90 blocks.last.addEdgeTo(thenTarget);
91 blocks.last.addEdgeTo(elseTarget);
92 _addBlock(thenTarget);
93 visitStatement(node.thenStatement);
94 _addBlock(elseTarget);
95 visitStatement(node.elseStatement);
96 }
97
98 visitWhileTrue(WhileTrue node) {
99 Block continueTarget = new Block();
100 _addGotoStatement(continueTarget);
101
102 continueTargets[node.label] = continueTarget;
103 blocks.last.addEdgeTo(continueTarget);
104 _addBlock(continueTarget);
105 _addStatement(node);
106 visitStatement(node.body);
107 }
108
109 visitWhileCondition(WhileCondition node) {
110 Block whileBlock = new Block();
111 _addGotoStatement(whileBlock);
112
113 _addBlock(whileBlock);
114 _addStatement(node);
115 whileBlock.statements.add(node);
116 blocks.last.addEdgeTo(whileBlock);
117
118 Block bodyBlock = new Block();
119 Block nextBlock = new Block();
120 whileBlock.addEdgeTo(bodyBlock);
121 whileBlock.addEdgeTo(nextBlock);
122
123 continueTargets[node.label] = bodyBlock;
124 _addBlock(bodyBlock);
125 visitStatement(node.body);
126
127 _addBlock(nextBlock);
128 visitStatement(node.next);
129
130 ifTargets[node.body] = bodyBlock;
131 ifTargets[node.next] = nextBlock;
132 }
133
134 visitExpressionStatement(ExpressionStatement node) {
135 _addStatement(node);
136 visitStatement(node.next);
137 }
138
139 visitFunctionDeclaration(FunctionDeclaration node) {
140 _addStatement(node);
141 visitStatement(node.next);
142 }
143 }
144
145 class TreeTracer extends TracerUtil with StatementVisitor {
146 final EventSink<String> output;
147
148 TreeTracer(this.output);
149
150 Names names;
151 BlockCollector collector;
152 int statementCounter;
153
154 void traceGraph(String name, FunctionDefinition function) {
155 names = new Names();
156 statementCounter = 0;
157 collector = new BlockCollector();
158 collector.collect(function);
159 tag("cfg", () {
160 printProperty("name", name);
161 int blockCounter = 0;
162 collector.blocks.forEach(printBlock);
163 });
164 names = null;
165 }
166
167 void printBlock(Block block) {
168 tag("block", () {
169 printProperty("name", block.name);
170 printProperty("from_bci", -1);
171 printProperty("to_bci", -1);
172 printProperty("predecessors", block.predecessors.map((b) => b.name));
173 printProperty("successors", block.successors.map((b) => b.name));
174 printEmptyProperty("xhandlers");
175 printEmptyProperty("flags");
176 tag("states", () {
177 tag("locals", () {
178 printProperty("size", 0);
179 printProperty("method", "None");
180 });
181 });
182 tag("HIR", () {
183 if (block.label != null) {
184 printStatement(null,
185 "Label ${block.name}, useCount=${block.label.useCount}");
186 }
187 block.statements.forEach(visitBlockMember);
188 });
189 });
190 }
191
192 void visitBlockMember(member) {
193 if (member is Block) {
194 printStatement(null, "goto block B${member.name}");
195 } else {
196 assert(member is Statement);
197 visitStatement(member);
198 }
199 }
200
201 void printStatement(String name, String contents) {
202 int bci = 0;
203 int uses = 0;
204 if (name == null) {
205 name = 'x${statementCounter++}';
206 }
207 addIndent();
208 add("$bci $uses $name $contents <|@\n");
209 }
210
211 visitLabeledStatement(LabeledStatement node) {
212 // These do not get added to a block's list of statements.
213 }
214
215 visitAssign(Assign node) {
216 String name = names.varName(node.variable);
217 String rhs = expr(node.definition);
218 String extra = node.hasExactlyOneUse ? "[single-use]" : "";
219 printStatement(null, "assign $name = $rhs $extra");
220 }
221
222 visitReturn(Return node) {
223 printStatement(null, "return ${expr(node.value)}");
224 }
225
226 visitBreak(Break node) {
227 printStatement(null, "break ${collector.breakTargets[node.target].name}");
228 }
229
230 visitContinue(Continue node) {
231 printStatement(null,
232 "continue ${collector.continueTargets[node.target].name}");
233 }
234
235 visitIf(If node) {
236 String condition = expr(node.condition);
237 String thenTarget = collector.ifTargets[node.thenStatement].name;
238 String elseTarget = collector.ifTargets[node.elseStatement].name;
239 printStatement(null, "if $condition then $thenTarget else $elseTarget");
240 }
241
242 visitWhileTrue(WhileTrue node) {
243 printStatement(null, "while true do");
244 }
245
246 visitWhileCondition(WhileCondition node) {
247 String bodyTarget = collector.ifTargets[node.body].name;
248 String nextTarget = collector.ifTargets[node.next].name;
249 printStatement(null, "while ${expr(node.condition)}");
250 printStatement(null, "do $bodyTarget");
251 printStatement(null, "then $nextTarget" );
252 }
253
254 visitExpressionStatement(ExpressionStatement node) {
255 printStatement(null, expr(node.expression));
256 }
257
258 visitFunctionDeclaration(FunctionDeclaration node) {
259 printStatement(null, 'function ${node.definition.element.name}');
260 }
261
262 String expr(Expression e) {
263 return e.accept(new SubexpressionVisitor(names));
264 }
265 }
266
267 class SubexpressionVisitor extends ExpressionVisitor<String> {
268 Names names;
269
270 SubexpressionVisitor(this.names);
271
272 String visitVariable(Variable node) {
273 return names.varName(node);
274 }
275
276 String formatArguments(Invoke node) {
277 List<String> args = new List<String>();
278 int positionalArgumentCount = node.selector.positionalArgumentCount;
279 for (int i = 0; i < positionalArgumentCount; ++i) {
280 args.add(node.arguments[i].accept(this));
281 }
282 for (int i = 0; i < node.selector.namedArgumentCount; ++i) {
283 String name = node.selector.namedArguments[i];
284 String arg = node.arguments[positionalArgumentCount + i].accept(this);
285 args.add("$name: $arg");
286 }
287 return args.join(', ');
288 }
289
290 String visitInvokeStatic(InvokeStatic node) {
291 String head = node.target.name;
292 String args = formatArguments(node);
293 return "$head($args)";
294 }
295
296 String visitInvokeMethod(InvokeMethod node) {
297 String receiver = node.receiver.accept(this);
298 String name = node.selector.name;
299 String args = formatArguments(node);
300 return "$receiver.$name($args)";
301 }
302
303 String visitInvokeSuperMethod(InvokeSuperMethod node) {
304 String name = node.selector.name;
305 String args = formatArguments(node);
306 return "super.$name($args)";
307 }
308
309 String visitInvokeConstructor(InvokeConstructor node) {
310 String callName;
311 if (node.target.name.isEmpty) {
312 callName = '${node.type}';
313 } else {
314 callName = '${node.type}.${node.target.name}';
315 }
316 String args = formatArguments(node);
317 String keyword = node.constant != null ? 'const' : 'new';
318 return "$keyword $callName($args)";
319 }
320
321 String visitConcatenateStrings(ConcatenateStrings node) {
322 String args = node.arguments.map(visitExpression).join(', ');
323 return "concat [$args]";
324 }
325
326 String visitLiteralList(LiteralList node) {
327 String values = node.values.map(visitExpression).join(', ');
328 return "list [$values]";
329 }
330
331 String visitLiteralMap(LiteralMap node) {
332 List<String> entries = new List<String>();
333 node.entries.forEach((LiteralMapEntry entry) {
334 String key = visitExpression(entry.key);
335 String value = visitExpression(entry.value);
336 entries.add("$key: $value");
337 });
338 return "map [${entries.join(', ')}]";
339 }
340
341 String visitConstant(Constant node) {
342 return "${node.value}";
343 }
344
345 String visitThis(This node) {
346 return "this";
347 }
348
349 String visitReifyTypeVar(ReifyTypeVar node) {
350 return "typevar [${node.typeVariable.name}]";
351 }
352
353 bool usesInfixNotation(Expression node) {
354 return node is Conditional || node is LogicalOperator;
355 }
356
357 String visitConditional(Conditional node) {
358 String condition = visitExpression(node.condition);
359 String thenExpr = visitExpression(node.thenExpression);
360 String elseExpr = visitExpression(node.elseExpression);
361 return "$condition ? $thenExpr : $elseExpr";
362 }
363
364 String visitLogicalOperator(LogicalOperator node) {
365 String left = visitExpression(node.left);
366 String right = visitExpression(node.right);
367 if (usesInfixNotation(node.left)) {
368 left = "($left)";
369 }
370 if (usesInfixNotation(node.right)) {
371 right = "($right)";
372 }
373 return "$left ${node.operator} $right";
374 }
375
376 String visitTypeOperator(TypeOperator node) {
377 String receiver = visitExpression(node.receiver);
378 String type = "${node.type}";
379 return "TypeOperator $receiver ${node.operator} $type";
380 }
381
382 String visitNot(Not node) {
383 String operand = visitExpression(node.operand);
384 if (usesInfixNotation(node.operand)) {
385 operand = '($operand)';
386 }
387 return '!$operand';
388 }
389
390 String visitFunctionExpression(FunctionExpression node) {
391 return "function ${node.definition.element.name}";
392 }
393
394 }
395
396 /**
397 * Invents (and remembers) names for Variables that do not have an associated
398 * identifier.
399 *
400 * In case a variable is named v0, v1, etc, it may be assigned a different
401 * name to avoid clashing with a previously synthesized variable name.
402 */
403 class Names {
404 final Map<Variable, String> _names = {};
405 final Set<String> _usedNames = new Set();
406 int _counter = 0;
407
408 String varName(Variable v) {
409 String name = _names[v];
410 if (name == null) {
411 String prefix = v.element == null ? 'v' : '${v.element.name}_';
412 while (name == null || _usedNames.contains(name)) {
413 name = "$prefix${_counter++}";
414 }
415 _names[v] = name;
416 _usedNames.add(name);
417 }
418 return name;
419 }
420 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698