graph_visualizer.cc revision 412f10cfed002ab617c78f2621d68446ca4dd8bd
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 } 111412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray } else if (location.IsStackSlot()) { 11286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << location.GetStackIndex() << "(sp)"; 113412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray } else { 114412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray DCHECK(location.IsDoubleStackSlot()); 115412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray output_ << "2x" << location.GetStackIndex() << "(sp)"; 11686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 11786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 11886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 11986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void VisitParallelMove(HParallelMove* instruction) { 12086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << instruction->DebugName(); 12186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " ("; 12286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray for (size_t i = 0, e = instruction->NumMoves(); i < e; ++i) { 12386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray MoveOperands* move = instruction->MoveOperandsAt(i); 12486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(move->GetSource(), Primitive::kPrimInt); 12586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " -> "; 12686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(move->GetDestination(), Primitive::kPrimInt); 12786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (i + 1 != e) { 12886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ", "; 12986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 13086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 13186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 13286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 133f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 134f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitInstruction(HInstruction* instruction) { 135f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->DebugName(); 136f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (instruction->InputCount() > 0) { 137f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " [ "; 138f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 139f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "v" << inputs.Current()->GetId() << " "; 140f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 141f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]"; 142f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 14386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (pass_name_ == kLivenessPassName && instruction->GetLifetimePosition() != kNoLifetime) { 144ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray output_ << " (liveness: " << instruction->GetLifetimePosition(); 145ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray if (instruction->HasLiveInterval()) { 146ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray output_ << " "; 147a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const LiveInterval& interval = *instruction->GetLiveInterval(); 148a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray interval.Dump(output_); 14986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 15086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 15186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } else if (pass_name_ == kRegisterAllocatorPassName) { 15286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray LocationSummary* locations = instruction->GetLocations(); 15386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (locations != nullptr) { 15486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " ( "; 15586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray for (size_t i = 0; i < instruction->InputCount(); ++i) { 15686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(locations->InAt(i), instruction->InputAt(i)->GetType()); 157a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray output_ << " "; 15886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 15986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 16086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (locations->Out().IsValid()) { 16186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " -> "; 16286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(locations->Out(), instruction->GetType()); 163a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray } 164ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 165ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 166f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 167f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 168f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintInstructions(const HInstructionList& list) { 169f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* kEndInstructionMarker = "<|@"; 170f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(list); !it.Done(); it.Advance()) { 171f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 172f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 173f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray int bci = 0; 174f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " "; 175f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray instruction->Accept(this); 176f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << kEndInstructionMarker << std::endl; 177f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 178f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 179f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 18086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void Run() { 181f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("cfg"); 18286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray PrintProperty("name", pass_name_); 183f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray VisitInsertionOrder(); 184f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("cfg"); 185f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 186f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 187f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitBasicBlock(HBasicBlock* block) { 188f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("block"); 189f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("name", "B", block->GetBlockId()); 190ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray if (block->GetLifetimeStart() != kNoLifetime) { 191ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray // Piggy back on these fields to show the lifetime of the block. 192ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("from_bci", block->GetLifetimeStart()); 193ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("to_bci", block->GetLifetimeEnd()); 194ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } else { 195ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("from_bci", -1); 196ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("to_bci", -1); 197ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 198f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintPredecessors(block); 199f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintSuccessors(block); 200f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("xhandlers"); 201f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("flags"); 202f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (block->GetDominator() != nullptr) { 203f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("dominator", "B", block->GetDominator()->GetBlockId()); 204f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 205f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 206f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("states"); 207f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("locals"); 208f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInt("size", 0); 209f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("method", "None"); 210f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 211f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 212f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 213f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->GetId() << " v" << instruction->GetId() << "[ "; 214f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 215f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << inputs.Current()->GetId() << " "; 216f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 217f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]" << std::endl; 218f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 219f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("locals"); 220f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("states"); 221f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 222f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("HIR"); 223f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetPhis()); 224f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetInstructions()); 225f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("HIR"); 226f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("block"); 227f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 228f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 229f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray private: 230f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::ostream& output_; 23186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray const char* pass_name_; 232a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen_; 233f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray size_t indent_; 234f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 235f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter); 236f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}; 237f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 238f635e63318447ca04731b265a86a573c9ed1737cNicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 239f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HGraph* graph, 240f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* string_filter, 241a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen, 242f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const DexCompilationUnit& cu) 243a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) { 244f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (output == nullptr) { 245f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 246f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 247f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile()); 248f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (pretty_name.find(string_filter) == std::string::npos) { 249f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 250f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 251f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 252f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray is_enabled_ = true; 25386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); 254f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.StartTag("compilation"); 255f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("name", pretty_name.c_str()); 256f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("method", pretty_name.c_str()); 257f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintTime("date"); 258f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.EndTag("compilation"); 259f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 260f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 2610d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 2620d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray HGraph* graph, 263a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen, 2640d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray const char* name) 265a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) { 2660d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray if (output == nullptr) { 2670d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray return; 2680d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray } 2690d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 2700d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray is_enabled_ = true; 27186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); 2720d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.StartTag("compilation"); 2730d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("name", name); 2740d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("method", name); 2750d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintTime("date"); 2760d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.EndTag("compilation"); 2770d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray} 2780d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 279f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayvoid HGraphVisualizer::DumpGraph(const char* pass_name) { 280f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (!is_enabled_) { 281f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 282f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 28386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph_, *output_, pass_name, codegen_); 28486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray printer.Run(); 285f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 286f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 287f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} // namespace art 288