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

Unified Diff: vm/il_printer.cc

Issue 10446116: Add flow graph printing into a .cfg file with flag --print-flow-graph-file. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: vm/il_printer.cc
===================================================================
--- vm/il_printer.cc (revision 8145)
+++ vm/il_printer.cc (working copy)
@@ -65,7 +65,6 @@
}
-
void Computation::PrintTo(BufferFormatter* f) const {
f->Print("%s(", DebugName());
PrintOperandsTo(f);
@@ -351,4 +350,183 @@
}
+void FlowGraphVisualizer::Print(const char* format, ...) {
+ OS::FPrint(file_, "%*s", 2 * indent_, "");
+ va_list args;
+ va_start(args, format);
+ OS::VFPrint(file_, format, args);
+ va_end(args);
+}
+
+
+void FlowGraphVisualizer::PrintInstruction(Instruction* instr) {
+ char str[120];
+ BufferFormatter f(str, sizeof(str));
+ instr->PrintToVisualizer(&f);
+ Print("%s <|@\n", str);
+}
+
+
+void FlowGraphVisualizer::PrintFunction() {
+#define BEGIN(name) \
+ Print("begin_%s\n", name); \
+ indent_++;
+#define END(name) \
+ Print("end_%s\n", name); \
+ indent_--;
+
+ {
+ BEGIN("compilation");
+ const char* name = function_.ToFullyQualifiedCString();
+ Print("%s \"%s\"\n", "name", name);
+ Print("%s \"%s\"\n", "method", name);
+ Print("%s %d\n", "date", 0); // Required field. Unused.
+ END("compilation");
+ }
+
+ {
+ BEGIN("cfg");
+ Print("%s \"%s\"\n", "name", "Flow graph builder");
+
+ for (intptr_t i = 0; i < block_order_.length(); ++i) {
+ BEGIN("block");
+ BlockEntryInstr* entry = block_order_[i];
+ Print("%s \"B%d\"\n", "name", entry->block_id());
+ Print("%s %d\n", "from_bci", -1); // Required field. Unused.
+ Print("%s %d\n", "to_bci", -1); // Required field. Unused.
+
+ Print("predecessors");
+ for (intptr_t j = 0; j < entry->PredecessorCount(); ++j) {
+ BlockEntryInstr* pred = entry->PredecessorAt(j);
+ Print(" \"B%d\"", pred->block_id());
+ }
+ Print("\n");
+
+ Print("successors");
+ Instruction* last = entry->last_instruction();
+ for (intptr_t j = 0; j < last->SuccessorCount(); ++j) {
+ intptr_t next_id = last->SuccessorAt(j)->block_id();
+ Print(" \"B%d\"", next_id);
+ }
+ Print("\n");
+
+ // TODO(fschneider): Use this for exception handlers.
+ Print("xhandlers\n");
+
+ // Can be freely used to mark blocks
+ Print("flags\n");
+
+ if (entry->dominator() != NULL) {
+ Print("%s \"B%d\"\n", "dominator", entry->dominator()->block_id());
+ }
+
+ // TODO(fschneider): Mark blocks with loop nesting level.
+ Print("%s %d\n", "loop_depth", 0);
+
+ {
+ BEGIN("states"); // Required section.
+ {
+ BEGIN("locals"); // Required section.
+ // TODO(fschneider): Insert phi-instructions here.
+ intptr_t num_phis = 0;
+ Print("%s %d\n", "size", num_phis);
+ END("locals");
+ }
+ END("states");
+ }
+
+ {
+ BEGIN("HIR");
+ // Print the block entry.
+ Print("0 0 "); // Required fields "bci" and "use". Unused.
+ Instruction* current = block_order_[i];
+ PrintInstruction(current);
+ current = current->StraightLineSuccessor();
+ // And all the successors until an exit, branch, or a block entry.
+ while ((current != NULL) && !current->IsBlockEntry()) {
+ Print("0 0 ");
+ PrintInstruction(current);
+ current = current->StraightLineSuccessor();
+ }
+ BlockEntryInstr* successor =
+ (current == NULL) ? NULL : current->AsBlockEntry();
+ if (successor != NULL) {
+ Print("0 0 _ Goto B%d <|@\n", successor->block_id());
+ }
+ END("HIR");
+ }
+ END("block");
+ }
+ END("cfg");
+ }
+#undef BEGIN
+#undef END
+}
+
+
+// === Printing instructions in a visualizer-understandable format:
+// "result instruction(op1, op2)" where result is a temporary name
+// or _ for instruction without result.
+void GraphEntryInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ [graph]");
+}
+
+
+void JoinEntryInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ [join]");
+}
+
+
+void TargetEntryInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ [target");
+ if (HasTryIndex()) {
+ f->Print(" catch %d]", try_index());
+ } else {
+ f->Print("]");
+ }
+}
+
+
+void DoInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ ");
+ computation()->PrintTo(f);
+}
+
+
+void BindInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("t%d ", temp_index());
+ computation()->PrintTo(f);
+}
+
+
+void ReturnInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ %s ", DebugName());
+ value()->PrintTo(f);
+}
+
+
+void ThrowInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ %s ", DebugName());
+ exception()->PrintTo(f);
+}
+
+
+void ReThrowInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ %s ", DebugName());
+ exception()->PrintTo(f);
+ f->Print(", ");
+ stack_trace()->PrintTo(f);
+}
+
+
+void BranchInstr::PrintToVisualizer(BufferFormatter* f) const {
+ f->Print("_ %s ", DebugName());
+ f->Print("if ");
+ value()->PrintTo(f);
+ f->Print(" goto (B%d, B%d)",
+ true_successor()->block_id(),
+ false_successor()->block_id());
+}
+
+
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698