diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-05-14 09:43:38 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-05-14 14:26:11 +0100 |
commit | f635e63318447ca04731b265a86a573c9ed1737c (patch) | |
tree | 47cab84a6ac47d8a4f5f281e3eabdf1780f220d0 /compiler/optimizing/graph_visualizer.cc | |
parent | d115735fe5523ff72319f0968f773683323c7f79 (diff) | |
download | art-f635e63318447ca04731b265a86a573c9ed1737c.zip art-f635e63318447ca04731b265a86a573c9ed1737c.tar.gz art-f635e63318447ca04731b265a86a573c9ed1737c.tar.bz2 |
Add a compilation tracing mechanism to the new compiler.
Code mostly imported from: https://android-review.googlesource.com/#/c/81653/.
Change-Id: I150fe942be0fb270e03fabb19032180f7a065d13
Diffstat (limited to 'compiler/optimizing/graph_visualizer.cc')
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc new file mode 100644 index 0000000..a7604be --- /dev/null +++ b/compiler/optimizing/graph_visualizer.cc @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "graph_visualizer.h" + +#include "driver/dex_compilation_unit.h" +#include "nodes.h" + +namespace art { + +/** + * HGraph visitor to generate a file suitable for the c1visualizer tool and IRHydra. + */ +class HGraphVisualizerPrinter : public HGraphVisitor { + public: + HGraphVisualizerPrinter(HGraph* graph, std::ostream& output) + : HGraphVisitor(graph), output_(output), indent_(0) {} + + void StartTag(const char* name) { + AddIndent(); + output_ << "begin_" << name << std::endl; + indent_++; + } + + void EndTag(const char* name) { + indent_--; + AddIndent(); + output_ << "end_" << name << std::endl; + } + + void PrintProperty(const char* name, const char* property) { + AddIndent(); + output_ << name << " \"" << property << "\"" << std::endl; + } + + void PrintProperty(const char* name, const char* property, int id) { + AddIndent(); + output_ << name << " \"" << property << id << "\"" << std::endl; + } + + void PrintEmptyProperty(const char* name) { + AddIndent(); + output_ << name << std::endl; + } + + void PrintTime(const char* name) { + AddIndent(); + output_ << name << " " << time(NULL) << std::endl; + } + + void PrintInt(const char* name, int value) { + AddIndent(); + output_ << name << " " << value << std::endl; + } + + void AddIndent() { + for (size_t i = 0; i < indent_; ++i) { + output_ << " "; + } + } + + void PrintPredecessors(HBasicBlock* block) { + AddIndent(); + output_ << "predecessors"; + for (size_t i = 0, e = block->GetPredecessors().Size(); i < e; ++i) { + HBasicBlock* predecessor = block->GetPredecessors().Get(i); + output_ << " \"B" << predecessor->GetBlockId() << "\" "; + } + output_<< std::endl; + } + + void PrintSuccessors(HBasicBlock* block) { + AddIndent(); + output_ << "successors"; + for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) { + HBasicBlock* successor = block->GetSuccessors().Get(i); + output_ << " \"B" << successor->GetBlockId() << "\" "; + } + output_<< std::endl; + } + + + void VisitInstruction(HInstruction* instruction) { + output_ << instruction->DebugName(); + if (instruction->InputCount() > 0) { + output_ << " [ "; + for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { + output_ << "v" << inputs.Current()->GetId() << " "; + } + output_ << "]"; + } + } + + void PrintInstructions(const HInstructionList& list) { + const char* kEndInstructionMarker = "<|@"; + for (HInstructionIterator it(list); !it.Done(); it.Advance()) { + HInstruction* instruction = it.Current(); + AddIndent(); + int bci = 0; + output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " "; + instruction->Accept(this); + output_ << kEndInstructionMarker << std::endl; + } + } + + void Run(const char* pass_name) { + StartTag("cfg"); + PrintProperty("name", pass_name); + VisitInsertionOrder(); + EndTag("cfg"); + } + + void VisitBasicBlock(HBasicBlock* block) { + StartTag("block"); + PrintProperty("name", "B", block->GetBlockId()); + PrintInt("from_bci", -1); + PrintInt("to_bci", -1); + PrintPredecessors(block); + PrintSuccessors(block); + PrintEmptyProperty("xhandlers"); + PrintEmptyProperty("flags"); + if (block->GetDominator() != nullptr) { + PrintProperty("dominator", "B", block->GetDominator()->GetBlockId()); + } + + StartTag("states"); + StartTag("locals"); + PrintInt("size", 0); + PrintProperty("method", "None"); + for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { + AddIndent(); + HInstruction* instruction = it.Current(); + output_ << instruction->GetId() << " v" << instruction->GetId() << "[ "; + for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) { + output_ << inputs.Current()->GetId() << " "; + } + output_ << "]" << std::endl; + } + EndTag("locals"); + EndTag("states"); + + StartTag("HIR"); + PrintInstructions(block->GetPhis()); + PrintInstructions(block->GetInstructions()); + EndTag("HIR"); + EndTag("block"); + } + + private: + std::ostream& output_; + size_t indent_; + + DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter); +}; + +HGraphVisualizer::HGraphVisualizer(std::ostream* output, + HGraph* graph, + const char* string_filter, + const DexCompilationUnit& cu) + : output_(output), graph_(graph), is_enabled_(false) { + if (output == nullptr) { + return; + } + std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile()); + if (pretty_name.find(string_filter) == std::string::npos) { + return; + } + + is_enabled_ = true; + HGraphVisualizerPrinter printer(graph, *output_); + printer.StartTag("compilation"); + printer.PrintProperty("name", pretty_name.c_str()); + printer.PrintProperty("method", pretty_name.c_str()); + printer.PrintTime("date"); + printer.EndTag("compilation"); +} + +void HGraphVisualizer::DumpGraph(const char* pass_name) { + if (!is_enabled_) { + return; + } + HGraphVisualizerPrinter printer(graph_, *output_); + printer.Run(pass_name); +} + +} // namespace art |