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_INSTRUCTION_H 17 #define CPP_ABCKIT_INSTRUCTION_H 18 19 #include "./base_classes.h" 20 #include "core/export_descriptor.h" 21 #include "./type.h" 22 #include "literal_array.h" 23 24 #include <functional> 25 26 namespace abckit { 27 28 /** 29 * @brief Instruction 30 */ 31 class Instruction final : public ViewInResource<AbckitInst *, const Graph *> { 32 // To access private constructor. 33 // We restrict constructors in order to prevent C/C++ API mix-up by user. 34 35 /// @brief To access private constructor 36 friend class BasicBlock; 37 /// @brief To access private constructor 38 friend class StaticIsa; 39 /// @brief To access private constructor 40 friend class DynamicIsa; 41 /// @brief abckit::DefaultHash<Instruction> 42 friend class abckit::DefaultHash<Instruction>; 43 /// @brief To access private constructor 44 friend class Graph; 45 46 public: 47 /** 48 * @brief Construct a new empty Instruction object 49 */ Instruction()50 Instruction() : ViewInResource(nullptr), conf_(nullptr) 51 { 52 SetResource(nullptr); 53 }; 54 55 /** 56 * @brief Construct a new Instruction object 57 * @param other 58 */ 59 Instruction(const Instruction &other) = default; 60 61 /** 62 * @brief Constructor 63 * @param other 64 * @return Instruction 65 */ 66 Instruction &operator=(const Instruction &other) = default; 67 68 /** 69 * @brief Constructor 70 * @param other 71 */ 72 Instruction(Instruction &&other) = default; 73 74 /** 75 * @brief Constructor 76 * @param other 77 * @return Instruction 78 */ 79 Instruction &operator=(Instruction &&other) = default; 80 81 /** 82 * @brief Destructor 83 */ 84 ~Instruction() override = default; 85 86 /** 87 * @brief Inserts `newInst` instruction after `ref` instruction into `ref`'s basic block. 88 * @param inst 89 * @return Instruction& 90 */ 91 Instruction InsertAfter(Instruction inst) const; 92 93 /** 94 * @brief Inserts `newInst` instruction before `ref` instruction into `ref`'s basic block. 95 * @param inst 96 * @return Instruction& 97 */ 98 Instruction InsertBefore(Instruction inst) const; 99 100 /** 101 * @brief Removes instruction from it's basic block. 102 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `bool(*this)` results in `false` 103 */ 104 void Remove() const; 105 106 /** 107 * @brief Returns value of I64 constant `Instruction`. 108 * @return Value of `Instruction`. 109 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `bool(*this)` results in `false` 110 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `Instruction` is not a constant instruction. 111 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `Instruction` is not I64 constant instruction. 112 */ 113 int64_t GetConstantValueI64() const; 114 115 /** 116 * @brief Get the String object 117 * @return std::string 118 */ 119 std::string GetString() const; 120 121 /** 122 * @brief Get the Next object 123 * @return Instruction 124 */ 125 Instruction GetNext() const; 126 127 /** 128 * @brief Get the Prev object 129 * @return Instruction 130 */ 131 Instruction GetPrev() const; 132 133 /** 134 * @brief Get the Function object 135 * @return core::Function 136 */ 137 core::Function GetFunction() const; 138 139 /** 140 * @brief Returns basic block that owns `Instruction`. 141 * @return `BasicBlock` which contains this `Instruction`. 142 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `bool(*this)` results in `false` 143 */ 144 BasicBlock GetBasicBlock() const; 145 146 /** 147 * @brief Returns number of inputs. 148 * @return Number of inputs. 149 */ 150 uint32_t GetInputCount() const; 151 152 /** 153 * @brief Returns `inst` input under given `index`. 154 * @param [ in ] index - Index of input to be returned. 155 * @return input `Instruction` 156 */ 157 Instruction GetInput(uint32_t index) const; 158 159 /** 160 * @brief Sets input, overwrites existing input. 161 * @return Instruction. 162 * @param [ in ] index - Index of input to be set. 163 * @param [ in ] input - Input instruction to be set. 164 */ 165 Instruction SetInput(uint32_t index, Instruction input) const; 166 167 /** 168 * @brief Enumerates `insts` user instructions, invoking callback `cb` for each user instruction. 169 * @param cb - Callback that will be invoked. 170 * @return bool 171 */ 172 bool VisitUsers(const std::function<bool(Instruction)> &cb) const; 173 174 /** 175 * @brief Returns number of `Instruction` users. 176 * @return Number of this `Instruction` users. 177 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `bool(*this)` results in `false` 178 */ 179 uint32_t GetUserCount() const; 180 181 /** 182 * @brief Returns LiteralArray argument of `Instruction`. 183 * @return LiteralArray 184 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `Instruction` is false. 185 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `Instruction` has no LiteralArray argument. 186 */ 187 LiteralArray GetLiteralArray() const; 188 189 /** 190 * @brief Returns a pointer to Graph that owns Instruction 191 * @return pointer to owning Graph 192 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `Instruction` is false. 193 */ 194 const Graph *GetGraph() const; 195 196 /** 197 * @brief Returns Type argument of Instruction. 198 * @return `core::Export`. 199 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `Instruction` is false. 200 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `Instruction` has no LiteralArray argument. 201 */ 202 Type GetType() const; 203 204 /** 205 * @brief Returns size in bits of this `Instruction` immediate under given `index`. 206 * @param [ in ] index - Index of immediate to get size. 207 * @return Size of this `Instruction` immediate under given `index` in bits. 208 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if this `Instruction` is false. 209 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if this `Instruction` has no immediates. 210 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` larger than this `Instruction` immediates number. 211 */ 212 enum AbckitBitImmSize GetImmediateSize(size_t index) const; 213 214 /** 215 * @brief Returns ID of instruction. 216 * @return ID of instruction. 217 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 218 */ 219 uint32_t GetId() const; 220 221 /** 222 * @brief Checks that inst is dominated by `dominator`. 223 * @return `true` if inst is dominated by `dominator`, `false` otherwise. 224 * @param [ in ] dominator - Instruction to be inspected. 225 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 226 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `dominator` is NULL. 227 * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `inst` and `dominator` differs. 228 */ 229 bool CheckDominance(Instruction dominator) const; 230 231 /** 232 * @brief Checks if `inst` is "call" instruction. 233 * @return `true` if `inst` is "call" instruction, `false` otherwise. 234 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 235 */ 236 bool CheckIsCall() const; 237 238 /** 239 * @brief Enumerates `insts` input instructions, invoking callback `cb` for each input instruction. 240 * @return `false` if was early exited. Otherwise - `true`. 241 * @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time 242 * it is invoked. 243 * @param [ in ] cb - Callback that will be invoked. Should return `false` on early exit and `true` when iterations 244 * should continue. 245 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 246 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL. 247 */ 248 bool VisitInputs(void *data, bool (*cb)(AbckitInst *input, size_t inputIdx, void *data)) const; 249 250 /** 251 * @brief Sets input instructions for `inst` starting from index 0, overwrites existing inputs. 252 * @return Instruction. 253 * @param [ in ] instrs ... - Instructions to be set as input for `inst`. 254 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 255 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if one of inst inputs are NULL. 256 * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `inst` and input inst differs. 257 */ 258 template <typename... Args> 259 Instruction SetInputs(Args... instrs); 260 261 /** 262 * @brief Appends `input` instruction to `inst` inputs. 263 * @return Instruction. 264 * @param [ in ] input - Instruction to be appended as input. 265 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 266 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `input` is NULL. 267 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not applicable for input appending. 268 * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `inst` and `input` differs. 269 * @note Allocates 270 */ 271 Instruction AppendInput(Instruction input) const; 272 273 /** 274 * @brief Dumps given `inst` into given file descriptor. 275 * @return None. 276 * @param [ in ] fd - File descriptor where dump is written. 277 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 278 * @note Allocates 279 */ 280 Instruction Dump(int32_t fd) const; 281 282 /** 283 * @brief Sets `inst` function operand. 284 * @return None. 285 * @param [ in ] function - Function to be set as `inst` operand. 286 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 287 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `function` is NULL. 288 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no function operand. 289 * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitFile`s owning `inst` and `function` differs. 290 */ 291 Instruction SetFunction(core::Function function) const; 292 293 /** 294 * @brief Returns `inst` immediate under given `index`. 295 * @return uint64_t . 296 * @param [ in ] index - Index of immediate. 297 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 298 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no immediates. 299 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` larger than `inst` immediates number. 300 */ 301 uint64_t GetImmediate(size_t index) const; 302 303 /** 304 * @brief Sets `inst` immediate under given `index` with value `imm`. 305 * @return None. 306 * @param [ in ] index - Index of immediate to be set. 307 * @param [ in ] imm - Value of immediate to be set. 308 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 309 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no immediates. 310 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` larger than `inst` immediates number. 311 */ 312 Instruction SetImmediate(size_t index, uint64_t imm) const; 313 314 /** 315 * @brief Returns number of `inst` immediates. 316 * @return Number of `inst` immediates. 317 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 318 */ 319 uint64_t GetImmediateCount() const; 320 321 /** 322 * @brief Sets `inst` literal array operand. 323 * @return None. 324 * @param [ in ] la - Literal array to be set as operand. 325 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 326 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `la` is NULL. 327 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no literal array operand. 328 * @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitFile`s owning `inst` and `la` differs. 329 */ 330 Instruction SetLiteralArray(LiteralArray la) const; 331 332 /** 333 * @brief Sets `inst` string operand. 334 * @return None. 335 * @param [ in ] s - String to be set as operand. 336 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 337 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `s` is NULL. 338 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no string operand. 339 */ 340 Instruction SetString(std::string_view s) const; 341 342 /** 343 * @brief Returns value of I32 constant `inst`. 344 * @return Value of `inst`. 345 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 346 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not a constant instruction. 347 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not I32 constant instruction. 348 */ 349 int32_t GetConstantValueI32() const; 350 351 /** 352 * @brief Returns value of U64 constant `inst`. 353 * @return Value of `inst`. 354 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 355 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not a constant instruction. 356 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not U64 constant instruction. 357 */ 358 uint64_t GetConstantValueU64() const; 359 360 /** 361 * @brief Returns value of F64 constant `inst`. 362 * @return Value of `inst`. 363 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL. 364 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not a constant instruction. 365 * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not F64 constant instruction. 366 */ 367 double GetConstantValueF64() const; 368 369 protected: 370 /** 371 * @brief Get the Api Config object 372 * @return const ApiConfig* 373 */ GetApiConfig()374 const ApiConfig *GetApiConfig() const override 375 { 376 return conf_; 377 } 378 379 private: 380 /** 381 * @brief Construct a new Instruction object 382 * @param inst 383 * @param conf 384 * @param graph 385 */ Instruction(AbckitInst * inst,const ApiConfig * conf,const Graph * graph)386 Instruction(AbckitInst *inst, const ApiConfig *conf, const Graph *graph) : ViewInResource(inst), conf_(conf) 387 { 388 SetResource(graph); 389 }; 390 const ApiConfig *conf_; 391 }; 392 393 } // namespace abckit 394 395 #endif // CPP_ABCKIT_INSTRUCTION_H 396