graph_visualizer.cc revision 0d3f578909d0d1ea072ca68d78301b6fb7a44451
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 19f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#include "driver/dex_compilation_unit.h" 20f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray#include "nodes.h" 21f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 22f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffraynamespace art { 23f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 24f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/** 25f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * HGraph visitor to generate a file suitable for the c1visualizer tool and IRHydra. 26f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */ 27f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayclass HGraphVisualizerPrinter : public HGraphVisitor { 28f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray public: 29f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HGraphVisualizerPrinter(HGraph* graph, std::ostream& output) 30f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray : HGraphVisitor(graph), output_(output), indent_(0) {} 31f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 32f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void StartTag(const char* name) { 33f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 34f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "begin_" << name << std::endl; 35f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray indent_++; 36f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 37f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 38f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void EndTag(const char* name) { 39f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray indent_--; 40f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 41f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "end_" << name << std::endl; 42f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 43f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 44f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintProperty(const char* name, const char* property) { 45f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 46f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " \"" << property << "\"" << std::endl; 47f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 48f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 49f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintProperty(const char* name, const char* property, int id) { 50f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 51f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " \"" << property << id << "\"" << std::endl; 52f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 53f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 54f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintEmptyProperty(const char* name) { 55f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 56f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << std::endl; 57f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 58f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 59f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintTime(const char* name) { 60f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 61f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " " << time(NULL) << std::endl; 62f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 63f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 64f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintInt(const char* name, int value) { 65f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 66f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << name << " " << value << std::endl; 67f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 68f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 69f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void AddIndent() { 70f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (size_t i = 0; i < indent_; ++i) { 71f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " "; 72f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 73f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 74f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 75f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintPredecessors(HBasicBlock* block) { 76f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 77f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "predecessors"; 78f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (size_t i = 0, e = block->GetPredecessors().Size(); i < e; ++i) { 79f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HBasicBlock* predecessor = block->GetPredecessors().Get(i); 80f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " \"B" << predecessor->GetBlockId() << "\" "; 81f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 82f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_<< std::endl; 83f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 84f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 85f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintSuccessors(HBasicBlock* block) { 86f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 87f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "successors"; 88f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) { 89f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HBasicBlock* successor = block->GetSuccessors().Get(i); 90f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " \"B" << successor->GetBlockId() << "\" "; 91f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 92f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_<< std::endl; 93f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 94f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 95f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 96f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitInstruction(HInstruction* instruction) { 97f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->DebugName(); 98f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (instruction->InputCount() > 0) { 99f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << " [ "; 100f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 101f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "v" << inputs.Current()->GetId() << " "; 102f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 103f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]"; 104f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 105f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 106f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 107f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void PrintInstructions(const HInstructionList& list) { 108f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* kEndInstructionMarker = "<|@"; 109f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(list); !it.Done(); it.Advance()) { 110f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 111f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 112f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray int bci = 0; 113f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " "; 114f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray instruction->Accept(this); 115f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << kEndInstructionMarker << std::endl; 116f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 117f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 118f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 119f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void Run(const char* pass_name) { 120f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("cfg"); 121f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("name", pass_name); 122f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray VisitInsertionOrder(); 123f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("cfg"); 124f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 125f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 126f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray void VisitBasicBlock(HBasicBlock* block) { 127f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("block"); 128f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("name", "B", block->GetBlockId()); 129f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInt("from_bci", -1); 130f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInt("to_bci", -1); 131f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintPredecessors(block); 132f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintSuccessors(block); 133f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("xhandlers"); 134f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintEmptyProperty("flags"); 135f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (block->GetDominator() != nullptr) { 136f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("dominator", "B", block->GetDominator()->GetBlockId()); 137f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 138f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 139f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("states"); 140f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("locals"); 141f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInt("size", 0); 142f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintProperty("method", "None"); 143f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 144f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray AddIndent(); 145f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HInstruction* instruction = it.Current(); 146f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << instruction->GetId() << " v" << instruction->GetId() << "[ "; 147f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { 148f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << inputs.Current()->GetId() << " "; 149f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 150f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray output_ << "]" << std::endl; 151f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 152f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("locals"); 153f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("states"); 154f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 155f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray StartTag("HIR"); 156f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetPhis()); 157f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray PrintInstructions(block->GetInstructions()); 158f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("HIR"); 159f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray EndTag("block"); 160f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 161f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 162f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray private: 163f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::ostream& output_; 164f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray size_t indent_; 165f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 166f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter); 167f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}; 168f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 169f635e63318447ca04731b265a86a573c9ed1737cNicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 170f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HGraph* graph, 171f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const char* string_filter, 172f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray const DexCompilationUnit& cu) 173f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray : output_(output), graph_(graph), is_enabled_(false) { 174f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (output == nullptr) { 175f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 176f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 177f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile()); 178f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (pretty_name.find(string_filter) == std::string::npos) { 179f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 180f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 181f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 182f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray is_enabled_ = true; 183f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_); 184f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.StartTag("compilation"); 185f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("name", pretty_name.c_str()); 186f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintProperty("method", pretty_name.c_str()); 187f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.PrintTime("date"); 188f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.EndTag("compilation"); 189f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 190f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 1910d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output, 1920d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray HGraph* graph, 1930d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray const char* name) 1940d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray : output_(output), graph_(graph), is_enabled_(false) { 1950d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray if (output == nullptr) { 1960d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray return; 1970d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray } 1980d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 1990d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray is_enabled_ = true; 2000d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray HGraphVisualizerPrinter printer(graph, *output_); 2010d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.StartTag("compilation"); 2020d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("name", name); 2030d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintProperty("method", name); 2040d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.PrintTime("date"); 2050d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray printer.EndTag("compilation"); 2060d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray} 2070d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray 208f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayvoid HGraphVisualizer::DumpGraph(const char* pass_name) { 209f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray if (!is_enabled_) { 210f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray return; 211f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray } 212f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray HGraphVisualizerPrinter printer(graph_, *output_); 213f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray printer.Run(pass_name); 214f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} 215f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray 216f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray} // namespace art 217