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 } 11196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray } else if (location.IsConstant()) { 11296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray output_ << "constant"; 11396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray } else if (location.IsInvalid()) { 11496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray output_ << "invalid"; 115412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray } else if (location.IsStackSlot()) { 11686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << location.GetStackIndex() << "(sp)"; 117412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray } else { 118412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray DCHECK(location.IsDoubleStackSlot()); 119412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray output_ << "2x" << location.GetStackIndex() << "(sp)"; 12086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 12186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 12286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 12386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void VisitParallelMove(HParallelMove* instruction) { 12486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << instruction->DebugName(); 12586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " ("; 12686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray for (size_t i = 0, e = instruction->NumMoves(); i < e; ++i) { 12786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray MoveOperands* move = instruction->MoveOperandsAt(i); 12886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(move->GetSource(), Primitive::kPrimInt); 12986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " -> "; 13086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(move->GetDestination(), Primitive::kPrimInt); 13186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (i + 1 != e) { 13286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ", "; 13386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 13486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 13586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 13686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 137f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 138f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitInstruction(HInstruction* instruction) { 139f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->DebugName(); 140f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (instruction->InputCount() > 0) { 141f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " [ "; 142f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 143f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "v" << inputs.Current()->GetId() << " "; 144f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 145f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]"; 146f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 14786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (pass_name_ == kLivenessPassName && instruction->GetLifetimePosition() != kNoLifetime) { 148ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray output_ << " (liveness: " << instruction->GetLifetimePosition(); 149ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray if (instruction->HasLiveInterval()) { 150ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray output_ << " "; 151a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const LiveInterval& interval = *instruction->GetLiveInterval(); 152a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray interval.Dump(output_); 15386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 15486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 15586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } else if (pass_name_ == kRegisterAllocatorPassName) { 15686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray LocationSummary* locations = instruction->GetLocations(); 15786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (locations != nullptr) { 15886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " ( "; 15986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray for (size_t i = 0; i < instruction->InputCount(); ++i) { 16086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(locations->InAt(i), instruction->InputAt(i)->GetType()); 161a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray output_ << " "; 16286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 16386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << ")"; 16486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray if (locations->Out().IsValid()) { 16586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray output_ << " -> "; 16686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray DumpLocation(locations->Out(), instruction->GetType()); 167a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray } 168ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 169ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 170f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 171f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 172f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintInstructions(const HInstructionList& list) { 173f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* kEndInstructionMarker = "<|@"; 174f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(list); !it.Done(); it.Advance()) { 175f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 176f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 177f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray int bci = 0; 178f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " "; 179f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray instruction->Accept(this); 180f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << kEndInstructionMarker << std::endl; 181f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 182f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 183f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 18486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void Run() { 185f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("cfg"); 18686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray PrintProperty("name", pass_name_); 187f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray VisitInsertionOrder(); 188f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("cfg"); 189f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 190f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 191f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitBasicBlock(HBasicBlock* block) { 192f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("block"); 193f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("name", "B", block->GetBlockId()); 194ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray if (block->GetLifetimeStart() != kNoLifetime) { 195ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray // Piggy back on these fields to show the lifetime of the block. 196ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("from_bci", block->GetLifetimeStart()); 197ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("to_bci", block->GetLifetimeEnd()); 198ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } else { 199ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("from_bci", -1); 200ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray PrintInt("to_bci", -1); 201ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray } 202f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintPredecessors(block); 203f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintSuccessors(block); 204f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("xhandlers"); 205f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("flags"); 206f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (block->GetDominator() != nullptr) { 207f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("dominator", "B", block->GetDominator()->GetBlockId()); 208f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 209f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 210f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("states"); 211f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("locals"); 212f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInt("size", 0); 213f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("method", "None"); 214f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 215f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 216f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 217f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->GetId() << " v" << instruction->GetId() << "[ "; 218f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 219f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << inputs.Current()->GetId() << " "; 220f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 221f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]" << std::endl; 222f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 223f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("locals"); 224f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("states"); 225f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 226f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("HIR"); 227f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetPhis()); 228f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetInstructions()); 229f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("HIR"); 230f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("block"); 231f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 232f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 233f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray private: 234f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::ostream& output_; 23586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray const char* pass_name_; 236a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen_; 237f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray size_t indent_; 238f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 239f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter); 240f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}; 241f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 242f635e63318447ca04731b265a86a573c9ed1737cNicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 243f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HGraph* graph, 244f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* string_filter, 245a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen, 246f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const DexCompilationUnit& cu) 247a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) { 248f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (output == nullptr) { 249f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 250f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 251f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile()); 252f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (pretty_name.find(string_filter) == std::string::npos) { 253f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 254f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 255f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 256f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray is_enabled_ = true; 25786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); 258f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.StartTag("compilation"); 259f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("name", pretty_name.c_str()); 260f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("method", pretty_name.c_str()); 261f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintTime("date"); 262f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.EndTag("compilation"); 263f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 264f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 2650d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 2660d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray HGraph* graph, 267a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray const CodeGenerator& codegen, 2680d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray const char* name) 269a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) { 2700d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray if (output == nullptr) { 2710d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray return; 2720d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray } 2730d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 2740d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray is_enabled_ = true; 27586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_, "", codegen_); 2760d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.StartTag("compilation"); 2770d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("name", name); 2780d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("method", name); 2790d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintTime("date"); 2800d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.EndTag("compilation"); 2810d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray} 2820d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 283f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayvoid HGraphVisualizer::DumpGraph(const char* pass_name) { 284f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (!is_enabled_) { 285f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 286f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 28786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray HGraphVisualizerPrinter printer(graph_, *output_, pass_name, codegen_); 28886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray printer.Run(); 289f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 290f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 291f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} // namespace art 292