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