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