| Index: frog/leg/ssa/tracer.dart
|
| ===================================================================
|
| --- frog/leg/ssa/tracer.dart (revision 5925)
|
| +++ frog/leg/ssa/tracer.dart (working copy)
|
| @@ -1,422 +0,0 @@
|
| -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -#library('tracer');
|
| -
|
| -#import('dart:io');
|
| -#import('ssa.dart');
|
| -#import('../leg.dart');
|
| -
|
| -final bool GENERATE_SSA_TRACE = false;
|
| -
|
| -class HTracer extends HGraphVisitor implements Tracer {
|
| - int indent = 0;
|
| - final RandomAccessFile output;
|
| - final bool enabled = GENERATE_SSA_TRACE;
|
| -
|
| - HTracer([String path = "dart.cfg"])
|
| - : output = GENERATE_SSA_TRACE ? new File(path).openSync(FileMode.WRITE)
|
| - : null;
|
| -
|
| - void close() {
|
| - if (enabled) output.closeSync();
|
| - }
|
| -
|
| - void traceCompilation(String methodName) {
|
| - tag("compilation", () {
|
| - printProperty("name", methodName);
|
| - printProperty("method", methodName);
|
| - printProperty("date", new Date.now().value);
|
| - });
|
| - }
|
| -
|
| - void traceGraph(String name, HGraph graph) {
|
| - if (!enabled) return;
|
| - tag("cfg", () {
|
| - printProperty("name", name);
|
| - visitDominatorTree(graph);
|
| - });
|
| - }
|
| -
|
| - void addPredecessors(HBasicBlock block) {
|
| - if (block.predecessors.isEmpty()) {
|
| - printEmptyProperty("predecessors");
|
| - } else {
|
| - addIndent();
|
| - add("predecessors");
|
| - for (HBasicBlock predecessor in block.predecessors) {
|
| - add(' "B${predecessor.id}"');
|
| - }
|
| - add("\n");
|
| - }
|
| - }
|
| -
|
| - void addSuccessors(HBasicBlock block) {
|
| - if (block.successors.isEmpty()) {
|
| - printEmptyProperty("successors");
|
| - } else {
|
| - addIndent();
|
| - add("successors");
|
| - for (HBasicBlock successor in block.successors) {
|
| - add(' "B${successor.id}"');
|
| - }
|
| - add("\n");
|
| - }
|
| - }
|
| -
|
| - void addInstructions(HInstructionStringifier stringifier,
|
| - HInstructionList list) {
|
| - for (HInstruction instruction = list.first;
|
| - instruction !== null;
|
| - instruction = instruction.next) {
|
| - int bci = 0;
|
| - int uses = instruction.usedBy.length;
|
| - addIndent();
|
| - String temporaryId = stringifier.temporaryId(instruction);
|
| - String instructionString = stringifier.visit(instruction);
|
| - add("$bci $uses $temporaryId $instructionString <|@\n");
|
| - }
|
| - }
|
| -
|
| - void visitBasicBlock(HBasicBlock block) {
|
| - HInstructionStringifier stringifier = new HInstructionStringifier(block);
|
| - assert(block.id !== null);
|
| - tag("block", () {
|
| - printProperty("name", "B${block.id}");
|
| - printProperty("from_bci", -1);
|
| - printProperty("to_bci", -1);
|
| - addPredecessors(block);
|
| - addSuccessors(block);
|
| - printEmptyProperty("xhandlers");
|
| - printEmptyProperty("flags");
|
| - if (block.dominator !== null) {
|
| - printProperty("dominator", "B${block.dominator.id}");
|
| - }
|
| - tag("states", () {
|
| - tag("locals", () {
|
| - printProperty("size", 0);
|
| - printProperty("method", "None");
|
| - block.forEachPhi((phi) {
|
| - String phiId = stringifier.temporaryId(phi);
|
| - StringBuffer inputIds = new StringBuffer();
|
| - for (int i = 0; i < phi.inputs.length; i++) {
|
| - inputIds.add(stringifier.temporaryId(phi.inputs[i]));
|
| - inputIds.add(" ");
|
| - }
|
| - println("${phi.id} $phiId [ $inputIds]");
|
| - });
|
| - });
|
| - });
|
| - tag("HIR", () {
|
| - addInstructions(stringifier, block.phis);
|
| - addInstructions(stringifier, block);
|
| - });
|
| - });
|
| - }
|
| -
|
| - void tag(String tagName, Function f) {
|
| - println("begin_$tagName");
|
| - indent++;
|
| - f();
|
| - indent--;
|
| - println("end_$tagName");
|
| - }
|
| -
|
| - void println(String string) {
|
| - addIndent();
|
| - add(string);
|
| - add("\n");
|
| - }
|
| -
|
| - void printEmptyProperty(String propertyName) {
|
| - println(propertyName);
|
| - }
|
| -
|
| - void printProperty(String propertyName, var value) {
|
| - if (value is num) {
|
| - println("$propertyName $value");
|
| - } else {
|
| - println('$propertyName "$value"');
|
| - }
|
| - }
|
| -
|
| - void add(String string) {
|
| - output.writeStringSync(string);
|
| - }
|
| -
|
| - void addIndent() {
|
| - for (int i = 0; i < indent; i++) {
|
| - add(" ");
|
| - }
|
| - }
|
| -}
|
| -
|
| -class HInstructionStringifier implements HVisitor<String> {
|
| - HBasicBlock currentBlock;
|
| -
|
| - HInstructionStringifier(this.currentBlock);
|
| -
|
| - visit(HInstruction node) => node.accept(this);
|
| -
|
| - visitBasicBlock(HBasicBlock node) {
|
| - unreachable();
|
| - }
|
| -
|
| - String temporaryId(HInstruction instruction) {
|
| - String prefix;
|
| - switch (instruction.type) {
|
| - case HType.ARRAY: prefix = 'a'; break;
|
| - case HType.BOOLEAN: prefix = 'b'; break;
|
| - case HType.INTEGER: prefix = 'i'; break;
|
| - case HType.DOUBLE: prefix = 'd'; break;
|
| - case HType.NUMBER: prefix = 'n'; break;
|
| - case HType.STRING: prefix = 's'; break;
|
| - case HType.UNKNOWN: prefix = 'v'; break;
|
| - case HType.CONFLICTING: prefix = 'c'; break;
|
| - case HType.STRING_OR_ARRAY: prefix = 'sa'; break;
|
| - default: unreachable();
|
| - }
|
| - return "$prefix${instruction.id}";
|
| - }
|
| -
|
| - String visitBoolify(HBoolify node) {
|
| - return "Boolify: ${temporaryId(node.inputs[0])}";
|
| - }
|
| -
|
| - String visitAdd(HAdd node) => visitInvokeStatic(node);
|
| -
|
| - String visitBitAnd(HBitAnd node) => visitInvokeStatic(node);
|
| -
|
| - String visitBitNot(HBitNot node) => visitInvokeStatic(node);
|
| -
|
| - String visitBitOr(HBitOr node) => visitInvokeStatic(node);
|
| -
|
| - String visitBitXor(HBitXor node) => visitInvokeStatic(node);
|
| -
|
| - String visitBoundsCheck(HBoundsCheck node) {
|
| - String lengthId = temporaryId(node.length);
|
| - String indexId = temporaryId(node.index);
|
| - return "Bounds check: length = $lengthId, index = $indexId";
|
| - }
|
| -
|
| - String visitBreak(HBreak node) {
|
| - HBasicBlock target = currentBlock.successors[0];
|
| - if (node.label !== null) {
|
| - return "Break ${node.label.labelName}: (B${target.id})";
|
| - }
|
| - return "Break: (B${target.id})";
|
| - }
|
| -
|
| - String visitConstant(HConstant constant) => "Constant ${constant.constant}";
|
| -
|
| - String visitContinue(HContinue node) {
|
| - HBasicBlock target = currentBlock.successors[0];
|
| - if (node.label !== null) {
|
| - return "Continue ${node.label.labelName}: (B${target.id})";
|
| - }
|
| - return "Continue: (B${target.id})";
|
| - }
|
| -
|
| - String visitDivide(HDivide node) => visitInvokeStatic(node);
|
| -
|
| - String visitEquals(HEquals node) => visitInvokeStatic(node);
|
| -
|
| - String visitExit(HExit node) => "exit";
|
| -
|
| - String visitFieldGet(HFieldGet node) {
|
| - return 'get ${node.element.name.slowToString()}';
|
| - }
|
| -
|
| - String visitFieldSet(HFieldSet node) {
|
| - String valueId = temporaryId(node.value);
|
| - return 'set ${node.element.name.slowToString()} to $valueId';
|
| - }
|
| -
|
| - String visitGoto(HGoto node) {
|
| - HBasicBlock target = currentBlock.successors[0];
|
| - return "Goto: (B${target.id})";
|
| - }
|
| -
|
| - String visitGreater(HGreater node) => visitInvokeStatic(node);
|
| - String visitGreaterEqual(HGreaterEqual node) => visitInvokeStatic(node);
|
| -
|
| - String visitIdentity(HIdentity node) => visitInvokeStatic(node);
|
| -
|
| - String visitIf(HIf node) {
|
| - HBasicBlock thenBlock = currentBlock.successors[0];
|
| - HBasicBlock elseBlock = currentBlock.successors[1];
|
| - String conditionId = temporaryId(node.inputs[0]);
|
| - return "If ($conditionId): (B${thenBlock.id}) else (B${elseBlock.id})";
|
| - }
|
| -
|
| - String visitGenericInvoke(String invokeType, String functionName,
|
| - List<HInstruction> arguments) {
|
| - StringBuffer argumentsString = new StringBuffer();
|
| - for (int i = 0; i < arguments.length; i++) {
|
| - if (i != 0) argumentsString.add(", ");
|
| - argumentsString.add(temporaryId(arguments[i]));
|
| - }
|
| - return "$invokeType: $functionName($argumentsString)";
|
| - }
|
| -
|
| - String visitIndex(HIndex node) => visitInvokeStatic(node);
|
| - String visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node);
|
| -
|
| - String visitIntegerCheck(HIntegerCheck node) {
|
| - String value = temporaryId(node.value);
|
| - return "Integer check: $value";
|
| - }
|
| -
|
| - String visitInvokeClosure(HInvokeClosure node)
|
| - => visitInvokeDynamic(node, "closure");
|
| -
|
| - String visitInvokeDynamic(HInvokeDynamic invoke, String kind) {
|
| - String receiver = temporaryId(invoke.receiver);
|
| - String target = "($kind) $receiver.${invoke.name.slowToString()}";
|
| - int offset = HInvoke.ARGUMENTS_OFFSET;
|
| - List arguments =
|
| - invoke.inputs.getRange(offset, invoke.inputs.length - offset);
|
| - return visitGenericInvoke("Invoke", target, arguments);
|
| - }
|
| -
|
| - String visitInvokeDynamicMethod(HInvokeDynamicMethod node)
|
| - => visitInvokeDynamic(node, "method");
|
| - String visitInvokeDynamicGetter(HInvokeDynamicGetter node)
|
| - => visitInvokeDynamic(node, "get");
|
| - String visitInvokeDynamicSetter(HInvokeDynamicSetter node)
|
| - => visitInvokeDynamic(node, "set");
|
| -
|
| - String visitInvokeInterceptor(HInvokeInterceptor invoke)
|
| - => visitInvokeStatic(invoke);
|
| -
|
| - String visitInvokeStatic(HInvokeStatic invoke) {
|
| - String target = temporaryId(invoke.target);
|
| - int offset = HInvoke.ARGUMENTS_OFFSET;
|
| - List arguments =
|
| - invoke.inputs.getRange(offset, invoke.inputs.length - offset);
|
| - return visitGenericInvoke("Invoke", target, arguments);
|
| - }
|
| -
|
| - String visitInvokeSuper(HInvokeSuper invoke) {
|
| - String target = temporaryId(invoke.target);
|
| - int offset = HInvoke.ARGUMENTS_OFFSET + 1;
|
| - List arguments =
|
| - invoke.inputs.getRange(offset, invoke.inputs.length - offset);
|
| - return visitGenericInvoke("Invoke super", target, arguments);
|
| - }
|
| -
|
| - String visitForeign(HForeign foreign) {
|
| - return visitGenericInvoke("Foreign", "${foreign.code}", foreign.inputs);
|
| - }
|
| -
|
| - String visitForeignNew(HForeignNew node) {
|
| - return visitGenericInvoke("New",
|
| - "${node.element.name.slowToString()}",
|
| - node.inputs);
|
| - }
|
| -
|
| - String visitLess(HLess node) => visitInvokeStatic(node);
|
| - String visitLessEqual(HLessEqual node) => visitInvokeStatic(node);
|
| -
|
| - String visitLiteralList(HLiteralList node) {
|
| - StringBuffer elementsString = new StringBuffer();
|
| - for (int i = 0; i < node.inputs.length; i++) {
|
| - if (i != 0) elementsString.add(", ");
|
| - elementsString.add(temporaryId(node.inputs[i]));
|
| - }
|
| - return "Literal list: [$elementsString]";
|
| - }
|
| -
|
| - String visitLoopBranch(HLoopBranch branch) {
|
| - HBasicBlock bodyBlock = currentBlock.successors[0];
|
| - HBasicBlock exitBlock = currentBlock.successors[1];
|
| - String conditionId = temporaryId(branch.inputs[0]);
|
| - return "While ($conditionId): (B${bodyBlock.id}) then (B${exitBlock.id})";
|
| - }
|
| -
|
| - String visitModulo(HModulo node) => visitInvokeStatic(node);
|
| -
|
| - String visitMultiply(HMultiply node) => visitInvokeStatic(node);
|
| -
|
| - String visitNegate(HNegate node) => visitInvokeStatic(node);
|
| -
|
| - String visitNot(HNot node) => "Not: ${temporaryId(node.inputs[0])}";
|
| -
|
| - String visitParameterValue(HParameterValue node) {
|
| - return "p${node.element.name.slowToString()}";
|
| - }
|
| -
|
| - String visitPhi(HPhi phi) {
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.add("Phi(");
|
| - for (int i = 0; i < phi.inputs.length; i++) {
|
| - if (i > 0) buffer.add(", ");
|
| - buffer.add(temporaryId(phi.inputs[i]));
|
| - }
|
| - buffer.add(")");
|
| - return buffer.toString();
|
| - }
|
| -
|
| - String visitReturn(HReturn node) => "Return ${temporaryId(node.inputs[0])}";
|
| -
|
| - String visitShiftLeft(HShiftLeft node) => visitInvokeStatic(node);
|
| -
|
| - String visitShiftRight(HShiftRight node) => visitInvokeStatic(node);
|
| -
|
| - String visitStatic(HStatic node)
|
| - => "Static ${node.element.name.slowToString()}";
|
| - String visitStaticStore(HStaticStore node) {
|
| - String lhs = node.element.name.slowToString();
|
| - return "Static $lhs = ${temporaryId(node.inputs[0])}";
|
| - }
|
| -
|
| - String visitSubtract(HSubtract node) => visitInvokeStatic(node);
|
| -
|
| - String visitThis(HThis node) => "this";
|
| -
|
| - String visitThrow(HThrow node) => "Throw ${temporaryId(node.inputs[0])}";
|
| -
|
| - String visitTruncatingDivide(HTruncatingDivide node) {
|
| - return visitInvokeStatic(node);
|
| - }
|
| -
|
| - String visitTry(HTry node) {
|
| - List<HBasicBlock> successors = currentBlock.successors;
|
| - String tryBlock = 'B${successors[0].id}';
|
| - StringBuffer catchBlocks = new StringBuffer();
|
| - for (int i = 1; i < successors.length - 1; i++) {
|
| - catchBlocks.add('B${successors[i].id}, ');
|
| - }
|
| -
|
| - String finallyBlock;
|
| - if (node.finallyBlock != null) {
|
| - finallyBlock = 'B${node.finallyBlock.id}';
|
| - } else {
|
| - catchBlocks.add('B${successors[successors.length - 1].id}');
|
| - finallyBlock = 'none';
|
| - }
|
| - return "Try: $tryBlock, Catch: $catchBlocks, Finally: $finallyBlock";
|
| - }
|
| -
|
| - String visitTypeGuard(HTypeGuard node) {
|
| - String type;
|
| - switch (node.type) {
|
| - case HType.ARRAY: type = "array"; break;
|
| - case HType.BOOLEAN: type = "bool"; break;
|
| - case HType.INTEGER: type = "integer"; break;
|
| - case HType.DOUBLE: type = "double"; break;
|
| - case HType.NUMBER: type = "number"; break;
|
| - case HType.STRING: type = "string"; break;
|
| - case HType.STRING_OR_ARRAY: type = "string_or_array"; break;
|
| - case HType.UNKNOWN: type = 'unknown'; break;
|
| - default: unreachable();
|
| - }
|
| - return "TypeGuard: ${temporaryId(node.inputs[0])} is $type";
|
| - }
|
| -
|
| - String visitIs(HIs node) {
|
| - String type = node.typeExpression.toString();
|
| - return "TypeTest: ${temporaryId(node.expression)} is $type";
|
| - }
|
| -}
|
|
|