graph_visualizer.cc revision 86dbb9a12119273039ce272b41c809fa548b37b6
1f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/* 2f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project 3f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * 4f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * you may not use this file except in compliance with the License. 6f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * You may obtain a copy of the License at 7f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * 8f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * 10f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * See the License for the specific language governing permissions and 14f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * limitations under the License. 15f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */ 16f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 17f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#include "graph_visualizer.h" 18f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 19a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray#include "code_generator.h" 20f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#include "driver/dex_compilation_unit.h" 21f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#include "nodes.h" 22ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "ssa_liveness_analysis.h" 23f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 24f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffraynamespace art { 25f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 26f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/** 27f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * HGraph visitor to generate a file suitable for the c1visualizer tool and IRHydra. 28f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */ 29f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayclass HGraphVisualizerPrinter : public HGraphVisitor { 30f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray public: 3186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter(HGraph* graph, 3286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray std::ostream& output, 3386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray const char* pass_name, 3486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray const CodeGenerator& codegen) 3586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray : HGraphVisitor(graph), 3686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_(output), 3786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray pass_name_(pass_name), 3886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray codegen_(codegen), 3986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray indent_(0) {} 40f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 41f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void StartTag(const char* name) { 42f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 43f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "begin_" << name << std::endl; 44f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray indent_++; 45f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 46f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 47f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void EndTag(const char* name) { 48f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray indent_--; 49f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 50f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "end_" << name << std::endl; 51f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 52f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 53f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintProperty(const char* name, const char* property) { 54f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 55f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " \"" << property << "\"" << std::endl; 56f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 57f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 58f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintProperty(const char* name, const char* property, int id) { 59f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 60f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " \"" << property << id << "\"" << std::endl; 61f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 62f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 63f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintEmptyProperty(const char* name) { 64f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 65f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << std::endl; 66f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 67f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 68f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintTime(const char* name) { 69f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 70f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " " << time(NULL) << std::endl; 71f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 72f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 73f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintInt(const char* name, int value) { 74f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 75f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " " << value << std::endl; 76f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 77f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 78f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void AddIndent() { 79f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (size_t i = 0; i < indent_; ++i) { 80f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " "; 81f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 82f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 83f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 84f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintPredecessors(HBasicBlock* block) { 85f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 86f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "predecessors"; 87f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (size_t i = 0, e = block->GetPredecessors().Size(); i < e; ++i) { 88f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HBasicBlock* predecessor = block->GetPredecessors().Get(i); 89f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " \"B" << predecessor->GetBlockId() << "\" "; 90f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 91f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_<< std::endl; 92f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 93f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 94f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintSuccessors(HBasicBlock* block) { 95f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 96f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "successors"; 97f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) { 98f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HBasicBlock* successor = block->GetSuccessors().Get(i); 99f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " \"B" << successor->GetBlockId() << "\" "; 100f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 101f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_<< std::endl; 102f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 103f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 10486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void DumpLocation(Location location, Primitive::Type type) { 10586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (location.IsRegister()) { 10686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (type == Primitive::kPrimDouble || type == Primitive::kPrimFloat) { 10786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray codegen_.DumpFloatingPointRegister(output_, location.reg().RegId()); 10886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } else { 10986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray codegen_.DumpCoreRegister(output_, location.reg().RegId()); 11086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 11186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } else { 11286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DCHECK(location.IsStackSlot()); 11386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << location.GetStackIndex() << "(sp)"; 11486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 11586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 11686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 11786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void VisitParallelMove(HParallelMove* instruction) { 11886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << instruction->DebugName(); 11986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " ("; 12086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray for (size_t i = 0, e = instruction->NumMoves(); i < e; ++i) { 12186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray MoveOperands* move = instruction->MoveOperandsAt(i); 12286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(move->GetSource(), Primitive::kPrimInt); 12386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " -> "; 12486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(move->GetDestination(), Primitive::kPrimInt); 12586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (i + 1 != e) { 12686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ", "; 12786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 12886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 12986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 13086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 131f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 132f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitInstruction(HInstruction* instruction) { 133f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->DebugName(); 134f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (instruction->InputCount() > 0) { 135f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " [ "; 136f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 137f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "v" << inputs.Current()->GetId() << " "; 138f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 139f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]"; 140f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 14186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (pass_name_ == kLivenessPassName && instruction->GetLifetimePosition() != kNoLifetime) { 142ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray output_ << " (liveness: " << instruction->GetLifetimePosition(); 143ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray if (instruction->HasLiveInterval()) { 144ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray output_ << " "; 145a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const LiveInterval& interval = *instruction->GetLiveInterval(); 146a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray interval.Dump(output_); 14786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 14886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 14986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } else if (pass_name_ == kRegisterAllocatorPassName) { 15086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray LocationSummary* locations = instruction->GetLocations(); 15186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (locations != nullptr) { 15286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " ( "; 15386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray for (size_t i = 0; i < instruction->InputCount(); ++i) { 15486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(locations->InAt(i), instruction->InputAt(i)->GetType()); 155a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray output_ << " "; 15686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 15786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 15886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (locations->Out().IsValid()) { 15986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " -> "; 16086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(locations->Out(), instruction->GetType()); 161a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray } 162ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 163ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 164f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 165f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 166f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintInstructions(const HInstructionList& list) { 167f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* kEndInstructionMarker = "<|@"; 168f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(list); !it.Done(); it.Advance()) { 169f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 170f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 171f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray int bci = 0; 172f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " "; 173f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray instruction->Accept(this); 174f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << kEndInstructionMarker << std::endl; 175f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 176f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 177f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 17886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void Run() { 179f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("cfg"); 18086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray PrintProperty("name", pass_name_); 181f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray VisitInsertionOrder(); 182f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("cfg"); 183f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 184f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 185f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitBasicBlock(HBasicBlock* block) { 186f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("block"); 187f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("name", "B", block->GetBlockId()); 188ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray if (block->GetLifetimeStart() != kNoLifetime) { 189ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray // Piggy back on these fields to show the lifetime of the block. 190ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("from_bci", block->GetLifetimeStart()); 191ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("to_bci", block->GetLifetimeEnd()); 192ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } else { 193ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("from_bci", -1); 194ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("to_bci", -1); 195ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 196f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintPredecessors(block); 197f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintSuccessors(block); 198f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("xhandlers"); 199f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("flags"); 200f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (block->GetDominator() != nullptr) { 201f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("dominator", "B", block->GetDominator()->GetBlockId()); 202f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 203f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 204f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("states"); 205f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("locals"); 206f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInt("size", 0); 207f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("method", "None"); 208f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 209f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 210f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 211f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->GetId() << " v" << instruction->GetId() << "[ "; 212f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 213f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << inputs.Current()->GetId() << " "; 214f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 215f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]" << std::endl; 216f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 217f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("locals"); 218f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("states"); 219f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 220f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("HIR"); 221f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetPhis()); 222f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetInstructions()); 223f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("HIR"); 224f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("block"); 225f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 226f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 227f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray private: 228f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::ostream& output_; 22986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray const char* pass_name_; 230a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen_; 231f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray size_t indent_; 232f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 233f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter); 234f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}; 235f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 236f635e63318447ca04731b265a86a573c9ed1737cNicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 237f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HGraph* graph, 238f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* string_filter, 239a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen, 240f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const DexCompilationUnit& cu) 241a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) { 242f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (output == nullptr) { 243f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 244f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 245f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile()); 246f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (pretty_name.find(string_filter) == std::string::npos) { 247f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 248f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 249f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 250f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray is_enabled_ = true; 25186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); 252f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.StartTag("compilation"); 253f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("name", pretty_name.c_str()); 254f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("method", pretty_name.c_str()); 255f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintTime("date"); 256f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.EndTag("compilation"); 257f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 258f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 2590d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 2600d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray HGraph* graph, 261a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen, 2620d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray const char* name) 263a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) { 2640d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray if (output == nullptr) { 2650d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray return; 2660d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray } 2670d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 2680d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray is_enabled_ = true; 26986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); 2700d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.StartTag("compilation"); 2710d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("name", name); 2720d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("method", name); 2730d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintTime("date"); 2740d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.EndTag("compilation"); 2750d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray} 2760d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 277f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayvoid HGraphVisualizer::DumpGraph(const char* pass_name) { 278f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (!is_enabled_) { 279f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 280f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 28186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph_, *output_, pass_name, codegen_); 28286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray printer.Run(); 283f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 284f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 285f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} // namespace art 286