summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/graph_visualizer.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-05-14 09:43:38 +0100
committerNicolas Geoffray <ngeoffray@google.com>2014-05-14 14:26:11 +0100
commitf635e63318447ca04731b265a86a573c9ed1737c (patch)
tree47cab84a6ac47d8a4f5f281e3eabdf1780f220d0 /compiler/optimizing/graph_visualizer.cc
parentd115735fe5523ff72319f0968f773683323c7f79 (diff)
downloadart-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.cc199
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