• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef PANDA_DISASSEMBLY_H
17 #define PANDA_DISASSEMBLY_H
18 
19 #include "compiler_options.h"
20 #include "macros.h"
21 #include <fstream>
22 #include <string>
23 #include <variant>
24 #include <memory>
25 
26 namespace ark::compiler {
27 
28 class Codegen;
29 class Encoder;
30 class Inst;
31 class StackMap;
32 
33 class CodeItem {
34 public:
CodeItem(size_t position,size_t cursorOffset,size_t depth)35     CodeItem(size_t position, size_t cursorOffset, size_t depth)
36         : position_(position), cursorOffset_(cursorOffset), depth_(depth)
37     {
38     }
GetPosition()39     size_t GetPosition() const
40     {
41         return position_;
42     }
GetCursorOffset()43     size_t GetCursorOffset() const
44     {
45         return cursorOffset_;
46     }
GetDepth()47     size_t GetDepth() const
48     {
49         return depth_;
50     }
51 
52 private:
53     size_t position_ {0};
54     size_t cursorOffset_ {0};
55     size_t depth_ {0};
56 };
57 
58 using DisassemblyItem = std::variant<CodeItem, std::string>;
59 
60 class Disassembly {
61 public:
62     explicit Disassembly(const Codegen *codegen);
63     ~Disassembly() = default;
64     NO_COPY_SEMANTIC(Disassembly);
65     NO_MOVE_SEMANTIC(Disassembly);
66 
67     void Init();
68 
GetStream()69     std::ostream &GetStream()
70     {
71         return *stream_;
72     }
73     std::string_view GetIndent(uint32_t depth);
GetDepth()74     uint32_t GetDepth() const
75     {
76         return depth_;
77     }
GetPosition()78     uint32_t GetPosition() const
79     {
80         return position_;
81     }
SetPosition(uint32_t pos)82     void SetPosition(uint32_t pos)
83     {
84         position_ = pos;
85     }
GetEncoder()86     const Encoder *GetEncoder() const
87     {
88         return encoder_;
89     }
SetEncoder(const Encoder * encoder)90     void SetEncoder(const Encoder *encoder)
91     {
92         encoder_ = encoder;
93     }
94     void PrintChapter(std::string_view name);
95     void IncreaseDepth();
DecreaseDepth()96     void DecreaseDepth()
97     {
98         depth_--;
99     }
IsEnabled()100     bool IsEnabled() const
101     {
102         return isEnabled_;
103     }
IsCodeEnabled()104     bool IsCodeEnabled() const
105     {
106         return isCodeEnabled_;
107     }
GetItems()108     std::vector<DisassemblyItem> &GetItems()
109     {
110         return items_;
111     }
112 
113     void PrintMethodEntry(const Codegen *codegen);
114     void PrintCodeInfo(const Codegen *codegen);
115     void PrintCodeStatistics(const Codegen *codegen);
116     void PrintStackMap(const Codegen *codegen);
117 
AddCode(size_t position,size_t cursorOffset,size_t depth)118     void AddCode(size_t position, size_t cursorOffset, size_t depth)
119     {
120         CodeItem item(position, cursorOffset, depth);
121         items_.emplace_back(item);
122     }
123 
124 private:
125     void FlushDisasm();
126 
127 private:
128     using StreamDeleterType = void (*)(std::ostream *stream);
129     const Codegen *codegen_ {nullptr};
130     const Encoder *encoder_ {nullptr};
131     std::unique_ptr<std::ostream, StreamDeleterType> stream_;
132     uint32_t depth_ {0};
133     uint32_t position_ {0};
134     bool isEnabled_ {false};
135     bool isCodeEnabled_ {false};
136     std::vector<DisassemblyItem> items_;
137 
138     friend class ScopedDisasmPrinter;
139 };
140 
141 class ScopedDisasmPrinter {
142 public:
143     ScopedDisasmPrinter(Codegen *codegen, const std::string &msg);
144     ScopedDisasmPrinter(Codegen *codegen, const Inst *inst);
145     ~ScopedDisasmPrinter();
146 
147     NO_COPY_SEMANTIC(ScopedDisasmPrinter);
148     NO_MOVE_SEMANTIC(ScopedDisasmPrinter);
149 
150 private:
151     Disassembly *disasm_ {nullptr};
152 };
153 
154 class ItemAppender {
155 public:
ItemAppender(Disassembly * disasm)156     explicit ItemAppender(Disassembly *disasm) : disasm_(disasm) {}
~ItemAppender()157     ~ItemAppender()
158     {
159         disasm_->GetItems().emplace_back(std::move(ss_).str());
160     }
161 
162     NO_COPY_SEMANTIC(ItemAppender);
163     NO_MOVE_SEMANTIC(ItemAppender);
164 
GetStream()165     std::ostringstream &GetStream()
166     {
167         return ss_;
168     }
169 
170 private:
171     Disassembly *disasm_;
172     std::ostringstream ss_;
173 };
174 
175 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
176 #define DISASM_VAR_CONCAT2(a, b) a##b
177 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
178 #define DISASM_VAR_CONCAT(a, b) DISASM_VAR_CONCAT2(a, b)
179 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
180 #define SCOPED_DISASM_INST(codegen, inst) ScopedDisasmPrinter DISASM_VAR_CONCAT(disasm_, __LINE__)(codegen, inst)
181 #ifndef NDEBUG
182 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
183 #define SCOPED_DISASM_STR(codegen, str) ScopedDisasmPrinter DISASM_VAR_CONCAT(disasm_, __LINE__)(codegen, str)
184 #else
185 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
186 #define SCOPED_DISASM_STR(codegen, str) (void)codegen
187 #endif
188 
189 }  // namespace ark::compiler
190 
191 #endif  // PANDA_DISASSEMBLY_H
192