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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/cps_ir/cps_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 dart2js.ir_tracer;
6
7 import 'dart:async' show EventSink;
8
9 import 'cps_ir_nodes.dart' as cps_ir hide Function;
10 import '../tracer.dart';
11
12 /**
13 * If true, show LetCont expressions in output.
14 */
15 const bool IR_TRACE_LET_CONT = false;
16
17 class IRTracer extends TracerUtil implements cps_ir.Visitor {
18 EventSink<String> output;
19
20 IRTracer(this.output);
21
22 visit(cps_ir.Node node) => node.accept(this);
23
24 void traceGraph(String name, cps_ir.FunctionDefinition graph) {
25 tag("cfg", () {
26 printProperty("name", name);
27 visitFunctionDefinition(graph);
28 });
29 }
30
31 // Temporary field used during tree walk
32 Names names;
33
34 visitFunctionDefinition(cps_ir.FunctionDefinition f) {
35 names = new Names();
36 BlockCollector builder = new BlockCollector(names);
37 builder.visit(f);
38
39 printNode(builder.entry);
40 for (Block block in builder.cont2block.values) {
41 printNode(block);
42 }
43 names = null;
44 }
45
46 int countUses(cps_ir.Definition definition) {
47 int count = 0;
48 cps_ir.Reference ref = definition.firstRef;
49 while (ref != null) {
50 ++count;
51 ref = ref.next;
52 }
53 return count;
54 }
55
56 printNode(Block block) {
57 tag("block", () {
58 printProperty("name", block.name);
59 printProperty("from_bci", -1);
60 printProperty("to_bci", -1);
61 printProperty("predecessors", block.pred.map((n) => n.name));
62 printProperty("successors", block.succ.map((n) => n.name));
63 printEmptyProperty("xhandlers");
64 printEmptyProperty("flags");
65 tag("states", () {
66 tag("locals", () {
67 printProperty("size", 0);
68 printProperty("method", "None");
69 });
70 });
71 tag("HIR", () {
72 for (cps_ir.Parameter param in block.parameters) {
73 String name = names.name(param);
74 printStmt(name, "Parameter $name [useCount=${countUses(param)}]");
75 }
76 visit(block.body);
77 });
78 });
79 }
80
81 void printStmt(String resultVar, String contents) {
82 int bci = 0;
83 int uses = 0;
84 addIndent();
85 add("$bci $uses $resultVar $contents <|@\n");
86 }
87
88 visitLetPrim(cps_ir.LetPrim node) {
89 String id = names.name(node.primitive);
90 printStmt(id, "LetPrim $id = ${formatPrimitive(node.primitive)}");
91 visit(node.body);
92 }
93
94 visitLetCont(cps_ir.LetCont node) {
95 if (IR_TRACE_LET_CONT) {
96 String dummy = names.name(node);
97 String id = names.name(node.continuation);
98 printStmt(dummy, "LetCont $id = <$id>");
99 }
100 visit(node.body);
101 }
102
103 visitInvokeStatic(cps_ir.InvokeStatic node) {
104 String dummy = names.name(node);
105 String callName = node.selector.name;
106 String args = node.arguments.map(formatReference).join(', ');
107 String kont = formatReference(node.continuation);
108 printStmt(dummy, "InvokeStatic $callName ($args) $kont");
109 }
110
111 visitInvokeMethod(cps_ir.InvokeMethod node) {
112 String dummy = names.name(node);
113 String receiver = formatReference(node.receiver);
114 String callName = node.selector.name;
115 String args = node.arguments.map(formatReference).join(', ');
116 String kont = formatReference(node.continuation);
117 printStmt(dummy,
118 "InvokeMethod $receiver $callName ($args) $kont");
119 }
120
121 visitInvokeSuperMethod(cps_ir.InvokeSuperMethod node) {
122 String dummy = names.name(node);
123 String callName = node.selector.name;
124 String args = node.arguments.map(formatReference).join(', ');
125 String kont = formatReference(node.continuation);
126 printStmt(dummy,
127 "InvokeSuperMethod $callName ($args) $kont");
128 }
129
130 visitInvokeConstructor(cps_ir.InvokeConstructor node) {
131 String dummy = names.name(node);
132 String callName;
133 if (node.target.name.isEmpty) {
134 callName = '${node.type}';
135 } else {
136 callName = '${node.type}.${node.target.name}';
137 }
138 String args = node.arguments.map(formatReference).join(', ');
139 String kont = formatReference(node.continuation);
140 printStmt(dummy, "InvokeConstructor $callName ($args) $kont");
141 }
142
143 visitConcatenateStrings(cps_ir.ConcatenateStrings node) {
144 String dummy = names.name(node);
145 String args = node.arguments.map(formatReference).join(', ');
146 String kont = formatReference(node.continuation);
147 printStmt(dummy, "ConcatenateStrings ($args) $kont");
148 }
149
150 visitLiteralList(cps_ir.LiteralList node) {
151 String dummy = names.name(node);
152 String values = node.values.map(formatReference).join(', ');
153 printStmt(dummy, "LiteralList ($values)");
154 }
155
156 visitLiteralMap(cps_ir.LiteralMap node) {
157 String dummy = names.name(node);
158 List<String> entries = new List<String>();
159 for (cps_ir.LiteralMapEntry entry in node.entries) {
160 String key = formatReference(entry.key);
161 String value = formatReference(entry.value);
162 entries.add("$key: $value");
163 }
164 printStmt(dummy, "LiteralMap (${entries.join(', ')})");
165 }
166
167 visitTypeOperator(cps_ir.TypeOperator node) {
168 String dummy = names.name(node);
169 String operator = node.isTypeTest ? 'is' : 'as';
170 List<String> entries = new List<String>();
171 String receiver = formatReference(node.receiver);
172 printStmt(dummy, "TypeOperator ($operator $receiver ${node.type})");
173 }
174
175 visitInvokeContinuation(cps_ir.InvokeContinuation node) {
176 String dummy = names.name(node);
177 String kont = formatReference(node.continuation);
178 String args = node.arguments.map(formatReference).join(', ');
179 printStmt(dummy, "InvokeContinuation $kont ($args)");
180 }
181
182 visitBranch(cps_ir.Branch node) {
183 String dummy = names.name(node);
184 String condition = visit(node.condition);
185 String trueCont = formatReference(node.trueContinuation);
186 String falseCont = formatReference(node.falseContinuation);
187 printStmt(dummy, "Branch $condition ($trueCont, $falseCont)");
188 }
189
190 visitSetClosureVariable(cps_ir.SetClosureVariable node) {
191 String dummy = names.name(node);
192 String variable = node.variable.name;
193 String value = formatReference(node.value);
194 printStmt(dummy, 'SetClosureVariable $variable = $value');
195 visit(node.body);
196 }
197
198 visitDeclareFunction(cps_ir.DeclareFunction node) {
199 String dummy = names.name(node);
200 String variable = node.variable.name;
201 printStmt(dummy, 'DeclareFunction $variable');
202 visit(node.body);
203 }
204
205 String formatReference(cps_ir.Reference ref) {
206 cps_ir.Definition target = ref.definition;
207 if (target is cps_ir.Continuation && target.isReturnContinuation) {
208 return "return"; // Do not generate a name for the return continuation
209 } else {
210 return names.name(ref.definition);
211 }
212 }
213
214 String formatPrimitive(cps_ir.Primitive p) => visit(p);
215
216 visitConstant(cps_ir.Constant node) {
217 return "Constant ${node.expression.value}";
218 }
219
220 visitParameter(cps_ir.Parameter node) {
221 return "Parameter ${names.name(node)}";
222 }
223
224 visitContinuation(cps_ir.Continuation node) {
225 return "Continuation ${names.name(node)}";
226 }
227
228 visitIsTrue(cps_ir.IsTrue node) {
229 return "IsTrue(${names.name(node.value.definition)})";
230 }
231
232 visitThis(cps_ir.This node) {
233 return "This";
234 }
235
236 visitReifyTypeVar(cps_ir.ReifyTypeVar node) {
237 return "ReifyTypeVar ${node.typeVariable.name}";
238 }
239
240 visitCreateFunction(cps_ir.CreateFunction node) {
241 return "CreateFunction ${node.definition.element.name}";
242 }
243
244 visitGetClosureVariable(cps_ir.GetClosureVariable node) {
245 String variable = node.variable.name;
246 return 'GetClosureVariable $variable';
247 }
248
249
250 visitCondition(cps_ir.Condition c) {}
251 visitExpression(cps_ir.Expression e) {}
252 visitPrimitive(cps_ir.Primitive p) {}
253 visitDefinition(cps_ir.Definition d) {}
254 visitNode(cps_ir.Node n) {}
255 }
256
257 /**
258 * Invents (and remembers) names for Continuations, Parameters, etc.
259 * The names must match the conventions used by IR Hydra, e.g.
260 * Continuations and Functions must have names of form B### since they
261 * are visualized as basic blocks.
262 */
263 class Names {
264 final Map<Object, String> names = {};
265 final Map<String, int> counters = {
266 'r': 0,
267 'B': 0,
268 'v': 0,
269 'x': 0
270 };
271
272 String prefix(x) {
273 if (x is cps_ir.Parameter) return 'r';
274 if (x is cps_ir.Continuation || x is cps_ir.FunctionDefinition) return 'B';
275 if (x is cps_ir.Primitive) return 'v';
276 return 'x';
277 }
278
279 String name(x) {
280 String nam = names[x];
281 if (nam == null) {
282 String pref = prefix(x);
283 int id = counters[pref]++;
284 nam = names[x] = '${pref}${id}';
285 }
286 return nam;
287 }
288 }
289
290 /**
291 * A vertex in the graph visualization, used in place of basic blocks.
292 */
293 class Block {
294 String name;
295 final List<cps_ir.Parameter> parameters;
296 final cps_ir.Expression body;
297 final List<Block> succ = <Block>[];
298 final List<Block> pred = <Block>[];
299
300 Block(this.name, this.parameters, this.body);
301
302 void addEdgeTo(Block successor) {
303 succ.add(successor);
304 successor.pred.add(this);
305 }
306 }
307
308 class BlockCollector extends cps_ir.Visitor {
309 Block entry;
310 final Map<cps_ir.Continuation, Block> cont2block =
311 <cps_ir.Continuation, Block>{};
312 Block current_block;
313
314 Names names;
315 BlockCollector(this.names);
316
317 Block getBlock(cps_ir.Continuation c) {
318 Block block = cont2block[c];
319 if (block == null) {
320 block = new Block(names.name(c), c.parameters, c.body);
321 cont2block[c] = block;
322 }
323 return block;
324 }
325
326 visitFunctionDefinition(cps_ir.FunctionDefinition f) {
327 entry = current_block = new Block(names.name(f), [], f.body);
328 visit(f.body);
329 }
330
331 visitLetPrim(cps_ir.LetPrim exp) {
332 visit(exp.body);
333 }
334
335 visitLetCont(cps_ir.LetCont exp) {
336 visit(exp.continuation);
337 visit(exp.body);
338 }
339
340 void addEdgeToContinuation(cps_ir.Reference continuation) {
341 cps_ir.Definition target = continuation.definition;
342 if (target is cps_ir.Continuation && !target.isReturnContinuation) {
343 current_block.addEdgeTo(getBlock(target));
344 }
345 }
346
347 visitInvokeStatic(cps_ir.InvokeStatic exp) {
348 addEdgeToContinuation(exp.continuation);
349 }
350
351 visitInvokeMethod(cps_ir.InvokeMethod exp) {
352 addEdgeToContinuation(exp.continuation);
353 }
354
355 visitInvokeConstructor(cps_ir.InvokeConstructor exp) {
356 addEdgeToContinuation(exp.continuation);
357 }
358
359 visitConcatenateStrings(cps_ir.ConcatenateStrings exp) {
360 addEdgeToContinuation(exp.continuation);
361 }
362
363 visitInvokeContinuation(cps_ir.InvokeContinuation exp) {
364 addEdgeToContinuation(exp.continuation);
365 }
366
367 visitSetClosureVariable(cps_ir.SetClosureVariable exp) {
368 visit(exp.body);
369 }
370
371 visitDeclareFunction(cps_ir.DeclareFunction exp) {
372 visit(exp.body);
373 }
374
375 visitBranch(cps_ir.Branch exp) {
376 cps_ir.Continuation trueTarget = exp.trueContinuation.definition;
377 if (!trueTarget.isReturnContinuation) {
378 current_block.addEdgeTo(getBlock(trueTarget));
379 }
380 cps_ir.Continuation falseTarget = exp.falseContinuation.definition;
381 if (!falseTarget.isReturnContinuation) {
382 current_block.addEdgeTo(getBlock(falseTarget));
383 }
384 }
385
386 visitContinuation(cps_ir.Continuation c) {
387 var old_node = current_block;
388 current_block = getBlock(c);
389 visit(c.body);
390 current_block = old_node;
391 }
392 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698