1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "graph.h"
17 #include "basicblock.h"
18 #include "dump.h"
19 #include "visualizer_printer.h"
20
21 namespace ark::compiler {
Print()22 void VisualizerPrinter::Print()
23 {
24 PrintBeginTag("cfg");
25 PrintProperty("name", ArenaString(passName_, graph_->GetLocalAllocator()->Adapter()));
26 for (const auto &block : graph_->GetBlocksRPO()) {
27 PrintBasicBlock(block);
28 }
29 PrintEndTag("cfg");
30 }
31
PrintBeginTag(const char * tag)32 void VisualizerPrinter::PrintBeginTag(const char *tag)
33 {
34 (*output_) << MakeOffset() << "begin_" << tag << "\n";
35 ++offset_;
36 }
37
PrintEndTag(const char * tag)38 void VisualizerPrinter::PrintEndTag(const char *tag)
39 {
40 --offset_;
41 (*output_) << MakeOffset() << "end_" << tag << "\n";
42 }
43
MakeOffset()44 std::string VisualizerPrinter::MakeOffset()
45 {
46 return std::string(offset_ << 1U, ' ');
47 }
48
PrintProperty(const char * prop,const ArenaString & value)49 void VisualizerPrinter::PrintProperty(const char *prop, const ArenaString &value)
50 {
51 (*output_) << MakeOffset() << prop;
52 if (!value.empty()) {
53 (*output_) << " \"" << value << "\"";
54 }
55 (*output_) << "\n";
56 }
57
PrintProperty(const char * prop,int value)58 void VisualizerPrinter::PrintProperty(const char *prop, int value)
59 {
60 (*output_) << MakeOffset() << std::dec << prop << " " << value << "\n";
61 }
62
63 template <typename T>
PrintDependences(const std::string & preffix,const T & blocks)64 void VisualizerPrinter::PrintDependences(const std::string &preffix, const T &blocks)
65 {
66 (*output_) << MakeOffset() << preffix << " ";
67 for (const auto &block : blocks) {
68 (*output_) << "\"B" << BBId(block, graph_->GetLocalAllocator()) << "\" ";
69 }
70 (*output_) << "\n";
71 }
72
PrintBasicBlock(BasicBlock * block)73 void VisualizerPrinter::PrintBasicBlock(BasicBlock *block)
74 {
75 PrintBeginTag("block");
76 PrintProperty("name", "B" + BBId(block, graph_->GetLocalAllocator()));
77 PrintProperty("from_bci", -1);
78 PrintProperty("to_bci", -1);
79 PrintDependences("predecessors", block->GetPredsBlocks());
80 PrintDependences("successors", block->GetSuccsBlocks());
81 PrintProperty("xhandlers", ArenaString("", graph_->GetLocalAllocator()->Adapter()));
82 PrintProperty("flags", ArenaString("", graph_->GetLocalAllocator()->Adapter()));
83 PrintProperty("loop_depth", 0);
84 PrintBeginTag("states");
85 PrintBeginTag("locals");
86 PrintProperty("size", 0);
87 PrintProperty("method", ArenaString("None", graph_->GetLocalAllocator()->Adapter()));
88 PrintEndTag("locals");
89 PrintEndTag("states");
90 PrintBeginTag("HIR");
91 PrintInsts(block);
92 PrintEndTag("HIR");
93 PrintEndTag("block");
94 }
95
PrintInsts(BasicBlock * block)96 void VisualizerPrinter::PrintInsts(BasicBlock *block)
97 {
98 if (block->AllInsts().begin() != block->AllInsts().end()) {
99 for (auto inst : block->AllInsts()) {
100 PrintInst(inst);
101 }
102 } else {
103 (*output_) << MakeOffset() << "0 0 - ";
104 if (block->IsStartBlock()) {
105 (*output_) << "EMPTY_START_BLOCK";
106 } else if (block->IsEndBlock()) {
107 (*output_) << "EXIT_BLOCK";
108 } else {
109 (*output_) << "EMPTY_BLOCK";
110 }
111 (*output_) << " <|@\n";
112 }
113 }
114
PrintInst(Inst * inst)115 void VisualizerPrinter::PrintInst(Inst *inst)
116 {
117 uint32_t usersSize = 0;
118 for (auto it = inst->GetUsers().begin(); it != inst->GetUsers().end(); ++it) {
119 usersSize++;
120 }
121 (*output_) << MakeOffset() << "0 " << std::dec << usersSize << " ";
122 (*output_) << InstId(inst, graph_->GetLocalAllocator()) << " ";
123 inst->DumpOpcode(output_);
124 (*output_) << " type:" << DataType::ToString(inst->GetType()) << " ";
125 (*output_) << "inputs: ";
126 bool hasInput = inst->DumpInputs(output_);
127 if (hasInput && !inst->GetUsers().Empty()) {
128 (*output_) << " users: ";
129 }
130 DumpUsers(inst, output_);
131 (*output_) << " <|@\n";
132 }
133 } // namespace ark::compiler
134