• 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_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