1 /*
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 #ifndef ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
18 #define ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
19 
20 #include "base/stringprintf.h"
21 #include "nodes.h"
22 
23 namespace art {
24 
25 class HPrettyPrinter : public HGraphVisitor {
26  public:
HPrettyPrinter(HGraph * graph)27   explicit HPrettyPrinter(HGraph* graph) : HGraphVisitor(graph) { }
28 
PrintPreInstruction(HInstruction * instruction)29   void PrintPreInstruction(HInstruction* instruction) {
30     PrintString("  ");
31     PrintInt(instruction->GetId());
32     PrintString(": ");
33   }
34 
VisitInstruction(HInstruction * instruction)35   void VisitInstruction(HInstruction* instruction) OVERRIDE {
36     PrintPreInstruction(instruction);
37     PrintString(instruction->DebugName());
38     PrintPostInstruction(instruction);
39   }
40 
PrintPostInstruction(HInstruction * instruction)41   void PrintPostInstruction(HInstruction* instruction) {
42     if (instruction->InputCount() != 0) {
43       PrintString("(");
44       bool first = true;
45       for (HInputIterator it(instruction); !it.Done(); it.Advance()) {
46         if (first) {
47           first = false;
48         } else {
49           PrintString(", ");
50         }
51         PrintInt(it.Current()->GetId());
52       }
53       PrintString(")");
54     }
55     if (instruction->HasUses()) {
56       PrintString(" [");
57       bool first = true;
58       for (const HUseListNode<HInstruction*>& use : instruction->GetUses()) {
59         if (first) {
60           first = false;
61         } else {
62           PrintString(", ");
63         }
64         PrintInt(use.GetUser()->GetId());
65       }
66       PrintString("]");
67     }
68     PrintNewLine();
69   }
70 
VisitBasicBlock(HBasicBlock * block)71   void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
72     PrintString("BasicBlock ");
73     PrintInt(block->GetBlockId());
74     const ArenaVector<HBasicBlock*>& predecessors = block->GetPredecessors();
75     if (!predecessors.empty()) {
76       PrintString(", pred: ");
77       for (size_t i = 0; i < predecessors.size() -1; i++) {
78         PrintInt(predecessors[i]->GetBlockId());
79         PrintString(", ");
80       }
81       PrintInt(predecessors.back()->GetBlockId());
82     }
83     const ArenaVector<HBasicBlock*>& successors = block->GetSuccessors();
84     if (!successors.empty()) {
85       PrintString(", succ: ");
86       for (size_t i = 0; i < successors.size() - 1; i++) {
87         PrintInt(successors[i]->GetBlockId());
88         PrintString(", ");
89       }
90       PrintInt(successors.back()->GetBlockId());
91     }
92     PrintNewLine();
93     HGraphVisitor::VisitBasicBlock(block);
94   }
95 
96   virtual void PrintNewLine() = 0;
97   virtual void PrintInt(int value) = 0;
98   virtual void PrintString(const char* value) = 0;
99 
100  private:
101   DISALLOW_COPY_AND_ASSIGN(HPrettyPrinter);
102 };
103 
104 class StringPrettyPrinter : public HPrettyPrinter {
105  public:
StringPrettyPrinter(HGraph * graph)106   explicit StringPrettyPrinter(HGraph* graph)
107       : HPrettyPrinter(graph), str_(""), current_block_(nullptr) { }
108 
PrintInt(int value)109   void PrintInt(int value) OVERRIDE {
110     str_ += StringPrintf("%d", value);
111   }
112 
PrintString(const char * value)113   void PrintString(const char* value) OVERRIDE {
114     str_ += value;
115   }
116 
PrintNewLine()117   void PrintNewLine() OVERRIDE {
118     str_ += '\n';
119   }
120 
Clear()121   void Clear() { str_.clear(); }
122 
str()123   std::string str() const { return str_; }
124 
VisitBasicBlock(HBasicBlock * block)125   void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
126     current_block_ = block;
127     HPrettyPrinter::VisitBasicBlock(block);
128   }
129 
VisitGoto(HGoto * gota)130   void VisitGoto(HGoto* gota) OVERRIDE {
131     PrintString("  ");
132     PrintInt(gota->GetId());
133     PrintString(": Goto ");
134     PrintInt(current_block_->GetSuccessors()[0]->GetBlockId());
135     PrintNewLine();
136   }
137 
138  private:
139   std::string str_;
140   HBasicBlock* current_block_;
141 
142   DISALLOW_COPY_AND_ASSIGN(StringPrettyPrinter);
143 };
144 
145 }  // namespace art
146 
147 #endif  // ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
148