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