blob: b9c1164eb5d18dba6d7ba2a570f4c4865bdbb854 [file] [log] [blame]
Nicolas Geoffrayf635e632014-05-14 09:43:38 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "graph_visualizer.h"
18
19#include "driver/dex_compilation_unit.h"
20#include "nodes.h"
21
22namespace art {
23
24/**
25 * HGraph visitor to generate a file suitable for the c1visualizer tool and IRHydra.
26 */
27class HGraphVisualizerPrinter : public HGraphVisitor {
28 public:
29 HGraphVisualizerPrinter(HGraph* graph, std::ostream& output)
30 : HGraphVisitor(graph), output_(output), indent_(0) {}
31
32 void StartTag(const char* name) {
33 AddIndent();
34 output_ << "begin_" << name << std::endl;
35 indent_++;
36 }
37
38 void EndTag(const char* name) {
39 indent_--;
40 AddIndent();
41 output_ << "end_" << name << std::endl;
42 }
43
44 void PrintProperty(const char* name, const char* property) {
45 AddIndent();
46 output_ << name << " \"" << property << "\"" << std::endl;
47 }
48
49 void PrintProperty(const char* name, const char* property, int id) {
50 AddIndent();
51 output_ << name << " \"" << property << id << "\"" << std::endl;
52 }
53
54 void PrintEmptyProperty(const char* name) {
55 AddIndent();
56 output_ << name << std::endl;
57 }
58
59 void PrintTime(const char* name) {
60 AddIndent();
61 output_ << name << " " << time(NULL) << std::endl;
62 }
63
64 void PrintInt(const char* name, int value) {
65 AddIndent();
66 output_ << name << " " << value << std::endl;
67 }
68
69 void AddIndent() {
70 for (size_t i = 0; i < indent_; ++i) {
71 output_ << " ";
72 }
73 }
74
75 void PrintPredecessors(HBasicBlock* block) {
76 AddIndent();
77 output_ << "predecessors";
78 for (size_t i = 0, e = block->GetPredecessors().Size(); i < e; ++i) {
79 HBasicBlock* predecessor = block->GetPredecessors().Get(i);
80 output_ << " \"B" << predecessor->GetBlockId() << "\" ";
81 }
82 output_<< std::endl;
83 }
84
85 void PrintSuccessors(HBasicBlock* block) {
86 AddIndent();
87 output_ << "successors";
88 for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) {
89 HBasicBlock* successor = block->GetSuccessors().Get(i);
90 output_ << " \"B" << successor->GetBlockId() << "\" ";
91 }
92 output_<< std::endl;
93 }
94
95
96 void VisitInstruction(HInstruction* instruction) {
97 output_ << instruction->DebugName();
98 if (instruction->InputCount() > 0) {
99 output_ << " [ ";
100 for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) {
101 output_ << "v" << inputs.Current()->GetId() << " ";
102 }
103 output_ << "]";
104 }
105 }
106
107 void PrintInstructions(const HInstructionList& list) {
108 const char* kEndInstructionMarker = "<|@";
109 for (HInstructionIterator it(list); !it.Done(); it.Advance()) {
110 HInstruction* instruction = it.Current();
111 AddIndent();
112 int bci = 0;
113 output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " ";
114 instruction->Accept(this);
115 output_ << kEndInstructionMarker << std::endl;
116 }
117 }
118
119 void Run(const char* pass_name) {
120 StartTag("cfg");
121 PrintProperty("name", pass_name);
122 VisitInsertionOrder();
123 EndTag("cfg");
124 }
125
126 void VisitBasicBlock(HBasicBlock* block) {
127 StartTag("block");
128 PrintProperty("name", "B", block->GetBlockId());
129 PrintInt("from_bci", -1);
130 PrintInt("to_bci", -1);
131 PrintPredecessors(block);
132 PrintSuccessors(block);
133 PrintEmptyProperty("xhandlers");
134 PrintEmptyProperty("flags");
135 if (block->GetDominator() != nullptr) {
136 PrintProperty("dominator", "B", block->GetDominator()->GetBlockId());
137 }
138
139 StartTag("states");
140 StartTag("locals");
141 PrintInt("size", 0);
142 PrintProperty("method", "None");
143 for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
144 AddIndent();
145 HInstruction* instruction = it.Current();
146 output_ << instruction->GetId() << " v" << instruction->GetId() << "[ ";
147 for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) {
148 output_ << inputs.Current()->GetId() << " ";
149 }
150 output_ << "]" << std::endl;
151 }
152 EndTag("locals");
153 EndTag("states");
154
155 StartTag("HIR");
156 PrintInstructions(block->GetPhis());
157 PrintInstructions(block->GetInstructions());
158 EndTag("HIR");
159 EndTag("block");
160 }
161
162 private:
163 std::ostream& output_;
164 size_t indent_;
165
166 DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter);
167};
168
169HGraphVisualizer::HGraphVisualizer(std::ostream* output,
170 HGraph* graph,
171 const char* string_filter,
172 const DexCompilationUnit& cu)
173 : output_(output), graph_(graph), is_enabled_(false) {
174 if (output == nullptr) {
175 return;
176 }
177 std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile());
178 if (pretty_name.find(string_filter) == std::string::npos) {
179 return;
180 }
181
182 is_enabled_ = true;
183 HGraphVisualizerPrinter printer(graph, *output_);
184 printer.StartTag("compilation");
185 printer.PrintProperty("name", pretty_name.c_str());
186 printer.PrintProperty("method", pretty_name.c_str());
187 printer.PrintTime("date");
188 printer.EndTag("compilation");
189}
190
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +0100191HGraphVisualizer::HGraphVisualizer(std::ostream* output,
192 HGraph* graph,
193 const char* name)
194 : output_(output), graph_(graph), is_enabled_(false) {
195 if (output == nullptr) {
196 return;
197 }
198
199 is_enabled_ = true;
200 HGraphVisualizerPrinter printer(graph, *output_);
201 printer.StartTag("compilation");
202 printer.PrintProperty("name", name);
203 printer.PrintProperty("method", name);
204 printer.PrintTime("date");
205 printer.EndTag("compilation");
206}
207
Nicolas Geoffrayf635e632014-05-14 09:43:38 +0100208void HGraphVisualizer::DumpGraph(const char* pass_name) {
209 if (!is_enabled_) {
210 return;
211 }
212 HGraphVisualizerPrinter printer(graph_, *output_);
213 printer.Run(pass_name);
214}
215
216} // namespace art