diff options
Diffstat (limited to 'compiler/optimizing/graph_visualizer.cc')
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 114 |
1 files changed, 93 insertions, 21 deletions
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index 5c5042e20f..0fb4737db2 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -28,8 +28,15 @@ namespace art { */ class HGraphVisualizerPrinter : public HGraphVisitor { public: - HGraphVisualizerPrinter(HGraph* graph, std::ostream& output, const CodeGenerator& codegen) - : HGraphVisitor(graph), output_(output), codegen_(codegen), indent_(0) {} + HGraphVisualizerPrinter(HGraph* graph, + std::ostream& output, + const char* pass_name, + const CodeGenerator& codegen) + : HGraphVisitor(graph), + output_(output), + pass_name_(pass_name), + codegen_(codegen), + indent_(0) {} void StartTag(const char* name) { AddIndent(); @@ -74,6 +81,25 @@ class HGraphVisualizerPrinter : public HGraphVisitor { } } + char GetTypeId(Primitive::Type type) { + // Note that Primitive::Descriptor would not work for us + // because it does not handle reference types (that is kPrimNot). + switch (type) { + case Primitive::kPrimBoolean: return 'z'; + case Primitive::kPrimByte: return 'b'; + case Primitive::kPrimChar: return 'c'; + case Primitive::kPrimShort: return 's'; + case Primitive::kPrimInt: return 'i'; + case Primitive::kPrimLong: return 'j'; + case Primitive::kPrimFloat: return 'f'; + case Primitive::kPrimDouble: return 'd'; + case Primitive::kPrimNot: return 'l'; + case Primitive::kPrimVoid: return 'v'; + } + LOG(FATAL) << "Unreachable"; + return 'v'; + } + void PrintPredecessors(HBasicBlock* block) { AddIndent(); output_ << "predecessors"; @@ -94,34 +120,77 @@ class HGraphVisualizerPrinter : public HGraphVisitor { output_<< std::endl; } + void DumpLocation(Location location, Primitive::Type type) { + if (location.IsRegister()) { + if (type == Primitive::kPrimDouble || type == Primitive::kPrimFloat) { + codegen_.DumpFloatingPointRegister(output_, location.reg().RegId()); + } else { + codegen_.DumpCoreRegister(output_, location.reg().RegId()); + } + } else if (location.IsConstant()) { + output_ << "constant"; + HConstant* constant = location.GetConstant(); + if (constant->IsIntConstant()) { + output_ << " " << constant->AsIntConstant()->GetValue(); + } else if (constant->IsLongConstant()) { + output_ << " " << constant->AsLongConstant()->GetValue(); + } + } else if (location.IsInvalid()) { + output_ << "invalid"; + } else if (location.IsStackSlot()) { + output_ << location.GetStackIndex() << "(sp)"; + } else { + DCHECK(location.IsDoubleStackSlot()); + output_ << "2x" << location.GetStackIndex() << "(sp)"; + } + } + + void VisitParallelMove(HParallelMove* instruction) { + output_ << instruction->DebugName(); + output_ << " ("; + for (size_t i = 0, e = instruction->NumMoves(); i < e; ++i) { + MoveOperands* move = instruction->MoveOperandsAt(i); + DumpLocation(move->GetSource(), Primitive::kPrimInt); + output_ << " -> "; + DumpLocation(move->GetDestination(), Primitive::kPrimInt); + if (i + 1 != e) { + output_ << ", "; + } + } + output_ << ")"; + } void VisitInstruction(HInstruction* instruction) { output_ << instruction->DebugName(); if (instruction->InputCount() > 0) { output_ << " [ "; for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { - output_ << "v" << inputs.Current()->GetId() << " "; + output_ << GetTypeId(inputs.Current()->GetType()) << inputs.Current()->GetId() << " "; } output_ << "]"; } - if (instruction->GetLifetimePosition() != kNoLifetime) { + if (pass_name_ == kLivenessPassName && instruction->GetLifetimePosition() != kNoLifetime) { output_ << " (liveness: " << instruction->GetLifetimePosition(); if (instruction->HasLiveInterval()) { output_ << " "; const LiveInterval& interval = *instruction->GetLiveInterval(); interval.Dump(output_); - if (interval.HasRegister()) { - int reg = interval.GetRegister(); + } + output_ << ")"; + } else if (pass_name_ == kRegisterAllocatorPassName) { + LocationSummary* locations = instruction->GetLocations(); + if (locations != nullptr) { + output_ << " ( "; + for (size_t i = 0; i < instruction->InputCount(); ++i) { + DumpLocation(locations->InAt(i), instruction->InputAt(i)->GetType()); output_ << " "; - if (instruction->GetType() == Primitive::kPrimFloat - || instruction->GetType() == Primitive::kPrimDouble) { - codegen_.DumpFloatingPointRegister(output_, reg); - } else { - codegen_.DumpCoreRegister(output_, reg); - } + } + output_ << ")"; + if (locations->Out().IsValid()) { + output_ << " -> "; + DumpLocation(locations->Out(), instruction->GetType()); } } - output_ << ")"; } } @@ -131,15 +200,16 @@ class HGraphVisualizerPrinter : public HGraphVisitor { HInstruction* instruction = it.Current(); AddIndent(); int bci = 0; - output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " "; + output_ << bci << " " << instruction->NumberOfUses() + << " " << GetTypeId(instruction->GetType()) << instruction->GetId() << " "; instruction->Accept(this); output_ << kEndInstructionMarker << std::endl; } } - void Run(const char* pass_name) { + void Run() { StartTag("cfg"); - PrintProperty("name", pass_name); + PrintProperty("name", pass_name_); VisitInsertionOrder(); EndTag("cfg"); } @@ -170,7 +240,8 @@ class HGraphVisualizerPrinter : public HGraphVisitor { for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { AddIndent(); HInstruction* instruction = it.Current(); - output_ << instruction->GetId() << " v" << instruction->GetId() << "[ "; + output_ << instruction->GetId() << " " << GetTypeId(instruction->GetType()) + << instruction->GetId() << "[ "; for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { output_ << inputs.Current()->GetId() << " "; } @@ -188,6 +259,7 @@ class HGraphVisualizerPrinter : public HGraphVisitor { private: std::ostream& output_; + const char* pass_name_; const CodeGenerator& codegen_; size_t indent_; @@ -209,7 +281,7 @@ HGraphVisualizer::HGraphVisualizer(std::ostream* output, } is_enabled_ = true; - HGraphVisualizerPrinter printer(graph, *output_, codegen_); + HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); printer.StartTag("compilation"); printer.PrintProperty("name", pretty_name.c_str()); printer.PrintProperty("method", pretty_name.c_str()); @@ -227,7 +299,7 @@ HGraphVisualizer::HGraphVisualizer(std::ostream* output, } is_enabled_ = true; - HGraphVisualizerPrinter printer(graph, *output_, codegen_); + HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); printer.StartTag("compilation"); printer.PrintProperty("name", name); printer.PrintProperty("method", name); @@ -239,8 +311,8 @@ void HGraphVisualizer::DumpGraph(const char* pass_name) { if (!is_enabled_) { return; } - HGraphVisualizerPrinter printer(graph_, *output_, codegen_); - printer.Run(pass_name); + HGraphVisualizerPrinter printer(graph_, *output_, pass_name, codegen_); + printer.Run(); } } // namespace art |