| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 ssa.tracer; | 5 library ssa.tracer; |
| 6 | 6 |
| 7 import 'dart:async' show EventSink; | 7 import 'dart:async' show EventSink; |
| 8 | 8 |
| 9 import '../compiler.dart' show Compiler; | |
| 10 import '../diagnostics/invariant.dart' show DEBUG_MODE; | 9 import '../diagnostics/invariant.dart' show DEBUG_MODE; |
| 11 import '../js_backend/js_backend.dart'; | 10 import '../js_backend/namer.dart' show Namer; |
| 12 import '../tracer.dart'; | 11 import '../tracer.dart'; |
| 13 import '../world.dart' show ClosedWorld; | 12 import '../world.dart' show ClosedWorld; |
| 14 import 'nodes.dart'; | 13 import 'nodes.dart'; |
| 15 | 14 |
| 16 /** | 15 /** |
| 17 * Outputs SSA code in a format readable by Hydra IR. | 16 * Outputs SSA code in a format readable by Hydra IR. |
| 18 * Tracing is disabled by default, see ../tracer.dart for how | 17 * Tracing is disabled by default, see ../tracer.dart for how |
| 19 * to enable it. | 18 * to enable it. |
| 20 */ | 19 */ |
| 21 class HTracer extends HGraphVisitor with TracerUtil { | 20 class HTracer extends HGraphVisitor with TracerUtil { |
| 22 Compiler compiler; | 21 final ClosedWorld closedWorld; |
| 22 final Namer namer; |
| 23 final EventSink<String> output; | 23 final EventSink<String> output; |
| 24 | 24 |
| 25 HTracer(this.output, this.compiler); | 25 HTracer(this.output, this.closedWorld, this.namer); |
| 26 | 26 |
| 27 void traceGraph(String name, HGraph graph) { | 27 void traceGraph(String name, HGraph graph) { |
| 28 DEBUG_MODE = true; | 28 DEBUG_MODE = true; |
| 29 tag("cfg", () { | 29 tag("cfg", () { |
| 30 printProperty("name", name); | 30 printProperty("name", name); |
| 31 visitDominatorTree(graph); | 31 visitDominatorTree(graph); |
| 32 }); | 32 }); |
| 33 } | 33 } |
| 34 | 34 |
| 35 void addPredecessors(HBasicBlock block) { | 35 void addPredecessors(HBasicBlock block) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 String depends = instruction.sideEffects.dependsOnSomething() ? '?' : ''; | 69 String depends = instruction.sideEffects.dependsOnSomething() ? '?' : ''; |
| 70 addIndent(); | 70 addIndent(); |
| 71 String temporaryId = stringifier.temporaryId(instruction); | 71 String temporaryId = stringifier.temporaryId(instruction); |
| 72 String instructionString = stringifier.visit(instruction); | 72 String instructionString = stringifier.visit(instruction); |
| 73 add("$bci $uses $temporaryId $instructionString $changes $depends <|@\n"); | 73 add("$bci $uses $temporaryId $instructionString $changes $depends <|@\n"); |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 | 76 |
| 77 void visitBasicBlock(HBasicBlock block) { | 77 void visitBasicBlock(HBasicBlock block) { |
| 78 HInstructionStringifier stringifier = | 78 HInstructionStringifier stringifier = |
| 79 new HInstructionStringifier(block, compiler); | 79 new HInstructionStringifier(block, closedWorld, namer); |
| 80 assert(block.id != null); | 80 assert(block.id != null); |
| 81 tag("block", () { | 81 tag("block", () { |
| 82 printProperty("name", "B${block.id}"); | 82 printProperty("name", "B${block.id}"); |
| 83 printProperty("from_bci", -1); | 83 printProperty("from_bci", -1); |
| 84 printProperty("to_bci", -1); | 84 printProperty("to_bci", -1); |
| 85 addPredecessors(block); | 85 addPredecessors(block); |
| 86 addSuccessors(block); | 86 addSuccessors(block); |
| 87 printEmptyProperty("xhandlers"); | 87 printEmptyProperty("xhandlers"); |
| 88 printEmptyProperty("flags"); | 88 printEmptyProperty("flags"); |
| 89 if (block.dominator != null) { | 89 if (block.dominator != null) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 106 }); | 106 }); |
| 107 tag("HIR", () { | 107 tag("HIR", () { |
| 108 addInstructions(stringifier, block.phis); | 108 addInstructions(stringifier, block.phis); |
| 109 addInstructions(stringifier, block); | 109 addInstructions(stringifier, block); |
| 110 }); | 110 }); |
| 111 }); | 111 }); |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 | 114 |
| 115 class HInstructionStringifier implements HVisitor<String> { | 115 class HInstructionStringifier implements HVisitor<String> { |
| 116 final Compiler compiler; | 116 final ClosedWorld closedWorld; |
| 117 final Namer namer; |
| 117 final HBasicBlock currentBlock; | 118 final HBasicBlock currentBlock; |
| 118 | 119 |
| 119 HInstructionStringifier(this.currentBlock, this.compiler); | 120 HInstructionStringifier(this.currentBlock, this.closedWorld, this.namer); |
| 120 | |
| 121 ClosedWorld get closedWorld => compiler.closedWorld; | |
| 122 | 121 |
| 123 visit(HInstruction node) => '${node.accept(this)} ${node.instructionType}'; | 122 visit(HInstruction node) => '${node.accept(this)} ${node.instructionType}'; |
| 124 | 123 |
| 125 String temporaryId(HInstruction instruction) { | 124 String temporaryId(HInstruction instruction) { |
| 126 String prefix; | 125 String prefix; |
| 127 if (instruction.isNull()) { | 126 if (instruction.isNull()) { |
| 128 prefix = 'u'; | 127 prefix = 'u'; |
| 129 } else if (instruction.isConflicting()) { | 128 } else if (instruction.isConflicting()) { |
| 130 prefix = 'c'; | 129 prefix = 'c'; |
| 131 } else if (instruction.isExtendableArray(closedWorld)) { | 130 } else if (instruction.isExtendableArray(closedWorld)) { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 String visitIndexAssign(HIndexAssign node) { | 287 String visitIndexAssign(HIndexAssign node) { |
| 289 String receiver = temporaryId(node.receiver); | 288 String receiver = temporaryId(node.receiver); |
| 290 String index = temporaryId(node.index); | 289 String index = temporaryId(node.index); |
| 291 String value = temporaryId(node.value); | 290 String value = temporaryId(node.value); |
| 292 return "IndexAssign: $receiver[$index] = $value"; | 291 return "IndexAssign: $receiver[$index] = $value"; |
| 293 } | 292 } |
| 294 | 293 |
| 295 String visitInterceptor(HInterceptor node) { | 294 String visitInterceptor(HInterceptor node) { |
| 296 String value = temporaryId(node.inputs[0]); | 295 String value = temporaryId(node.inputs[0]); |
| 297 if (node.interceptedClasses != null) { | 296 if (node.interceptedClasses != null) { |
| 298 JavaScriptBackend backend = compiler.backend; | 297 String cls = namer.suffixForGetInterceptor(node.interceptedClasses); |
| 299 String cls = | |
| 300 backend.namer.suffixForGetInterceptor(node.interceptedClasses); | |
| 301 return "Interceptor ($cls): $value"; | 298 return "Interceptor ($cls): $value"; |
| 302 } | 299 } |
| 303 return "Interceptor: $value"; | 300 return "Interceptor: $value"; |
| 304 } | 301 } |
| 305 | 302 |
| 306 String visitInvokeClosure(HInvokeClosure node) => | 303 String visitInvokeClosure(HInvokeClosure node) => |
| 307 handleInvokeDynamic(node, "InvokeClosure"); | 304 handleInvokeDynamic(node, "InvokeClosure"); |
| 308 | 305 |
| 309 String handleInvokeDynamic(HInvokeDynamic invoke, String kind) { | 306 String handleInvokeDynamic(HInvokeDynamic invoke, String kind) { |
| 310 String receiver = temporaryId(invoke.receiver); | 307 String receiver = temporaryId(invoke.receiver); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 } | 552 } |
| 556 | 553 |
| 557 String visitAwait(HAwait node) { | 554 String visitAwait(HAwait node) { |
| 558 return "Await: ${temporaryId(node.inputs[0])}"; | 555 return "Await: ${temporaryId(node.inputs[0])}"; |
| 559 } | 556 } |
| 560 | 557 |
| 561 String visitYield(HYield node) { | 558 String visitYield(HYield node) { |
| 562 return "Yield${node.hasStar ? "*" : ""}: ${temporaryId(node.inputs[0])}"; | 559 return "Yield${node.hasStar ? "*" : ""}: ${temporaryId(node.inputs[0])}"; |
| 563 } | 560 } |
| 564 } | 561 } |
| OLD | NEW |