| OLD | NEW |
| 1 library dart2js.ir_tracer; | 1 library dart2js.ir_tracer; |
| 2 | 2 |
| 3 import 'dart:async' show EventSink; | 3 import 'dart:async' show EventSink; |
| 4 | 4 |
| 5 import 'ir_nodes.dart' as ir hide Function; | 5 import 'ir_nodes.dart' as ir hide Function; |
| 6 import '../tracer.dart'; | 6 import '../tracer.dart'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * If true, show LetCont expressions in output. | 9 * If true, show LetCont expressions in output. |
| 10 */ | 10 */ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 visitFunctionDefinition(graph); | 24 visitFunctionDefinition(graph); |
| 25 }); | 25 }); |
| 26 } | 26 } |
| 27 | 27 |
| 28 // Temporary field used during tree walk | 28 // Temporary field used during tree walk |
| 29 Names names; | 29 Names names; |
| 30 | 30 |
| 31 visitFunctionDefinition(ir.FunctionDefinition f) { | 31 visitFunctionDefinition(ir.FunctionDefinition f) { |
| 32 names = new Names(); | 32 names = new Names(); |
| 33 BlockCollector builder = new BlockCollector(names); | 33 BlockCollector builder = new BlockCollector(names); |
| 34 f.accept(builder); | 34 builder.visit(f); |
| 35 | 35 |
| 36 printNode(builder.entry); | 36 printNode(builder.entry); |
| 37 for (Block block in builder.cont2block.values) { | 37 for (Block block in builder.cont2block.values) { |
| 38 printNode(block); | 38 printNode(block); |
| 39 } | 39 } |
| 40 names = null; | 40 names = null; |
| 41 } | 41 } |
| 42 | 42 |
| 43 printNode(Block block) { | 43 printNode(Block block) { |
| 44 tag("block", () { | 44 tag("block", () { |
| 45 printProperty("name", block.name); | 45 printProperty("name", block.name); |
| 46 printProperty("from_bci", -1); | 46 printProperty("from_bci", -1); |
| 47 printProperty("to_bci", -1); | 47 printProperty("to_bci", -1); |
| 48 printProperty("predecessors", block.pred.map((n) => n.name)); | 48 printProperty("predecessors", block.pred.map((n) => n.name)); |
| 49 printProperty("successors", block.succ.map((n) => n.name)); | 49 printProperty("successors", block.succ.map((n) => n.name)); |
| 50 printEmptyProperty("xhandlers"); | 50 printEmptyProperty("xhandlers"); |
| 51 printEmptyProperty("flags"); | 51 printEmptyProperty("flags"); |
| 52 tag("states", () { | 52 tag("states", () { |
| 53 tag("locals", () { | 53 tag("locals", () { |
| 54 printProperty("size", 0); | 54 printProperty("size", 0); |
| 55 printProperty("method", "None"); | 55 printProperty("method", "None"); |
| 56 // We could print parameters here, | 56 // We could print parameters here, |
| 57 // but does the hydra tool actually use this info?? | 57 // but does the hydra tool actually use this info?? |
| 58 }); | 58 }); |
| 59 }); | 59 }); |
| 60 tag("HIR", () { | 60 tag("HIR", () { |
| 61 block.body.accept(this); | 61 visit(block.body); |
| 62 }); | 62 }); |
| 63 }); | 63 }); |
| 64 } | 64 } |
| 65 | 65 |
| 66 void printStmt(String resultVar, String contents) { | 66 void printStmt(String resultVar, String contents) { |
| 67 int bci = 0; | 67 int bci = 0; |
| 68 int uses = 0; | 68 int uses = 0; |
| 69 addIndent(); | 69 addIndent(); |
| 70 add("$bci $uses $resultVar $contents <|@\n"); | 70 add("$bci $uses $resultVar $contents <|@\n"); |
| 71 } | 71 } |
| 72 | 72 |
| 73 visitLetPrim(ir.LetPrim node) { | 73 visitLetPrim(ir.LetPrim node) { |
| 74 String id = names.name(node.primitive); | 74 String id = names.name(node.primitive); |
| 75 printStmt(id, "LetPrim $id = ${formatPrimitive(node.primitive)}"); | 75 printStmt(id, "LetPrim $id = ${formatPrimitive(node.primitive)}"); |
| 76 node.body.accept(this); | 76 visit(node.body); |
| 77 } | 77 } |
| 78 | 78 |
| 79 visitLetCont(ir.LetCont node) { | 79 visitLetCont(ir.LetCont node) { |
| 80 if (IR_TRACE_LET_CONT) { | 80 if (IR_TRACE_LET_CONT) { |
| 81 String dummy = names.name(node); | 81 String dummy = names.name(node); |
| 82 String id = names.name(node.continuation); | 82 String id = names.name(node.continuation); |
| 83 printStmt(dummy, "LetCont $id = <$id>"); | 83 printStmt(dummy, "LetCont $id = <$id>"); |
| 84 } | 84 } |
| 85 node.body.accept(this); | 85 visit(node.body); |
| 86 } | 86 } |
| 87 | 87 |
| 88 visitInvokeStatic(ir.InvokeStatic node) { | 88 visitInvokeStatic(ir.InvokeStatic node) { |
| 89 String dummy = names.name(node); | 89 String dummy = names.name(node); |
| 90 String callName = node.selector.name; | 90 String callName = node.selector.name; |
| 91 String args = node.arguments.map(formatReference).join(', '); | 91 String args = node.arguments.map(formatReference).join(', '); |
| 92 String kont = formatReference(node.continuation); | 92 String kont = formatReference(node.continuation); |
| 93 printStmt(dummy, "InvokeStatic $callName ($args) $kont"); | 93 printStmt(dummy, "InvokeStatic $callName ($args) $kont"); |
| 94 } | 94 } |
| 95 | 95 |
| 96 visitInvokeContinuation(ir.InvokeContinuation node) { | 96 visitInvokeContinuation(ir.InvokeContinuation node) { |
| 97 String dummy = names.name(node); | 97 String dummy = names.name(node); |
| 98 String kont = formatReference(node.continuation); | 98 String kont = formatReference(node.continuation); |
| 99 String arg = formatReference(node.argument); | 99 String args = node.arguments.map(formatReference).join(', '); |
| 100 printStmt(dummy, "InvokeContinuation $kont ($arg)"); | 100 printStmt(dummy, "InvokeContinuation $kont ($args)"); |
| 101 } |
| 102 |
| 103 visitBranch(ir.Branch node) { |
| 104 String dummy = names.name(node); |
| 105 String condition = visit(node.condition); |
| 106 String trueCont = formatReference(node.trueContinuation); |
| 107 String falseCont = formatReference(node.falseContinuation); |
| 108 printStmt(dummy, "Branch $condition ($trueCont, $falseCont)"); |
| 101 } | 109 } |
| 102 | 110 |
| 103 String formatReference(ir.Reference ref) { | 111 String formatReference(ir.Reference ref) { |
| 104 ir.Definition target = ref.definition; | 112 ir.Definition target = ref.definition; |
| 105 if (target is ir.Continuation && target.body == null) { | 113 if (target is ir.Continuation && target.body == null) { |
| 106 return "return"; // Do not generate a name for the return continuation | 114 return "return"; // Do not generate a name for the return continuation |
| 107 } else { | 115 } else { |
| 108 return names.name(ref.definition); | 116 return names.name(ref.definition); |
| 109 } | 117 } |
| 110 } | 118 } |
| 111 | 119 |
| 112 String formatPrimitive(ir.Primitive p) { | 120 String formatPrimitive(ir.Primitive p) => visit(p); |
| 113 return p.accept(this); | |
| 114 } | |
| 115 | 121 |
| 116 visitConstant(ir.Constant node) { | 122 visitConstant(ir.Constant node) { |
| 117 return "Constant ${node.value}"; | 123 return "Constant ${node.value}"; |
| 118 } | 124 } |
| 119 | 125 |
| 120 visitParameter(ir.Parameter node) { | 126 visitParameter(ir.Parameter node) { |
| 121 return "Parameter ${names.name(node)}"; | 127 return "Parameter ${names.name(node)}"; |
| 122 } | 128 } |
| 123 | 129 |
| 124 visitContinuation(ir.Continuation node) { | 130 visitContinuation(ir.Continuation node) { |
| 125 return "Continuation ${names.name(node)}"; | 131 return "Continuation ${names.name(node)}"; |
| 126 } | 132 } |
| 127 | 133 |
| 134 visitIsTrue(ir.IsTrue node) { |
| 135 return "IsTrue(${names.name(node)})"; |
| 136 } |
| 137 |
| 138 visitCondition(ir.Condition c) {} |
| 128 visitExpression(ir.Expression e) {} | 139 visitExpression(ir.Expression e) {} |
| 129 visitPrimitive(ir.Primitive p) {} | 140 visitPrimitive(ir.Primitive p) {} |
| 130 visitDefinition(ir.Definition d) {} | 141 visitDefinition(ir.Definition d) {} |
| 131 visitNode(ir.Node n) {} | 142 visitNode(ir.Node n) {} |
| 132 } | 143 } |
| 133 | 144 |
| 134 /** | 145 /** |
| 135 * Invents (and remembers) names for Continuations, Parameters, etc. | 146 * Invents (and remembers) names for Continuations, Parameters, etc. |
| 136 * The names must match the conventions used by IR Hydra, e.g. | 147 * The names must match the conventions used by IR Hydra, e.g. |
| 137 * Continuations and Functions must have names of form B### since they | 148 * Continuations and Functions must have names of form B### since they |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 Block block = cont2block[c]; | 205 Block block = cont2block[c]; |
| 195 if (block == null) { | 206 if (block == null) { |
| 196 block = new Block(names.name(c), c.parameters, c.body); | 207 block = new Block(names.name(c), c.parameters, c.body); |
| 197 cont2block[c] = block; | 208 cont2block[c] = block; |
| 198 } | 209 } |
| 199 return block; | 210 return block; |
| 200 } | 211 } |
| 201 | 212 |
| 202 visitFunctionDefinition(ir.FunctionDefinition f) { | 213 visitFunctionDefinition(ir.FunctionDefinition f) { |
| 203 entry = current_block = new Block(names.name(f), [], f.body); | 214 entry = current_block = new Block(names.name(f), [], f.body); |
| 204 f.body.accept(this); | 215 visit(f.body); |
| 205 } | 216 } |
| 206 | 217 |
| 207 visitLetPrim(ir.LetPrim exp) { | 218 visitLetPrim(ir.LetPrim exp) { |
| 208 exp.body.accept(this); | 219 visit(exp.body); |
| 209 } | 220 } |
| 210 | 221 |
| 211 visitLetCont(ir.LetCont exp) { | 222 visitLetCont(ir.LetCont exp) { |
| 212 exp.continuation.accept(this); | 223 visit(exp.continuation); |
| 213 exp.body.accept(this); | 224 visit(exp.body); |
| 214 } | 225 } |
| 215 | 226 |
| 216 visitInvokeStatic(ir.InvokeStatic exp) { | 227 visitInvokeStatic(ir.InvokeStatic exp) { |
| 217 ir.Definition target = exp.continuation.definition; | 228 ir.Definition target = exp.continuation.definition; |
| 218 if (target is ir.Continuation && target.body != null) { | 229 if (target is ir.Continuation && target.body != null) { |
| 219 current_block.addEdgeTo(getBlock(target)); | 230 current_block.addEdgeTo(getBlock(target)); |
| 220 } | 231 } |
| 221 } | 232 } |
| 222 | 233 |
| 223 visitInvokeContinuation(ir.InvokeContinuation exp) { | 234 visitInvokeContinuation(ir.InvokeContinuation exp) { |
| 224 ir.Definition target = exp.continuation.definition; | 235 ir.Definition target = exp.continuation.definition; |
| 225 if (target is ir.Continuation && target.body != null) { | 236 if (target is ir.Continuation && target.body != null) { |
| 226 current_block.addEdgeTo(getBlock(target)); | 237 current_block.addEdgeTo(getBlock(target)); |
| 227 } | 238 } |
| 228 } | 239 } |
| 229 | 240 |
| 230 visitConstant(ir.Constant constant) {} | 241 visitBranch(ir.Branch exp) { |
| 231 | 242 ir.Continuation trueTarget = exp.trueContinuation.definition; |
| 232 visitParameter(ir.Parameter p) {} | 243 if (trueTarget.body != null) { |
| 244 current_block.addEdgeTo(getBlock(trueTarget)); |
| 245 } |
| 246 ir.Continuation falseTarget = exp.falseContinuation.definition; |
| 247 if (falseTarget.body != null) { |
| 248 current_block.addEdgeTo(getBlock(falseTarget)); |
| 249 } |
| 250 } |
| 233 | 251 |
| 234 visitContinuation(ir.Continuation c) { | 252 visitContinuation(ir.Continuation c) { |
| 235 var old_node = current_block; | 253 var old_node = current_block; |
| 236 current_block = getBlock(c); | 254 current_block = getBlock(c); |
| 237 c.body.accept(this); | 255 visit(c.body); |
| 238 current_block = old_node; | 256 current_block = old_node; |
| 239 } | 257 } |
| 240 } | 258 } |
| OLD | NEW |