graph_visualizer.cc revision ddb311fdeca82ca628fed694c4702f463b5c4927
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"
21ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray#include "ssa_liveness_analysis.h"
22f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
23f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffraynamespace art {
24f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
25f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray/**
26f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray * HGraph visitor to generate a file suitable for the c1visualizer tool and IRHydra.
27f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray */
28f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayclass HGraphVisualizerPrinter : public HGraphVisitor {
29f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray public:
30f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  HGraphVisualizerPrinter(HGraph* graph, std::ostream& output)
31f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      : HGraphVisitor(graph), output_(output), indent_(0) {}
32f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
33f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void StartTag(const char* name) {
34f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
35f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << "begin_" << name << std::endl;
36f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    indent_++;
37f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
38f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
39f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void EndTag(const char* name) {
40f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    indent_--;
41f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
42f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << "end_" << name << std::endl;
43f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
44f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
45f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintProperty(const char* name, const char* property) {
46f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
47f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << name << " \"" << property << "\"" << std::endl;
48f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
49f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
50f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintProperty(const char* name, const char* property, int id) {
51f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
52f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << name << " \"" << property << id << "\"" << std::endl;
53f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
54f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
55f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintEmptyProperty(const char* name) {
56f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
57f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << name << std::endl;
58f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
59f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
60f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintTime(const char* name) {
61f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
62f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << name << " " << time(NULL) << std::endl;
63f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
64f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
65f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintInt(const char* name, int value) {
66f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
67f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << name << " " << value << std::endl;
68f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
69f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
70f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void AddIndent() {
71f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (size_t i = 0; i < indent_; ++i) {
72f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << "  ";
73f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
74f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
75f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
76f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintPredecessors(HBasicBlock* block) {
77f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
78f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << "predecessors";
79f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (size_t i = 0, e = block->GetPredecessors().Size(); i < e; ++i) {
80f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      HBasicBlock* predecessor = block->GetPredecessors().Get(i);
81f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << " \"B" << predecessor->GetBlockId() << "\" ";
82f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
83f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_<< std::endl;
84f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
85f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
86f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintSuccessors(HBasicBlock* block) {
87f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    AddIndent();
88f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << "successors";
89f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) {
90f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      HBasicBlock* successor = block->GetSuccessors().Get(i);
91f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << " \"B" << successor->GetBlockId() << "\" ";
92f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
93f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_<< std::endl;
94f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
95f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
96f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
97f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void VisitInstruction(HInstruction* instruction) {
98f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    output_ << instruction->DebugName();
99f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    if (instruction->InputCount() > 0) {
100f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << " [ ";
101f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) {
102f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray        output_ << "v" << inputs.Current()->GetId() << " ";
103f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      }
104f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << "]";
105f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
106ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    if (instruction->GetLifetimePosition() != kNoLifetime) {
107ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      output_ << " (liveness: " << instruction->GetLifetimePosition();
108ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      if (instruction->HasLiveInterval()) {
109ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray        output_ << " ";
110ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray        const GrowableArray<LiveRange>& ranges = instruction->GetLiveInterval()->GetRanges();
111ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray        size_t i = ranges.Size() - 1;
112ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray        do {
113ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray          output_ << "[" << ranges.Get(i).GetStart() << "," << ranges.Get(i).GetEnd() << "[";
114ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray          if (i == 0) {
115ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray            break;
116ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray          } else {
117ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray            --i;
118ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray            output_ << ",";
119ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray          }
120ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray        } while (true);
121ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      }
122ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      output_ << ")";
123ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    }
124f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
125f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
126f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void PrintInstructions(const HInstructionList& list) {
127f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    const char* kEndInstructionMarker = "<|@";
128f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (HInstructionIterator it(list); !it.Done(); it.Advance()) {
129f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      HInstruction* instruction = it.Current();
130f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      AddIndent();
131f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      int bci = 0;
132f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << bci << " " << instruction->NumberOfUses() << " v" << instruction->GetId() << " ";
133f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      instruction->Accept(this);
134f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << kEndInstructionMarker << std::endl;
135f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
136f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
137f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
138f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void Run(const char* pass_name) {
139f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("cfg");
140f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintProperty("name", pass_name);
141f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    VisitInsertionOrder();
142f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("cfg");
143f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
144f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
145f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  void VisitBasicBlock(HBasicBlock* block) {
146f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("block");
147f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintProperty("name", "B", block->GetBlockId());
148ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    if (block->GetLifetimeStart() != kNoLifetime) {
149ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      // Piggy back on these fields to show the lifetime of the block.
150ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("from_bci", block->GetLifetimeStart());
151ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("to_bci", block->GetLifetimeEnd());
152ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    } else {
153ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("from_bci", -1);
154ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray      PrintInt("to_bci", -1);
155ddb311fdeca82ca628fed694c4702f463b5c4927Nicolas Geoffray    }
156f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintPredecessors(block);
157f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintSuccessors(block);
158f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintEmptyProperty("xhandlers");
159f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintEmptyProperty("flags");
160f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    if (block->GetDominator() != nullptr) {
161f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      PrintProperty("dominator", "B", block->GetDominator()->GetBlockId());
162f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
163f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
164f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("states");
165f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("locals");
166f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintInt("size", 0);
167f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintProperty("method", "None");
168f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
169f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      AddIndent();
170f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      HInstruction* instruction = it.Current();
171f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << instruction->GetId() << " v" << instruction->GetId() << "[ ";
172f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      for (HInputIterator inputs(instruction); !inputs.Done(); inputs.Advance()) {
173f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray        output_ << inputs.Current()->GetId() << " ";
174f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      }
175f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray      output_ << "]" << std::endl;
176f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    }
177f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("locals");
178f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("states");
179f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
180f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    StartTag("HIR");
181f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintInstructions(block->GetPhis());
182f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    PrintInstructions(block->GetInstructions());
183f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("HIR");
184f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    EndTag("block");
185f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
186f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
187f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray private:
188f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  std::ostream& output_;
189f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  size_t indent_;
190f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
191f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(HGraphVisualizerPrinter);
192f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray};
193f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
194f635e63318447ca04731b265a86a573c9ed1737cNicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output,
195f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray                                   HGraph* graph,
196f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray                                   const char* string_filter,
197f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray                                   const DexCompilationUnit& cu)
198f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    : output_(output), graph_(graph), is_enabled_(false) {
199f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  if (output == nullptr) {
200f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    return;
201f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
202f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  std::string pretty_name = PrettyMethod(cu.GetDexMethodIndex(), *cu.GetDexFile());
203f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  if (pretty_name.find(string_filter) == std::string::npos) {
204f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    return;
205f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
206f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
207f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  is_enabled_ = true;
208f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  HGraphVisualizerPrinter printer(graph, *output_);
209f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.StartTag("compilation");
210f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.PrintProperty("name", pretty_name.c_str());
211f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.PrintProperty("method", pretty_name.c_str());
212f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.PrintTime("date");
213f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.EndTag("compilation");
214f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}
215f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
2160d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas GeoffrayHGraphVisualizer::HGraphVisualizer(std::ostream* output,
2170d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray                                   HGraph* graph,
2180d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray                                   const char* name)
2190d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray    : output_(output), graph_(graph), is_enabled_(false) {
2200d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  if (output == nullptr) {
2210d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray    return;
2220d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  }
2230d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray
2240d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  is_enabled_ = true;
2250d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  HGraphVisualizerPrinter printer(graph, *output_);
2260d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.StartTag("compilation");
2270d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.PrintProperty("name", name);
2280d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.PrintProperty("method", name);
2290d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.PrintTime("date");
2300d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray  printer.EndTag("compilation");
2310d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray}
2320d3f578909d0d1ea072ca68d78301b6fb7a44451Nicolas Geoffray
233f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffrayvoid HGraphVisualizer::DumpGraph(const char* pass_name) {
234f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  if (!is_enabled_) {
235f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray    return;
236f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  }
237f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  HGraphVisualizerPrinter printer(graph_, *output_);
238f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray  printer.Run(pass_name);
239f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}
240f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray
241f635e63318447ca04731b265a86a573c9ed1737cNicolas Geoffray}  // namespace art
242