| Index: runtime/vm/flow_graph_builder.cc
|
| diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
|
| index 2424a1d6182db3274ebecf7e0169ed23674f40f1..bdb5b3b5d470576212334777a8057062798a4aa8 100644
|
| --- a/runtime/vm/flow_graph_builder.cc
|
| +++ b/runtime/vm/flow_graph_builder.cc
|
| @@ -865,28 +865,89 @@ void FlowGraphBuilder::TraceBailout() const {
|
| }
|
|
|
|
|
| -void FlowGraphBuilder::PrintGraph() const {
|
| - if (!FLAG_print_flow_graph || HasBailedOut()) return;
|
| +// Graph printing.
|
| +class FlowGraphPrinter : public InstructionVisitor {
|
| + public:
|
| + explicit FlowGraphPrinter(const Function& function) : function_(function) { }
|
|
|
| - OS::Print("==== %s\n",
|
| - parsed_function().function().ToFullyQualifiedCString());
|
| + virtual ~FlowGraphPrinter() {}
|
|
|
| - for (intptr_t i = postorder_block_entries_.length() - 1; i >= 0; --i) {
|
| + // Print the instructions in a block terminated by newlines. Add "goto N"
|
| + // to the end of the block if it ends with an unconditional jump to
|
| + // another block and that block is not next in reverse postorder.
|
| + void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order);
|
| +
|
| + // Each visit function prints an instruction with a four space
|
| + // indent and no trailing newline. Basic block entries are labeled
|
| + // with their block number.
|
| +#define DECLARE_VISIT(type) \
|
| + virtual void Visit##type(type##Instr* instr);
|
| + FOR_EACH_INSTRUCTION(DECLARE_VISIT)
|
| +#undef DECLARE_VISIT
|
| +
|
| + private:
|
| + const Function& function_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(FlowGraphPrinter);
|
| +};
|
| +
|
| +
|
| +void FlowGraphPrinter::VisitBlocks(
|
| + const GrowableArray<BlockEntryInstr*>& block_order) {
|
| + OS::Print("==== %s\n", function_.ToFullyQualifiedCString());
|
| +
|
| + for (intptr_t i = block_order.length() - 1; i >= 0; --i) {
|
| // Print the block entry.
|
| - Instruction* current = postorder_block_entries_[i]->Print();
|
| + Instruction* current = block_order[i]->Accept(this);
|
| // And all the successors until an exit, branch, or a block entry.
|
| while ((current != NULL) && !current->IsBlockEntry()) {
|
| OS::Print("\n");
|
| - current = current->Print();
|
| + current = current->Accept(this);
|
| }
|
| - if (current != NULL && current->IsBlockEntry()) {
|
| - OS::Print(" goto %d", current->GetBlockNumber());
|
| + if ((current != NULL) && current->IsBlockEntry()) {
|
| + OS::Print(" goto %d", BlockEntryInstr::cast(current)->block_number());
|
| }
|
| OS::Print("\n");
|
| }
|
| }
|
|
|
|
|
| +void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) {
|
| + OS::Print("%2d: [join]", instr->block_number());
|
| +}
|
| +
|
| +
|
| +void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) {
|
| + OS::Print("%2d: [target]", instr->block_number());
|
| +}
|
| +
|
| +
|
| +void FlowGraphPrinter::VisitDo(DoInstr* instr) {
|
| + OS::Print(" ");
|
| + instr->computation()->Print();
|
| +}
|
| +
|
| +
|
| +void FlowGraphPrinter::VisitBind(BindInstr* instr) {
|
| + OS::Print(" t%d <-", instr->temp_index());
|
| + instr->computation()->Print();
|
| +}
|
| +
|
| +
|
| +void FlowGraphPrinter::VisitReturn(ReturnInstr* instr) {
|
| + OS::Print(" return ");
|
| + instr->value()->Print();
|
| +}
|
| +
|
| +
|
| +void FlowGraphPrinter::VisitBranch(BranchInstr* instr) {
|
| + OS::Print(" if ");
|
| + instr->value()->Print();
|
| + OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(),
|
| + instr->false_successor()->block_number());
|
| +}
|
| +
|
| +
|
| void FlowGraphBuilder::BuildGraph() {
|
| EffectGraphVisitor for_effect(this, 0);
|
| for_effect.AddInstruction(new TargetEntryInstr());
|
| @@ -898,10 +959,13 @@ void FlowGraphBuilder::BuildGraph() {
|
| // Number the blocks in reverse postorder starting with 0.
|
| intptr_t last_index = postorder_block_entries_.length() - 1;
|
| for (intptr_t i = last_index; i >= 0; --i) {
|
| - postorder_block_entries_[i]->SetBlockNumber(last_index - i);
|
| + postorder_block_entries_[i]->set_block_number(last_index - i);
|
| }
|
| }
|
| - PrintGraph();
|
| + if (FLAG_print_flow_graph) {
|
| + FlowGraphPrinter printer(parsed_function().function());
|
| + printer.VisitBlocks(postorder_block_entries_);
|
| + }
|
| }
|
|
|
| } // namespace dart
|
|
|