graph_visualizer.cc revision 86dbb9a12119273039ce272b41c809fa548b37b6
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      }
11186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    } else {
11286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      DCHECK(location.IsStackSlot());
11386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      output_ << location.GetStackIndex() << "(sp)";
11486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    }
11586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  }
11686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray
11786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  void VisitParallelMove(HParallelMove* instruction) {
11886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    output_ << instruction->DebugName();
11986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    output_ << " (";
12086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    for (size_t i = 0, e = instruction->NumMoves(); i < e; ++i) {
12186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      MoveOperands* move = instruction->MoveOperandsAt(i);
12286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      DumpLocation(move->GetSource(), Primitive::kPrimInt);
12386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      output_ << " -> ";
12486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      DumpLocation(move->GetDestination(), Primitive::kPrimInt);
12586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      if (i + 1 != e) {
12686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray        output_ << ", ";
12786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      }
12886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    }
12986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    output_ << ")";
13086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  }
131f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
132f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void VisitInstruction(HInstruction* instruction) {
133f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << instruction->DebugName();
134f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    if (instruction->InputCount() > 0) {
135f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << " [ ";
136f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) {
137f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray        output_ << "v" << inputs.Current()->GetId() << " ";
138f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      }
139f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << "]";
140f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
14186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    if (pass_name_ == kLivenessPassName && instruction->GetLifetimePosition() != kNoLifetime) {
142ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      output_ << " (liveness: " << instruction->GetLifetimePosition();
143ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      if (instruction->HasLiveInterval()) {
144ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray        output_ << " ";
145a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray        const LiveInterval& interval = *instruction->GetLiveInterval();
146a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray        interval.Dump(output_);
14786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      }
14886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      output_ << ")";
14986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    } else if (pass_name_ == kRegisterAllocatorPassName) {
15086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      LocationSummary* locations = instruction->GetLocations();
15186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      if (locations != nullptr) {
15286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray        output_ << " ( ";
15386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray        for (size_t i = 0; i < instruction->InputCount(); ++i) {
15486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray          DumpLocation(locations->InAt(i), instruction->InputAt(i)->GetType());
155a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray          output_ << " ";
15686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray        }
15786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray        output_ << ")";
15886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray        if (locations->Out().IsValid()) {
15986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray          output_ << " -> ";
16086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray          DumpLocation(locations->Out(), instruction->GetType());
161a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray        }
162ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      }
163ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    }
164f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
165f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
166f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintInstructions(const HInstructionList& list) {
167f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    const char* kEndInstructionMarker = "<|@";
168f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (HInstructionIterator it(list); !it.Done(); it.Advance()) {
169f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      HInstruction* instruction = it.Current();
170f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      AddIndent();
171f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      int bci = 0;
172f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " ";
173f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      instruction->Accept(this);
174f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << kEndInstructionMarker << std::endl;
175f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
176f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
177f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
17886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  void Run() {
179f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("cfg");
18086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    PrintProperty("name", pass_name_);
181f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    VisitInsertionOrder();
182f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("cfg");
183f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
184f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
185f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void VisitBasicBlock(HBasicBlock* block) {
186f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("block");
187f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintProperty("name", "B", block->GetBlockId());
188ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    if (block->GetLifetimeStart() != kNoLifetime) {
189ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      // Piggy back on these fields to show the lifetime of the block.
190ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("from_bci", block->GetLifetimeStart());
191ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("to_bci", block->GetLifetimeEnd());
192ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    } else {
193ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("from_bci", -1);
194ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("to_bci", -1);
195ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    }
196f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintPredecessors(block);
197f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintSuccessors(block);
198f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintEmptyProperty("xhandlers");
199f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintEmptyProperty("flags");
200f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    if (block->GetDominator() != nullptr) {
201f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      PrintProperty("dominator", "B", block->GetDominator()->GetBlockId());
202f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
203f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
204f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("states");
205f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("locals");
206f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintInt("size", 0);
207f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintProperty("method", "None");
208f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
209f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      AddIndent();
210f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      HInstruction* instruction = it.Current();
211f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << instruction->GetId() << " v" << instruction->GetId() << "[ ";
212f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) {
213f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray        output_ << inputs.Current()->GetId() << " ";
214f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      }
215f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << "]" << std::endl;
216f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
217f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("locals");
218f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("states");
219f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
220f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("HIR");
221f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintInstructions(block->GetPhis());
222f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintInstructions(block->GetInstructions());
223f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("HIR");
224f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("block");
225f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
226f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
227f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray private:
228f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  std::ostream& output_;
22986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  const char* pass_name_;
230a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  const CodeGenerator& codegen_;
231f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  size_t indent_;
232f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
233f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter);
234f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray};
235f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
236f635e63318447ca04731b265a86a573c9ed1737cNicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output,
237f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray                                   HGraph* graph,
238f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray                                   const char* string_filter,
239a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray                                   const CodeGenerator& codegen,
240f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray                                   const DexCompilationUnit& cu)
241a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray    : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) {
242f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  if (output == nullptr) {
243f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    return;
244f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
245f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile());
246f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  if (pretty_name.find(string_filter) == std::string::npos) {
247f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    return;
248f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
249f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
250f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  is_enabled_ = true;
25186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  HGraphVisualizerPrinter printer(graph, *output_, "", codegen_);
252f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.StartTag("compilation");
253f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.PrintProperty("name", pretty_name.c_str());
254f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.PrintProperty("method", pretty_name.c_str());
255f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.PrintTime("date");
256f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.EndTag("compilation");
257f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}
258f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
2590d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output,
2600d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray                                   HGraph* graph,
261a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray                                   const CodeGenerator& codegen,
2620d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray                                   const char* name)
263a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray    : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) {
2640d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  if (output == nullptr) {
2650d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray    return;
2660d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  }
2670d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray
2680d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  is_enabled_ = true;
26986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  HGraphVisualizerPrinter printer(graph, *output_, "", codegen_);
2700d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.StartTag("compilation");
2710d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.PrintProperty("name", name);
2720d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.PrintProperty("method", name);
2730d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.PrintTime("date");
2740d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.EndTag("compilation");
2750d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray}
2760d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray
277f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayvoid HGraphVisualizer::DumpGraph(const char* pass_name) {
278f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  if (!is_enabled_) {
279f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    return;
280f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
28186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  HGraphVisualizerPrinter printer(graph_, *output_, pass_name, codegen_);
28286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  printer.Run();
283f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}
284f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
285f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}  // namespace art
286