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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart

Issue 2246623002: Delete CPS IR (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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
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 '../tracer.dart';
10 import 'cps_ir_nodes.dart' as cps_ir;
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 node) {
25 tag("cfg", () {
26 printProperty("name", name);
27
28 names = new Names();
29 BlockCollector builder = new BlockCollector(names);
30 builder.visit(node);
31
32 for (Block block in builder.entries) {
33 printBlock(block, entryPoint: node);
34 }
35 for (Block block in builder.cont2block.values) {
36 printBlock(block);
37 }
38 names = null;
39 });
40 }
41
42 // Temporary field used during tree walk
43 Names names;
44
45 visitFunctionDefinition(cps_ir.FunctionDefinition node) {
46 unexpectedNode(node);
47 }
48
49 // Bodies and initializers are not visited. They contain continuations which
50 // are found by a BlockCollector, then those continuations are processed by
51 // this visitor.
52 unexpectedNode(cps_ir.Node node) {
53 throw 'The IR tracer reached an unexpected IR instruction: $node';
54 }
55
56 int countUses(cps_ir.Definition definition) {
57 int count = 0;
58 cps_ir.Reference ref = definition.firstRef;
59 while (ref != null) {
60 ++count;
61 ref = ref.next;
62 }
63 return count;
64 }
65
66 /// If [entryPoint] is given, this block is an entry point.
67 printBlock(Block block, {cps_ir.FunctionDefinition entryPoint}) {
68 tag("block", () {
69 printProperty("name", block.name);
70 printProperty("from_bci", -1);
71 printProperty("to_bci", -1);
72 printProperty("predecessors", block.pred.map((n) => n.name));
73 printProperty("successors", block.succ.map((n) => n.name));
74 printEmptyProperty("xhandlers");
75 printEmptyProperty("flags");
76 tag("states", () {
77 tag("locals", () {
78 printProperty("size", 0);
79 printProperty("method", "None");
80 });
81 });
82 tag("HIR", () {
83 String formatParameter(cps_ir.Parameter param) {
84 return '${names.name(param)} ${param.type}';
85 }
86
87 if (entryPoint != null) {
88 String thisParam = entryPoint.receiverParameter != null
89 ? formatParameter(entryPoint.receiverParameter)
90 : 'no receiver';
91 String interceptorParam = entryPoint.interceptorParameter != null
92 ? formatParameter(entryPoint.interceptorParameter)
93 : 'no interceptor';
94 String params = entryPoint.parameters.map(formatParameter).join(', ');
95 printStmt('x0', 'Entry ($interceptorParam) ($thisParam) ($params)');
96 }
97 String params = block.parameters.map(formatParameter).join(', ');
98 printStmt('x0', 'Parameters ($params)');
99 visit(block.body);
100 });
101 });
102 }
103
104 void printStmt(String resultVar, String contents) {
105 int bci = 0;
106 int uses = 0;
107 addIndent();
108 add("$bci $uses $resultVar $contents <|@\n");
109 }
110
111 visitLetPrim(cps_ir.LetPrim node) {
112 String id = names.name(node.primitive);
113 String primitive = visit(node.primitive);
114 printStmt(id, "LetPrim $id = $primitive [type=${node.primitive.type}]");
115 visit(node.body);
116 }
117
118 visitLetCont(cps_ir.LetCont node) {
119 if (IR_TRACE_LET_CONT) {
120 String dummy = names.name(node);
121
122 String nameContinuation(cps_ir.Continuation cont) {
123 String name = names.name(cont);
124 return cont.isRecursive ? '$name*' : name;
125 }
126
127 String ids = node.continuations.map(nameContinuation).join(', ');
128 printStmt(dummy, "LetCont $ids");
129 }
130 visit(node.body);
131 }
132
133 visitLetHandler(cps_ir.LetHandler node) {
134 if (IR_TRACE_LET_CONT) {
135 String dummy = names.name(node);
136 String id = names.name(node.handler);
137 printStmt(dummy, "LetHandler $id = <$id>");
138 }
139 visit(node.body);
140 }
141
142 visitLetMutable(cps_ir.LetMutable node) {
143 String id = names.name(node.variable);
144 printStmt(id, "LetMutable $id = ${formatReference(node.valueRef)}");
145 visit(node.body);
146 }
147
148 visitInvokeStatic(cps_ir.InvokeStatic node) {
149 String callName = node.selector.name;
150 String args = node.argumentRefs.map(formatReference).join(', ');
151 return "InvokeStatic $callName ($args)";
152 }
153
154 visitInvokeMethod(cps_ir.InvokeMethod node) {
155 String receiver = formatReference(node.receiverRef);
156 String callName = node.selector.name;
157 String args = node.argumentRefs.map(formatReference).join(', ');
158 return "InvokeMethod $receiver $callName ($args)";
159 }
160
161 visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
162 String receiver = formatReference(node.receiverRef);
163 String callName = node.selector.name;
164 String args = node.argumentRefs.map(formatReference).join(', ');
165 return "InvokeMethodDirectly $receiver $callName ($args)";
166 }
167
168 visitInvokeConstructor(cps_ir.InvokeConstructor node) {
169 String className = node.target.enclosingClass.name;
170 String callName;
171 if (node.target.name.isEmpty) {
172 callName = '${className}';
173 } else {
174 callName = '${className}.${node.target.name}';
175 }
176 String args = node.argumentRefs.map(formatReference).join(', ');
177 return "InvokeConstructor $callName ($args)";
178 }
179
180 visitThrow(cps_ir.Throw node) {
181 String dummy = names.name(node);
182 String value = formatReference(node.valueRef);
183 printStmt(dummy, "Throw $value");
184 }
185
186 visitRethrow(cps_ir.Rethrow node) {
187 String dummy = names.name(node);
188 printStmt(dummy, "Rethrow");
189 }
190
191 visitUnreachable(cps_ir.Unreachable node) {
192 String dummy = names.name(node);
193 printStmt(dummy, 'Unreachable');
194 }
195
196 visitLiteralList(cps_ir.LiteralList node) {
197 String values = node.valueRefs.map(formatReference).join(', ');
198 return "LiteralList ($values)";
199 }
200
201 visitTypeCast(cps_ir.TypeCast node) {
202 String value = formatReference(node.valueRef);
203 String args = node.typeArgumentRefs.map(formatReference).join(', ');
204 return "TypeCast ($value ${node.dartType} ($args))";
205 }
206
207 visitInvokeContinuation(cps_ir.InvokeContinuation node) {
208 String dummy = names.name(node);
209 String kont = formatReference(node.continuationRef);
210 String args = node.argumentRefs.map(formatReference).join(', ');
211 printStmt(dummy, "InvokeContinuation $kont ($args)");
212 }
213
214 visitBranch(cps_ir.Branch node) {
215 String dummy = names.name(node);
216 String condition = formatReference(node.conditionRef);
217 String trueCont = formatReference(node.trueContinuationRef);
218 String falseCont = formatReference(node.falseContinuationRef);
219 String strict = node.isStrictCheck ? "Strict" : "NonStrict";
220 printStmt(dummy, "Branch $condition ($trueCont, $falseCont) $strict");
221 }
222
223 visitAwait(cps_ir.Await node) {
224 String value = formatReference(node.inputRef);
225 return 'Await $value';
226 }
227
228 visitYield(cps_ir.Yield node) {
229 String name = node.hasStar ? 'YieldStar' : 'Yield';
230 String value = formatReference(node.inputRef);
231 return '$name $value';
232 }
233
234 visitSetMutable(cps_ir.SetMutable node) {
235 String variable = names.name(node.variable);
236 String value = formatReference(node.valueRef);
237 return 'SetMutable $variable := $value';
238 }
239
240 String formatReference(cps_ir.Reference ref) {
241 if (ref == null) return 'null';
242 cps_ir.Definition target = ref.definition;
243 if (target is cps_ir.Continuation && target.isReturnContinuation) {
244 return "return"; // Do not generate a name for the return continuation
245 } else {
246 return names.name(ref.definition);
247 }
248 }
249
250 visitConstant(cps_ir.Constant node) {
251 return "Constant ${node.value.toStructuredText()}";
252 }
253
254 visitParameter(cps_ir.Parameter node) {
255 return "Parameter ${names.name(node)}";
256 }
257
258 visitMutableVariable(cps_ir.MutableVariable node) {
259 return "MutableVariable ${names.name(node)}";
260 }
261
262 visitContinuation(cps_ir.Continuation node) {
263 return "Continuation ${names.name(node)}";
264 }
265
266 visitSetField(cps_ir.SetField node) {
267 String object = formatReference(node.objectRef);
268 String field = node.field.name;
269 String value = formatReference(node.valueRef);
270 return 'SetField $object.$field = $value';
271 }
272
273 visitGetField(cps_ir.GetField node) {
274 String object = formatReference(node.objectRef);
275 String field = node.field.name;
276 String finalFlag = node.isFinal ? 'final' : 'non-final';
277 return 'GetField $object.$field $finalFlag';
278 }
279
280 visitGetStatic(cps_ir.GetStatic node) {
281 String element = node.element.name;
282 String finalFlag = node.isFinal ? 'final' : 'non-final';
283 return 'GetStatic $element $finalFlag';
284 }
285
286 visitSetStatic(cps_ir.SetStatic node) {
287 String element = node.element.name;
288 String value = formatReference(node.valueRef);
289 return 'SetStatic $element = $value';
290 }
291
292 visitGetLazyStatic(cps_ir.GetLazyStatic node) {
293 String element = node.element.name;
294 String finalFlag = node.isFinal ? 'final' : 'non-final';
295 return "GetLazyStatic $element $finalFlag";
296 }
297
298 visitCreateBox(cps_ir.CreateBox node) {
299 return 'CreateBox';
300 }
301
302 visitCreateInstance(cps_ir.CreateInstance node) {
303 String className = node.classElement.name;
304 String arguments = node.argumentRefs.map(formatReference).join(', ');
305 String typeInformation = formatReference(node.typeInformationRef);
306 return 'CreateInstance $className ($arguments) <$typeInformation>';
307 }
308
309 visitInterceptor(cps_ir.Interceptor node) {
310 return 'Interceptor(${formatReference(node.inputRef)}, '
311 '${node.interceptedClasses})';
312 }
313
314 visitGetMutable(cps_ir.GetMutable node) {
315 String variable = names.name(node.variable);
316 return 'GetMutable $variable';
317 }
318
319 visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
320 return "ReadTypeVariable ${node.variable.element} "
321 "${formatReference(node.targetRef)}";
322 }
323
324 visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
325 return "ReifyRuntimeType ${formatReference(node.valueRef)}";
326 }
327
328 visitTypeExpression(cps_ir.TypeExpression node) {
329 return "TypeExpression ${node.kindAsString} ${node.dartType}"
330 "${node.argumentRefs.map(formatReference).join(', ')}";
331 }
332
333 visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
334 String args = node.argumentRefs.map(formatReference).join(', ');
335 return "CreateInvocationMirror(${node.selector.name}, $args)";
336 }
337
338 visitTypeTest(cps_ir.TypeTest node) {
339 String value = formatReference(node.valueRef);
340 String args = node.typeArgumentRefs.map(formatReference).join(', ');
341 return "TypeTest ($value ${node.dartType} ($args))";
342 }
343
344 visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
345 String interceptor = formatReference(node.interceptorRef);
346 return "TypeTestViaFlag ($interceptor ${node.dartType})";
347 }
348
349 visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
350 String operator = node.operator.toString();
351 String args = node.argumentRefs.map(formatReference).join(', ');
352 return 'ApplyBuiltinOperator $operator ($args)';
353 }
354
355 visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
356 String method = node.method.toString();
357 String receiver = formatReference(node.receiverRef);
358 String args = node.argumentRefs.map(formatReference).join(', ');
359 return 'ApplyBuiltinMethod $method $receiver ($args)';
360 }
361
362 visitForeignCode(cps_ir.ForeignCode node) {
363 String id = names.name(node);
364 String arguments = node.argumentRefs.map(formatReference).join(', ');
365 printStmt(
366 id, "ForeignCode ${node.type} ${node.codeTemplate.source} $arguments");
367 }
368
369 visitGetLength(cps_ir.GetLength node) {
370 String object = formatReference(node.objectRef);
371 String finalFlag = node.isFinal ? 'final' : 'non-final';
372 return 'GetLength $object $finalFlag';
373 }
374
375 visitGetIndex(cps_ir.GetIndex node) {
376 String object = formatReference(node.objectRef);
377 String index = formatReference(node.indexRef);
378 return 'GetIndex $object $index';
379 }
380
381 visitSetIndex(cps_ir.SetIndex node) {
382 String object = formatReference(node.objectRef);
383 String index = formatReference(node.indexRef);
384 String value = formatReference(node.valueRef);
385 return 'SetIndex $object $index $value';
386 }
387
388 visitRefinement(cps_ir.Refinement node) {
389 String value = formatReference(node.value);
390 return 'Refinement $value ${node.refineType}';
391 }
392
393 visitBoundsCheck(cps_ir.BoundsCheck node) {
394 String object = formatReference(node.objectRef);
395 String index =
396 node.indexRef == null ? 'no-index' : formatReference(node.indexRef);
397 String length =
398 node.lengthRef == null ? 'no-length' : formatReference(node.lengthRef);
399 return 'BoundsCheck $object $index $length ${node.checkString}';
400 }
401
402 visitReceiverCheck(cps_ir.ReceiverCheck node) {
403 String value = formatReference(node.valueRef);
404 String condition = formatReference(node.conditionRef);
405 return 'ReceiverCheck $value $condition ${node.selector} '
406 '${node.flagString}';
407 }
408 }
409
410 /**
411 * Invents (and remembers) names for Continuations, Parameters, etc.
412 * The names must match the conventions used by IR Hydra, e.g.
413 * Continuations and Functions must have names of form B### since they
414 * are visualized as basic blocks.
415 */
416 class Names {
417 final Map<Object, String> names = {};
418 final Map<String, int> counters = {'r': 0, 'B': 0, 'v': 0, 'x': 0, 'c': 0};
419
420 String prefix(x) {
421 if (x is cps_ir.Parameter) return 'r';
422 if (x is cps_ir.Continuation || x is cps_ir.FunctionDefinition) return 'B';
423 if (x is cps_ir.Primitive) return 'v';
424 if (x is cps_ir.MutableVariable) return 'c';
425 return 'x';
426 }
427
428 String name(x) {
429 String nam = names[x];
430 if (nam == null) {
431 String pref = prefix(x);
432 int id = counters[pref]++;
433 nam = names[x] = '${pref}${id}';
434 }
435 return nam;
436 }
437 }
438
439 /**
440 * A vertex in the graph visualization, used in place of basic blocks.
441 */
442 class Block {
443 String name;
444 final List<cps_ir.Parameter> parameters;
445 final cps_ir.Expression body;
446 final List<Block> succ = <Block>[];
447 final List<Block> pred = <Block>[];
448
449 Block(this.name, this.parameters, this.body);
450
451 void addEdgeTo(Block successor) {
452 succ.add(successor);
453 successor.pred.add(this);
454 }
455 }
456
457 class BlockCollector implements cps_ir.Visitor {
458 final Map<cps_ir.Continuation, Block> cont2block =
459 <cps_ir.Continuation, Block>{};
460 final Set<Block> entries = new Set<Block>();
461 Block currentBlock;
462
463 Names names;
464 BlockCollector(this.names);
465
466 Block getBlock(cps_ir.Continuation c) {
467 Block block = cont2block[c];
468 if (block == null) {
469 block = new Block(names.name(c), c.parameters, c.body);
470 cont2block[c] = block;
471 }
472 return block;
473 }
474
475 visit(cps_ir.Node node) => node.accept(this);
476
477 visitFunctionDefinition(cps_ir.FunctionDefinition node) {
478 currentBlock = new Block(names.name(node), [], node.body);
479 entries.add(currentBlock);
480 visit(node.body);
481 }
482
483 visitLetPrim(cps_ir.LetPrim exp) {
484 visit(exp.body);
485 }
486
487 visitLetCont(cps_ir.LetCont exp) {
488 exp.continuations.forEach(visit);
489 visit(exp.body);
490 }
491
492 visitLetHandler(cps_ir.LetHandler exp) {
493 visit(exp.handler);
494 visit(exp.body);
495 }
496
497 visitLetMutable(cps_ir.LetMutable exp) {
498 visit(exp.body);
499 }
500
501 void addEdgeToContinuation(cps_ir.Reference continuation) {
502 cps_ir.Definition target = continuation.definition;
503 if (target is cps_ir.Continuation && !target.isReturnContinuation) {
504 currentBlock.addEdgeTo(getBlock(target));
505 }
506 }
507
508 visitInvokeContinuation(cps_ir.InvokeContinuation exp) {
509 addEdgeToContinuation(exp.continuationRef);
510 }
511
512 visitInvokeStatic(cps_ir.InvokeStatic node) {
513 unexpectedNode(node);
514 }
515
516 visitInvokeMethod(cps_ir.InvokeMethod node) {
517 unexpectedNode(node);
518 }
519
520 visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
521 unexpectedNode(node);
522 }
523
524 visitInvokeConstructor(cps_ir.InvokeConstructor node) {
525 unexpectedNode(node);
526 }
527
528 visitThrow(cps_ir.Throw exp) {}
529
530 visitRethrow(cps_ir.Rethrow exp) {}
531
532 visitUnreachable(cps_ir.Unreachable node) {}
533
534 visitGetLazyStatic(cps_ir.GetLazyStatic node) {
535 unexpectedNode(node);
536 }
537
538 visitBranch(cps_ir.Branch exp) {
539 cps_ir.Continuation trueTarget = exp.trueContinuation;
540 if (!trueTarget.isReturnContinuation) {
541 currentBlock.addEdgeTo(getBlock(trueTarget));
542 }
543 cps_ir.Continuation falseTarget = exp.falseContinuation;
544 if (!falseTarget.isReturnContinuation) {
545 currentBlock.addEdgeTo(getBlock(falseTarget));
546 }
547 }
548
549 visitTypeCast(cps_ir.TypeCast node) {
550 unexpectedNode(node);
551 }
552
553 visitContinuation(cps_ir.Continuation c) {
554 var old_node = currentBlock;
555 currentBlock = getBlock(c);
556 visit(c.body);
557 currentBlock = old_node;
558 }
559
560 // Primitives and conditions are not visited when searching for blocks.
561 unexpectedNode(cps_ir.Node node) {
562 throw "The IR tracer's block collector reached an unexpected IR "
563 "instruction: $node";
564 }
565
566 visitLiteralList(cps_ir.LiteralList node) {
567 unexpectedNode(node);
568 }
569
570 visitConstant(cps_ir.Constant node) {
571 unexpectedNode(node);
572 }
573
574 visitGetMutable(cps_ir.GetMutable node) {
575 unexpectedNode(node);
576 }
577
578 visitParameter(cps_ir.Parameter node) {
579 unexpectedNode(node);
580 }
581
582 visitMutableVariable(cps_ir.MutableVariable node) {
583 unexpectedNode(node);
584 }
585
586 visitGetField(cps_ir.GetField node) {
587 unexpectedNode(node);
588 }
589
590 visitGetStatic(cps_ir.GetStatic node) {
591 unexpectedNode(node);
592 }
593
594 visitCreateBox(cps_ir.CreateBox node) {
595 unexpectedNode(node);
596 }
597
598 visitCreateInstance(cps_ir.CreateInstance node) {
599 unexpectedNode(node);
600 }
601
602 visitInterceptor(cps_ir.Interceptor node) {
603 unexpectedNode(node);
604 }
605
606 visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
607 unexpectedNode(node);
608 }
609
610 visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
611 unexpectedNode(node);
612 }
613
614 visitTypeExpression(cps_ir.TypeExpression node) {
615 unexpectedNode(node);
616 }
617
618 visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
619 unexpectedNode(node);
620 }
621
622 visitTypeTest(cps_ir.TypeTest node) {
623 unexpectedNode(node);
624 }
625
626 visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
627 unexpectedNode(node);
628 }
629
630 visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
631 unexpectedNode(node);
632 }
633
634 visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
635 unexpectedNode(node);
636 }
637
638 visitGetLength(cps_ir.GetLength node) {
639 unexpectedNode(node);
640 }
641
642 visitGetIndex(cps_ir.GetIndex node) {
643 unexpectedNode(node);
644 }
645
646 visitSetIndex(cps_ir.SetIndex node) {
647 unexpectedNode(node);
648 }
649
650 visitSetMutable(cps_ir.SetMutable node) {
651 unexpectedNode(node);
652 }
653
654 visitSetField(cps_ir.SetField node) {
655 unexpectedNode(node);
656 }
657
658 visitSetStatic(cps_ir.SetStatic node) {
659 unexpectedNode(node);
660 }
661
662 visitForeignCode(cps_ir.ForeignCode node) {
663 unexpectedNode(node);
664 }
665
666 visitAwait(cps_ir.Await node) {
667 unexpectedNode(node);
668 }
669
670 visitYield(cps_ir.Yield node) {
671 unexpectedNode(node);
672 }
673
674 visitRefinement(cps_ir.Refinement node) {
675 unexpectedNode(node);
676 }
677
678 visitBoundsCheck(cps_ir.BoundsCheck node) {
679 unexpectedNode(node);
680 }
681
682 visitReceiverCheck(cps_ir.ReceiverCheck node) {
683 unexpectedNode(node);
684 }
685 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart ('k') | pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698