• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 CPP_ABCKIT_BASIC_BLOCK_H
17 #define CPP_ABCKIT_BASIC_BLOCK_H
18 
19 #include "./base_classes.h"
20 #include "./instruction.h"
21 
22 #include <cstdint>
23 #include <vector>
24 
25 namespace abckit {
26 
27 /**
28  * @brief BasicBlock
29  */
30 class BasicBlock final : public ViewInResource<AbckitBasicBlock *, const Graph *> {
31     // We restrict constructors in order to prevent C/C++ API mix-up by user.
32     /// @brief to access private constructor
33     friend class Graph;
34     /// @brief to access private constructor
35     friend class Instruction;
36     /// @brief abckit::DefaultHash<BasicBlock>
37     friend class abckit::DefaultHash<BasicBlock>;
38 
39 public:
40     /**
41      * @brief Constructor
42      * @param other
43      */
44     BasicBlock(const BasicBlock &other) = default;
45 
46     /**
47      * @brief Constructor
48      * @param other
49      * @return BasicBlock&
50      */
51     BasicBlock &operator=(const BasicBlock &other) = default;
52 
53     /**
54      * @brief Constructor
55      * @param other
56      */
57     BasicBlock(BasicBlock &&other) = default;
58 
59     /**
60      * @brief Constructor
61      * @param other
62      * @return BasicBlock&
63      */
64     BasicBlock &operator=(BasicBlock &&other) = default;
65 
66     /**
67      * @brief Destructor
68      */
69     ~BasicBlock() override = default;
70 
71     /**
72      * @brief Enumerates basic blocks successing to the basicBlock, invoking callback `cb` for each basic block.
73      * @param [ in ] cb - Callback that will be invoked.
74      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
75      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
76      */
77     void VisitSuccBlocks(const std::function<void(BasicBlock)> &cb) const;
78 
79     /**
80      * @brief Enumerates basic blocks predcessing to the basicBlock, invoking callback `cb` for each basic block.
81      * @param [ in ] cb - Callback that will be invoked.
82      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
83      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
84      */
85     void VisitPredBlocks(const std::function<bool(BasicBlock)> &cb) const;
86 
87     /**
88      * @brief Returns the number of basic blocks successing the basicBlock.
89      * @return Number of successor basic blocks.
90      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
91      */
92     uint64_t GetSuccCount() const;
93 
94     /**
95      * @brief Get the Succ By Idx object
96      * @param idx
97      * @return BasicBlock
98      */
99     BasicBlock GetSuccByIdx(uint32_t idx) const;
100 
101     /**
102      * @brief Get the Succs object
103      * @return std::vector<BasicBlock>
104      */
105     std::vector<BasicBlock> GetSuccs() const;
106 
107     /**
108      * @brief Get the Preds object
109      * @return std::vector<BasicBlock>
110      */
111     std::vector<BasicBlock> GetPreds() const;
112 
113     /**
114      * @brief Insert `inst` at the beginning of basicBlock.
115      * @return None.
116      * @param [ in ] inst - Instruction to insert.
117      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
118      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
119      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is constant.
120      * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning basicBlock and `inst`
121      * differs.
122      * @note Allocates
123      */
124     BasicBlock AddInstFront(Instruction inst) const;
125 
126     /**
127      * @brief Appends `inst` at the end of basicBlock.
128      * @return None.
129      * @param [ in ] inst - Instruction to insert.
130      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
131      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
132      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is constant.
133      * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning basicBlock and `inst`
134      * differs.
135      * @note Allocates
136      */
137     BasicBlock AddInstBack(Instruction inst) const;
138 
139     /**
140      * @brief Get the Instructions object
141      * @return std::vector<Instruction>
142      */
143     std::vector<Instruction> GetInstructions() const;
144 
145     /**
146      * @brief Returns first instruction from basicBlock.
147      * @return Pointer to the `AbckitInst`.
148      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
149      */
150     Instruction GetFirstInst() const;
151 
152     /**
153      * @brief Returns last instruction.
154      * @return `Instruction`.
155      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if view itself is false.
156      */
157     Instruction GetLastInst() const;
158 
159     /**
160      * @brief Returns ID of basicBlock.
161      * @return ID of basicBlock.
162      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
163      */
164     uint32_t GetId() const;
165 
166     /**
167      * @brief Returns graph owning basicBlock.
168      * @return Pointer to `AbckitGraph`.
169      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
170      */
171     const Graph *GetGraph() const;
172 
173     /**
174      * @brief Returns the number of basic blocks preceding the basicBlock.
175      * @return Number of predecessor basic blocks.
176      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
177      */
178     uint64_t GetPredBlockCount() const;
179 
180     /**
181      * @brief Returns basic block predcessing to basicBlock under given `index`.
182      * @return Pointer to the `AbckitBasicBlock`.
183      * @param [ in ] index - Index of predecessor basic block.
184      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
185      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if there is no predecessor basic block under given `index`.
186      */
187     BasicBlock GetPredBlock(uint32_t index) const;
188 
189     /**
190      * @brief Returns the number of basic blocks successing the basicBlock.
191      * @return Number of successor basic blocks.
192      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
193      */
194     uint64_t GetSuccBlockCount() const;
195 
196     /**
197      * @brief Returns basic block successing to basicBlock under given `index`.
198      * @return Pointer to the `AbckitBasicBlock`.
199      * @param [ in ] index - Index of successor basic block.
200      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
201      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if there is no successor basic block under given `index`.
202      */
203     BasicBlock GetSuccBlock(uint32_t index) const;
204 
205     /**
206      * @brief Inserts `succBlock` by `index` in basicBlock successors list
207      * and shifts the rest if there were successors with a larger index.
208      * @return None.
209      * @param [ in ] succBlock - Basic block to be inserted.
210      * @param [ in ] index - Index by which the `succBlock` will be inserted.
211      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
212      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `succBlock` is NULL.
213      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` is larger than quantity of basicBlock successors.
214      * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning basicBlock and `succBlock`
215      * differs.
216      * @note Allocates
217      */
218     BasicBlock InsertSuccBlock(BasicBlock succBlock, uint32_t index);
219 
220     /**
221      * @brief Appends successor to the end of basicBlock successors list.
222      * @return None.
223      * @param [ in ] succBlock - Basic block to be inserted.
224      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
225      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `succBlock` is NULL.
226      * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning basicBlock and `succBlock`
227      * differs.
228      */
229     BasicBlock AppendSuccBlock(BasicBlock succBlock);
230 
231     /**
232      * @brief Deletes the successor and shifts the rest if there were successors with a larger index.
233      * @return None.
234      * @param [ in ] index - Index of successor to be deleted.
235      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
236      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` is larger than basicBlock successors quantity.
237      */
238     BasicBlock EraseSuccBlock(uint32_t index);
239 
240     /**
241      * @brief Returns successor of basicBlock with index 0.
242      * @return Pinter to the `AbckitBasicBlock`.
243      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
244      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock has no successors.
245      */
246     BasicBlock GetTrueBranch() const;
247 
248     /**
249      * @brief Returns successor of basicBlock with index 1.
250      * @return Pinter to the `AbckitBasicBlock`.
251      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
252      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock has less than one successor.
253      */
254     BasicBlock GetFalseBranch() const;
255 
256     /**
257      * @brief Removes all instructions from basicBlock.
258      * @return None.
259      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
260      */
261     BasicBlock RemoveAllInsts();
262 
263     /**
264      * @brief Returns number of instruction in basicBlock.
265      * @return Number of instruction in basicBlock.
266      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
267      */
268     uint32_t GetNumberOfInstructions() const;
269 
270     /**
271      * @brief Returns immediate dominator of basicBlock.
272      * @return Pinter to the `AbckitBasicBlock`.
273      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
274      */
275     BasicBlock GetImmediateDominator() const;
276 
277     /**
278      * @brief Checks that basicBlock is dominated by `dominator`
279      * @return True if basicBlock is dominated by `dominator`.
280      * @param [ in ] dom - Basic block to be inspected.
281      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
282      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `dominator` is NULL.
283      * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning basicBlock and `dominator`
284      * differs.
285      */
286     bool CheckDominance(BasicBlock dom) const;
287 
288     /**
289      * @brief Enumerates basic blocks predcessing to the basicBlock, invoking callback `cb` for each basic block.
290      * @param [ in ] cb - Callback that will be invoked.
291      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
292      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
293      */
294     void VisitDominatedBlocks(const std::function<bool(BasicBlock)> &cb) const;
295 
296     /**
297      * @brief Tells if basicBlock is start basic block.
298      * @return `true` if basicBlock is start basic block, `false` otherwise.
299      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
300      */
301     bool IsStart() const;
302 
303     /**
304      * @brief Tells if basicBlock is end basic block.
305      * @return `true` if basicBlock is end basic block, `false` otherwise.
306      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
307      */
308     bool IsEnd() const;
309 
310     /**
311      * @brief Tells if basicBlock is loop head basic block.
312      * @return `true` if basicBlock is loop head basic block, `false` otherwise.
313      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
314      */
315     bool IsLoopHead() const;
316 
317     /**
318      * @brief Tells if basicBlock is loop prehead basic block.
319      * @return `true` if basicBlock is loop prehead basic block, `false` otherwise.
320      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
321      */
322     bool IsLoopPrehead() const;
323 
324     /**
325      * @brief Tells if basicBlock is try begin basic block.
326      * @return `true` if basicBlock is try begin basic block, `false` otherwise.
327      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
328      */
329     bool IsTryBegin() const;
330 
331     /**
332      * @brief Tells if basicBlock is try basic block.
333      * @return `true` if basicBlock is try basic block, `false` otherwise.
334      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
335      */
336     bool IsTry() const;
337 
338     /**
339      * @brief Tells if basicBlock is try end basic block.
340      * @return `true` if basicBlock is try end basic block, `false` otherwise.
341      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
342      */
343     bool IsTryEnd() const;
344 
345     /**
346      * @brief Tells if basicBlock is catch begin basic block.
347      * @return `true` if basicBlock is catch begin basic block, `false` otherwise.
348      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
349      */
350     bool IsCatchBegin() const;
351 
352     /**
353      * @brief Tells if basicBlock is catch basic block.
354      * @return `true` if basicBlock is catch basic block, `false` otherwise.
355      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
356      */
357     bool IsCatch() const;
358 
359     /**
360      * @brief Dumps basicBlock into given file descriptor.
361      * @return None.
362      * @param [ in ] fd - File descriptor where dump is written.
363      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if basicBlock is NULL.
364      * @note Allocates
365      */
366     BasicBlock Dump(int32_t fd);
367 
368     /**
369      * @brief Creates new basic block and moves all instructions after ins into new basic block.
370      * @return Pointer to newly create `AbckitBasicBlock`.
371      * @param [ in ] ins - Instruction after which all instructions will be moved into new basic block.
372      * @param [ in ] makeEdge - If `true` connects old and new basic blocks.
373      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
374      * @note Allocates
375      */
376     BasicBlock SplitBlockAfterInstruction(Instruction ins, bool makeEdge);
377 
378     /**
379      * @brief Creates new Phi instruction
380      * @return Instruction
381      * @param [ in ] args ... - Phi inputs, must be pointers to `AbckitInst`.
382      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
383      * @note Allocates
384      */
385     template <typename... Args>
386     Instruction CreatePhi(Args... args);
387 
388     /**
389      * @brief Creates new Phi instruction
390      * @return Instruction
391      * @param [ in ] args ... - Phi inputs, must be pointers to `AbckitInst`.
392      * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
393      * @note Allocates
394      */
395     template <typename... Args>
396     Instruction CreateCatchPhi(Args... args);
397 
398 protected:
GetApiConfig()399     const ApiConfig *GetApiConfig() const override
400     {
401         return conf_;
402     }
403 
404 private:
BasicBlock(AbckitBasicBlock * bb,const ApiConfig * conf,const Graph * graph)405     BasicBlock(AbckitBasicBlock *bb, const ApiConfig *conf, const Graph *graph) : ViewInResource(bb), conf_(conf)
406     {
407         SetResource(graph);
408     };
409     const ApiConfig *conf_;
410 };
411 
412 }  // namespace abckit
413 
414 #endif  // CPP_ABCKIT_BASIC_BLOCK_H
415