• 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 #include "ir_static.h"
17 
18 #include "datatype.h"
19 #include "libabckit/include/c/ir_core.h"
20 #include "libabckit/include/c/statuses.h"
21 #include "libabckit/src/adapter_static/helpers_static.h"
22 
23 #include "libabckit/include/c/metadata_core.h"
24 #include "libabckit/src/statuses_impl.h"
25 #include "libabckit/src/macros.h"
26 #include "libabckit/src/metadata_inspect_impl.h"
27 #include "libabckit/src/helpers_common.h"
28 #include "libabckit/src/ir_impl.h"
29 #include "libabckit/src/wrappers/pandasm_wrapper.h"
30 
31 #include "static_core/assembler/assembly-program.h"
32 #include "static_core/assembler/mangling.h"
33 
34 #include "static_core/compiler/optimizer/ir/graph.h"
35 #include "static_core/compiler/optimizer/ir/basicblock.h"
36 #include "static_core/compiler/optimizer/ir/inst.h"
37 #include "static_core/compiler/optimizer/analysis/loop_analyzer.h"
38 
39 #include "generated/insn_info.h"
40 
41 #include "abckit_intrinsics_opcodes.inc"
42 
43 #include <cstdarg>
44 #include <cstdint>
45 
46 namespace libabckit {
47 
48 #include "inst_props_helpers_dynamic.inc"
49 
50 // helpers for getting inst operand's info
51 // for dynamic insts helpers are autogenerated by inst_props_helpers_dynamic.inc.erb
HasMethodIdOperandStatic(AbckitIsaApiStaticOpcode opcode)52 static bool HasMethodIdOperandStatic(AbckitIsaApiStaticOpcode opcode)
53 {
54     switch (opcode) {
55         case ABCKIT_ISA_API_STATIC_OPCODE_INITOBJECT:
56         case ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC:
57         case ABCKIT_ISA_API_STATIC_OPCODE_CALL_VIRTUAL:
58             return true;
59         default:
60             return false;
61     }
62 }
63 
GetMethodIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)64 static int GetMethodIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)
65 {
66     switch (opcode) {
67         case ABCKIT_ISA_API_STATIC_OPCODE_INITOBJECT:
68         case ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC:
69         case ABCKIT_ISA_API_STATIC_OPCODE_CALL_VIRTUAL:
70             return 0;
71         default:
72             return 0;
73     }
74 }
75 
HasStringIdOperandStatic(AbckitIsaApiStaticOpcode opcode)76 static bool HasStringIdOperandStatic(AbckitIsaApiStaticOpcode opcode)
77 {
78     switch (opcode) {
79         case ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING:
80             return true;
81         default:
82             return false;
83     }
84 }
85 
GetStringIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)86 static int GetStringIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)
87 {
88     switch (opcode) {
89         case ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING:
90             return 0;
91         default:
92             return 0;
93     }
94 }
95 
HasLiteralArrayIdOperandStatic(AbckitIsaApiStaticOpcode opcode)96 static bool HasLiteralArrayIdOperandStatic(AbckitIsaApiStaticOpcode opcode)
97 {
98     switch (opcode) {
99         case ABCKIT_ISA_API_STATIC_OPCODE_LOADCONSTARRAY:
100             return true;
101         default:
102             return false;
103     }
104 }
105 
GetLiteralArrayIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)106 static int GetLiteralArrayIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)
107 {
108     switch (opcode) {
109         case ABCKIT_ISA_API_STATIC_OPCODE_LOADCONSTARRAY:
110             return 0;
111         default:
112             return 0;
113     }
114 }
115 
HasTypeIdOperandStatic(AbckitIsaApiStaticOpcode opcode)116 [[maybe_unused]] static bool HasTypeIdOperandStatic(AbckitIsaApiStaticOpcode opcode)
117 {
118     switch (opcode) {
119         case ABCKIT_ISA_API_STATIC_OPCODE_NEWARRAY:
120         case ABCKIT_ISA_API_STATIC_OPCODE_NEWOBJECT:
121         case ABCKIT_ISA_API_STATIC_OPCODE_CHECKCAST:
122         case ABCKIT_ISA_API_STATIC_OPCODE_ISINSTANCE:
123             return true;
124         default:
125             return false;
126     }
127 }
128 
GetTypeIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)129 [[maybe_unused]] static int GetTypeIdOperandIndexStatic(AbckitIsaApiStaticOpcode opcode)
130 {
131     switch (opcode) {
132         case ABCKIT_ISA_API_STATIC_OPCODE_NEWARRAY:
133         case ABCKIT_ISA_API_STATIC_OPCODE_NEWOBJECT:
134         case ABCKIT_ISA_API_STATIC_OPCODE_CHECKCAST:
135         case ABCKIT_ISA_API_STATIC_OPCODE_ISINSTANCE:
136             return 0;
137         default:
138             return -1;
139     }
140 }
141 
142 // ========================================
143 // Api for Graph manipulation
144 // ========================================
145 
GfindOrCreateConstantI64Static(AbckitGraph * graph,int64_t value)146 AbckitInst *GfindOrCreateConstantI64Static(AbckitGraph *graph, int64_t value)
147 {
148     LIBABCKIT_LOG_FUNC;
149     if (graph == nullptr) {
150         LIBABCKIT_LOG(DEBUG) << "nullptr argument\n";
151         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
152         return nullptr;
153     }
154     auto constantI64Impl = graph->impl->FindOrCreateConstant(value);
155     return CreateInstFromImpl(graph, constantI64Impl);
156 }
157 
GfindOrCreateConstantI32Static(AbckitGraph * graph,int32_t value)158 AbckitInst *GfindOrCreateConstantI32Static(AbckitGraph *graph, int32_t value)
159 {
160     LIBABCKIT_LOG_FUNC;
161     if (graph == nullptr) {
162         LIBABCKIT_LOG(DEBUG) << "nullptr argument\n";
163         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
164         return nullptr;
165     }
166     auto constantI32Impl = graph->impl->FindOrCreateConstant(value);
167     return CreateInstFromImpl(graph, constantI32Impl);
168 }
169 
GfindOrCreateConstantU64Static(AbckitGraph * graph,uint64_t value)170 AbckitInst *GfindOrCreateConstantU64Static(AbckitGraph *graph, uint64_t value)
171 {
172     LIBABCKIT_LOG_FUNC;
173     if (graph == nullptr) {
174         LIBABCKIT_LOG(DEBUG) << "nullptr argument\n";
175         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
176         return nullptr;
177     }
178     auto constantU64Impl = graph->impl->FindOrCreateConstant(value);
179     return CreateInstFromImpl(graph, constantU64Impl);
180 }
181 
GfindOrCreateConstantF64Static(AbckitGraph * graph,double value)182 AbckitInst *GfindOrCreateConstantF64Static(AbckitGraph *graph, double value)
183 {
184     LIBABCKIT_LOG_FUNC;
185     // check inputs are valid
186     if (graph == nullptr) {
187         LIBABCKIT_LOG(DEBUG) << "nullptr argument\n";
188         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
189         return nullptr;
190     }
191     auto constantF64Impl = graph->impl->FindOrCreateConstant(value);
192     return CreateInstFromImpl(graph, constantF64Impl);
193 }
194 
GgetNumberOfBasicBlocksStatic(AbckitGraph * graph)195 uint32_t GgetNumberOfBasicBlocksStatic(AbckitGraph *graph)
196 {
197     LIBABCKIT_LOG_FUNC;
198     if (graph == nullptr) {
199         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
200         return 0;
201     }
202     return graph->impl->GetVectorBlocks().size();
203 }
204 
GgetBasicBlockStatic(AbckitGraph * graph,uint32_t id)205 AbckitBasicBlock *GgetBasicBlockStatic(AbckitGraph *graph, uint32_t id)
206 {
207     LIBABCKIT_LOG_FUNC;
208     if (graph == nullptr) {
209         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
210         return nullptr;
211     }
212     if (id >= graph->impl->GetVectorBlocks().size()) {
213         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
214         return nullptr;
215     }
216     auto *bbImpl = graph->impl->GetVectorBlocks()[id];
217     return graph->implToBB.at(bbImpl);
218 }
219 
GgetNumberOfParametersStatic(AbckitGraph * graph)220 uint32_t GgetNumberOfParametersStatic(AbckitGraph *graph)
221 {
222     auto list = graph->impl->GetParameters();
223     auto ins = list.begin();
224     uint32_t size = 0;
225     while (ins != list.end()) {
226         ++ins;
227         ++size;
228     }
229     return size;
230 }
231 
GgetParameterStatic(AbckitGraph * graph,uint32_t index)232 AbckitInst *GgetParameterStatic(AbckitGraph *graph, uint32_t index)
233 {
234     LIBABCKIT_LOG_FUNC;
235     if (graph == nullptr) {
236         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
237         return nullptr;
238     }
239 
240     if (index >= GgetNumberOfParametersStatic(graph)) {
241         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
242         return nullptr;
243     }
244 
245     auto list = graph->impl->GetParameters();
246     auto ins = list.begin();
247     for (uint32_t i = 0; i < index; i++) {
248         if (ins != list.end()) {
249             ++ins;
250         }
251     }
252     return graph->implToInst.at(*ins);
253 }
254 
SetTryBlocks(AbckitGraph * graph,AbckitBasicBlock * tryLastBB,AbckitBasicBlock * tryBeginBB,AbckitBasicBlock * tryEndBB)255 void SetTryBlocks(AbckitGraph *graph, AbckitBasicBlock *tryLastBB, AbckitBasicBlock *tryBeginBB,
256                   AbckitBasicBlock *tryEndBB)
257 {
258     tryBeginBB->impl->SetTryBegin(true);
259     tryBeginBB->impl->SetTryId(tryBeginBB->impl->GetId());
260     graph->impl->AppendTryBeginBlock(tryBeginBB->impl);
261     AbckitInst *tryInst = IcreateTryStatic(graph);
262     BBaddInstFrontStatic(tryBeginBB, tryInst);
263 
264     tryEndBB->impl->SetTryEnd(true);
265     tryEndBB->impl->SetTryId(tryBeginBB->impl->GetTryId());
266     // NOTE(nsizov): NOTE, calculate guest pc for new created blocks (abckit-wise problem)
267     tryEndBB->impl->SetGuestPc(tryLastBB->impl->GetGuestPc() - 1);
268     tryInst->impl->CastToTry()->SetTryEndBlock(tryEndBB->impl);
269     // NOTE(nsizov): NOTE, set proper typeid for catch blocks (abckit-wise problem)
270     tryInst->impl->CastToTry()->AppendCatchTypeId(0, 1);
271 }
272 
273 struct VisitorData {
274     AbckitBasicBlock *cur;
275     AbckitBasicBlock *tryBegin;
276     AbckitBasicBlock *tryEnd;
277     AbckitBasicBlock *catchEnd;
278     std::unordered_set<AbckitBasicBlock *> *visited;
279     std::queue<AbckitBasicBlock *> *toVisit;
280 };
281 
VisitBbs(AbckitBasicBlock * tryFirstBB,AbckitBasicBlock * tryLastBB,AbckitBasicBlock * catchBeginBB,AbckitBasicBlock * tryBeginBB,std::unordered_set<AbckitBasicBlock * > * visited,std::queue<AbckitBasicBlock * > * toVisit,VisitorData visitorData)282 void VisitBbs(AbckitBasicBlock *tryFirstBB, AbckitBasicBlock *tryLastBB, AbckitBasicBlock *catchBeginBB,
283               AbckitBasicBlock *tryBeginBB, std::unordered_set<AbckitBasicBlock *> *visited,
284               std::queue<AbckitBasicBlock *> *toVisit, VisitorData visitorData)
285 {
286     visitorData.cur = tryFirstBB;
287 
288     // A data to pass into visitors traverse
289 
290     BBvisitPredBlocksStatic(tryFirstBB, &visitorData, [](AbckitBasicBlock *predBasicBlock, void *data) {
291         AbckitBasicBlock *curBasicBlock = static_cast<struct VisitorData *>(data)->cur;
292         AbckitBasicBlock *tryBeginBB = static_cast<struct VisitorData *>(data)->tryBegin;
293 
294         predBasicBlock->impl->ReplaceSucc(curBasicBlock->impl, tryBeginBB->impl);
295         curBasicBlock->impl->RemovePred(predBasicBlock->impl);
296         return true;
297     });
298 
299     BBappendSuccBlockStatic(tryBeginBB, tryFirstBB);
300     BBappendSuccBlockStatic(tryBeginBB, catchBeginBB);
301 
302     visitorData.cur = tryLastBB;
303 
304     BBvisitPredBlocksStatic(tryLastBB, &visitorData, [](AbckitBasicBlock *predBasicBlock, void *data) {
305         AbckitBasicBlock *curBasicBlock = static_cast<struct VisitorData *>(data)->cur;
306         AbckitBasicBlock *tryEndBB = static_cast<struct VisitorData *>(data)->tryEnd;
307 
308         predBasicBlock->impl->ReplaceSucc(curBasicBlock->impl, tryEndBB->impl);
309         curBasicBlock->impl->RemovePred(predBasicBlock->impl);
310         return true;
311     });
312 
313     toVisit->push(tryBeginBB);
314 
315     while (!(*toVisit).empty()) {
316         AbckitBasicBlock *curBB = toVisit->front();
317         visitorData.cur = curBB;
318         toVisit->pop();
319         visited->insert(curBB);
320         curBB->impl->SetTry(true);
321         curBB->impl->SetTryId(tryBeginBB->impl->GetTryId());
322         BBvisitSuccBlocksStatic(curBB, &visitorData, [](AbckitBasicBlock *succBasicBlock, void *data) {
323             if (succBasicBlock->impl->IsTryEnd() || succBasicBlock->impl->IsCatchBegin() ||
324                 succBasicBlock->impl->IsEndBlock()) {
325                 return false;
326             }
327 
328             auto *visited = static_cast<struct VisitorData *>(data)->visited;
329             auto *toVisit = static_cast<struct VisitorData *>(data)->toVisit;
330 
331             auto it = visited->find(succBasicBlock);
332             if (it == visited->end()) {
333                 toVisit->push(succBasicBlock);
334             }
335             return true;
336         });
337     }
338 }
339 
CheckCatchEnv(AbckitBasicBlock * tryFirstBB,AbckitBasicBlock * tryLastBB)340 bool CheckCatchEnv(AbckitBasicBlock *tryFirstBB, AbckitBasicBlock *tryLastBB)
341 {
342     // NOTE(nsizov): check input for dominance tryFirstBB -> tryLastBB
343     //               and catchBeginBB -> catchEndBB
344 
345     if (BBisStartStatic(tryFirstBB) || BBisEndStatic(tryFirstBB)) {
346         LIBABCKIT_LOG(DEBUG) << "tryFirstBB cannot be niether 'start' nor 'end' block";
347         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
348         return false;
349     }
350 
351     if (BBisStartStatic(tryLastBB) || BBisEndStatic(tryLastBB)) {
352         LIBABCKIT_LOG(DEBUG) << "tryLastBB cannot be niether 'start' nor 'end' block";
353         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
354         return false;
355     }
356     return true;
357 }
358 
GinsertTryCatchStatic(AbckitBasicBlock * tryFirstBB,AbckitBasicBlock * tryLastBB,AbckitBasicBlock * catchBeginBB,AbckitBasicBlock * catchEndBB)359 void GinsertTryCatchStatic(AbckitBasicBlock *tryFirstBB, AbckitBasicBlock *tryLastBB, AbckitBasicBlock *catchBeginBB,
360                            AbckitBasicBlock *catchEndBB)
361 {
362     LIBABCKIT_LOG_FUNC;
363     if (!CheckCatchEnv(tryFirstBB, tryLastBB)) {
364         return;
365     }
366 
367     AbckitGraph *graph = tryFirstBB->graph;
368 
369     // NOTE(nsizov): implement for static mode as well
370     if (!IsDynamic(graph->function->owningModule->target)) {
371         libabckit::statuses::SetLastError(ABCKIT_STATUS_WRONG_TARGET);
372         return;
373     }
374 
375     if ((graph != tryLastBB->graph) || (graph != catchBeginBB->graph) || (graph != catchEndBB->graph)) {
376         SetLastError(ABCKIT_STATUS_WRONG_CTX);
377         return;
378     }
379 
380     AbckitBasicBlock *tryBeginBB = BBcreateEmptyStatic(graph);
381     AbckitBasicBlock *tryEndBB = BBcreateEmptyStatic(graph);
382     SetTryBlocks(graph, tryLastBB, tryBeginBB, tryEndBB);
383 
384     catchBeginBB->impl->SetCatchBegin(true);
385     if (catchBeginBB != catchEndBB) {
386         catchEndBB->impl->SetCatch(true);
387     }
388 
389     std::unordered_set<AbckitBasicBlock *> visited;
390     std::queue<AbckitBasicBlock *> toVisit;
391 
392     auto visitorData = VisitorData {nullptr, tryBeginBB, tryEndBB, catchEndBB, &visited, &toVisit};
393 
394     VisitBbs(tryFirstBB, tryLastBB, catchBeginBB, tryBeginBB, &visited, &toVisit, visitorData);
395 
396     visited.erase(visited.begin(), visited.end());
397     std::queue<AbckitBasicBlock *>().swap(toVisit);
398 
399     while (!toVisit.empty()) {
400         AbckitBasicBlock *curBB = toVisit.front();
401         toVisit.pop();
402         visited.insert(curBB);
403         curBB->impl->SetCatch(true);
404         curBB->impl->SetTryId(tryBeginBB->impl->GetTryId());
405         BBvisitSuccBlocksStatic(curBB, &visitorData, [](AbckitBasicBlock *succBasicBlock, void *data) {
406             auto catchEndBB = static_cast<struct VisitorData *>(data)->catchEnd;
407 
408             // NOTE(ivagin) if (succBasicBlock->impl->IsCatchEnd()
409             if (succBasicBlock == catchEndBB || succBasicBlock->impl->IsTry()) {
410                 return false;
411             }
412 
413             auto *visited = static_cast<struct VisitorData *>(data)->visited;
414             auto *toVisit = static_cast<struct VisitorData *>(data)->toVisit;
415 
416             if (visited->find(succBasicBlock) == visited->end()) {
417                 toVisit->push(succBasicBlock);
418             }
419             return true;
420         });
421     }
422 
423     BBappendSuccBlockStatic(tryEndBB, tryLastBB);
424     BBappendSuccBlockStatic(tryEndBB, catchBeginBB);
425     BBappendSuccBlockStatic(catchEndBB, tryLastBB);
426 }
427 
GgetStartBasicBlockStatic(AbckitGraph * graph)428 AbckitBasicBlock *GgetStartBasicBlockStatic(AbckitGraph *graph)
429 {
430     LIBABCKIT_LOG_FUNC;
431     LIBABCKIT_BAD_ARGUMENT(graph, nullptr);
432     ark::compiler::BasicBlock *bbImpl = graph->impl->GetStartBlock();
433     auto *bb = graph->implToBB.at(bbImpl);
434 
435     return bb;
436 }
437 
GgetEndBasicBlockStatic(AbckitGraph * graph)438 AbckitBasicBlock *GgetEndBasicBlockStatic(AbckitGraph *graph)
439 {
440     LIBABCKIT_LOG_FUNC;
441     LIBABCKIT_BAD_ARGUMENT(graph, nullptr);
442     ark::compiler::BasicBlock *bbImpl = graph->impl->GetEndBlock();
443     auto *bb = graph->implToBB.at(bbImpl);
444 
445     return bb;
446 }
447 
IdumpStatic(AbckitInst * inst,int fd)448 void IdumpStatic(AbckitInst *inst, int fd)
449 {
450     LIBABCKIT_LOG_FUNC;
451     std::stringstream ss;
452     inst->impl->Dump(&ss);
453     write(fd, ss.str().data(), ss.str().size());
454 }
455 
GdumpStatic(AbckitGraph * graph,int fd)456 void GdumpStatic(AbckitGraph *graph, int fd)
457 {
458     LIBABCKIT_LOG_FUNC;
459     if (GraphHasUnreachableBlocks(graph->impl)) {
460         LIBABCKIT_LOG(DEBUG) << "Cannot dump, there are unreachable blocks in graph\n";
461         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
462         return;
463     }
464     std::stringstream ss;
465     graph->impl->Dump(&ss);
466     write(fd, ss.str().data(), ss.str().size());
467 }
468 
GrunPassRemoveUnreachableBlocksStatic(AbckitGraph * graph)469 void GrunPassRemoveUnreachableBlocksStatic(AbckitGraph *graph)
470 {
471     LIBABCKIT_LOG_FUNC;
472     graph->impl->RemoveUnreachableBlocks();
473     GraphInvalidateAnalyses(graph->impl);
474 }
475 
GvisitBlocksRPOStatic(AbckitGraph * graph,void * data,bool (* cb)(AbckitBasicBlock * bb,void * data))476 bool GvisitBlocksRPOStatic(AbckitGraph *graph, void *data, bool (*cb)(AbckitBasicBlock *bb, void *data))
477 {
478     LIBABCKIT_LOG_FUNC;
479     LIBABCKIT_BAD_ARGUMENT(graph, false)
480     LIBABCKIT_BAD_ARGUMENT(cb, false)
481 
482     if (GraphHasUnreachableBlocks(graph->impl)) {
483         LIBABCKIT_LOG(DEBUG) << "Cannot get blocks RPO, there are unreachable blocks in graph\n";
484         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
485         return false;
486     }
487 
488     std::stringstream ss;
489     for (auto *bbImpl : graph->impl->GetBlocksRPO()) {
490         auto *bb = graph->implToBB.at(bbImpl);
491         if (!cb(bb, data)) {
492             return false;
493         }
494     }
495     return true;
496 }
497 
498 // ========================================
499 // Api for basic block manipulation
500 // ========================================
501 
BBvisitSuccBlocksStatic(AbckitBasicBlock * curBasicBlock,void * data,bool (* cb)(AbckitBasicBlock * succBasicBlock,void * data))502 bool BBvisitSuccBlocksStatic(AbckitBasicBlock *curBasicBlock, void *data,
503                              bool (*cb)(AbckitBasicBlock *succBasicBlock, void *data))
504 {
505     LIBABCKIT_LOG_FUNC;
506     LIBABCKIT_BAD_ARGUMENT(curBasicBlock, false)
507     LIBABCKIT_BAD_ARGUMENT(cb, false)
508 
509     auto *graph = curBasicBlock->graph;
510     auto *bbImpl = curBasicBlock->impl;
511     auto succImpls = bbImpl->GetSuccsBlocks();
512     for (auto *succImpl : succImpls) {
513         auto *succ = graph->implToBB.at(succImpl);
514         if (!cb(succ, data)) {
515             return false;
516         }
517     }
518     return true;
519 }
520 
BBvisitPredBlocksStatic(AbckitBasicBlock * curBasicBlock,void * data,bool (* cb)(AbckitBasicBlock * succBasicBlock,void * data))521 bool BBvisitPredBlocksStatic(AbckitBasicBlock *curBasicBlock, void *data,
522                              bool (*cb)(AbckitBasicBlock *succBasicBlock, void *data))
523 {
524     LIBABCKIT_LOG_FUNC;
525     LIBABCKIT_BAD_ARGUMENT(curBasicBlock, false)
526     LIBABCKIT_BAD_ARGUMENT(cb, false)
527 
528     auto *graph = curBasicBlock->graph;
529     auto *bbImpl = curBasicBlock->impl;
530     auto predImpls = bbImpl->GetPredsBlocks();
531     for (auto *predImpl : predImpls) {
532         auto *pred = graph->implToBB.at(predImpl);
533         if (!cb(pred, data)) {
534             return false;
535         }
536     }
537     return true;
538 }
539 
BBcreateEmptyStatic(AbckitGraph * graph)540 AbckitBasicBlock *BBcreateEmptyStatic(AbckitGraph *graph)
541 {
542     LIBABCKIT_LOG_FUNC;
543     LIBABCKIT_BAD_ARGUMENT(graph, nullptr);
544 
545     auto *bbImpl = graph->impl->CreateEmptyBlock(0U);
546     auto *bb = graph->impl->GetLocalAllocator()->New<AbckitBasicBlock>();
547     bb->graph = graph;
548     bb->impl = bbImpl;
549     graph->implToBB.insert({bbImpl, bb});
550     GraphInvalidateAnalyses(graph->impl);
551     return bb;
552 }
553 
BBaddInstFrontStatic(AbckitBasicBlock * basicBlock,AbckitInst * inst)554 void BBaddInstFrontStatic(AbckitBasicBlock *basicBlock, AbckitInst *inst)
555 {
556     LIBABCKIT_LOG_FUNC;
557     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
558     LIBABCKIT_BAD_ARGUMENT_VOID(inst)
559 
560     LIBABCKIT_WRONG_CTX_VOID(basicBlock->graph, inst->graph);
561 
562     if (inst->impl->IsConst()) {
563         LIBABCKIT_LOG(DEBUG) << "can't use constant instruction as an argument";
564         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
565         return;
566     }
567 
568     basicBlock->impl->PrependInst(inst->impl);
569 }
570 
BBsplitBlockAfterInstructionStatic(AbckitBasicBlock * basicBlock,AbckitInst * inst,bool makeEdge)571 AbckitBasicBlock *BBsplitBlockAfterInstructionStatic(AbckitBasicBlock *basicBlock, AbckitInst *inst, bool makeEdge)
572 {
573     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
574     LIBABCKIT_BAD_ARGUMENT(inst, nullptr);
575 
576     auto *bbImpl = inst->impl->GetBasicBlock();
577     auto *newBbImpl = bbImpl->SplitBlockAfterInstruction(inst->impl, makeEdge);
578 
579     auto *iBb = IgetBasicBlockStatic(inst);
580     if (iBb != basicBlock) {
581         LIBABCKIT_LOG(DEBUG) << "Instruction should be in basic block";
582         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
583         return nullptr;
584     }
585 
586     auto *bb = inst->graph->impl->GetLocalAllocator()->New<AbckitBasicBlock>();
587     bb->graph = inst->graph;
588     bb->impl = newBbImpl;
589     inst->graph->implToBB.insert({newBbImpl, bb});
590     GraphInvalidateAnalyses(basicBlock->graph->impl);
591     return bb;
592 }
593 
BBaddInstBackStatic(AbckitBasicBlock * basicBlock,AbckitInst * inst)594 void BBaddInstBackStatic(AbckitBasicBlock *basicBlock, AbckitInst *inst)
595 {
596     LIBABCKIT_LOG_FUNC;
597     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
598     LIBABCKIT_BAD_ARGUMENT_VOID(inst)
599 
600     LIBABCKIT_WRONG_CTX_VOID(basicBlock->graph, inst->graph);
601 
602     if (inst->impl->IsConst()) {
603         LIBABCKIT_LOG(DEBUG) << "can't use constant instruction as an argument";
604         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
605         return;
606     }
607 
608     basicBlock->impl->AppendInst(inst->impl);
609 }
610 
BBgetLastInstStatic(AbckitBasicBlock * basicBlock)611 AbckitInst *BBgetLastInstStatic(AbckitBasicBlock *basicBlock)
612 {
613     LIBABCKIT_LOG_FUNC;
614     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
615 
616     auto *bb = basicBlock->impl;
617     auto *inst = bb->GetLastInst();
618     if (inst == nullptr) {
619         return nullptr;
620     }
621     return basicBlock->graph->implToInst.at(inst);
622 }
623 
BBgetGraphStatic(AbckitBasicBlock * basicBlock)624 AbckitGraph *BBgetGraphStatic(AbckitBasicBlock *basicBlock)
625 {
626     LIBABCKIT_LOG_FUNC;
627     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
628 
629     return basicBlock->graph;
630 }
631 
BBgetFirstInstStatic(AbckitBasicBlock * basicBlock)632 AbckitInst *BBgetFirstInstStatic(AbckitBasicBlock *basicBlock)
633 {
634     LIBABCKIT_LOG_FUNC;
635     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
636 
637     auto *bbImpl = basicBlock->impl;
638 
639     ark::compiler::Inst *instImpl = bbImpl->GetFirstPhi();
640     if (instImpl == nullptr) {
641         instImpl = bbImpl->GetFirstInst();
642     }
643     if (instImpl == nullptr) {
644         return nullptr;
645     }
646 
647     auto *inst = basicBlock->graph->implToInst.at(instImpl);
648     return inst;
649 }
650 
BBdisconnectSuccBlockStatic(AbckitBasicBlock * bb,size_t index)651 void BBdisconnectSuccBlockStatic(AbckitBasicBlock *bb, size_t index)
652 {
653     LIBABCKIT_LOG_FUNC;
654     LIBABCKIT_BAD_ARGUMENT_VOID(bb)
655 
656     if (index >= bb->impl->GetSuccsBlocks().size()) {
657         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
658         return;
659     }
660 
661     auto succ = bb->impl->GetSuccessor(index);
662     succ->RemovePred(bb->impl);
663     bb->impl->RemoveSucc(succ);
664     GraphInvalidateAnalyses(bb->graph->impl);
665 }
666 
BBremoveAllInstsStatic(AbckitBasicBlock * basicBlock)667 void BBremoveAllInstsStatic(AbckitBasicBlock *basicBlock)
668 {
669     LIBABCKIT_LOG_FUNC;
670     basicBlock->impl->Clear();
671 }
672 
BBgetSuccBlockStatic(AbckitBasicBlock * basicBlock,uint32_t index)673 AbckitBasicBlock *BBgetSuccBlockStatic(AbckitBasicBlock *basicBlock, uint32_t index)
674 {
675     LIBABCKIT_LOG_FUNC;
676     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
677     if (index >= basicBlock->impl->GetSuccsBlocks().size()) {
678         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
679         return nullptr;
680     }
681 
682     auto *succImpl = basicBlock->impl->GetSuccsBlocks()[index];
683 
684     return basicBlock->graph->implToBB.at(succImpl);
685 }
686 
BBgetSuccBlockCountStatic(AbckitBasicBlock * basicBlock)687 uint64_t BBgetSuccBlockCountStatic(AbckitBasicBlock *basicBlock)
688 {
689     LIBABCKIT_LOG_FUNC;
690     LIBABCKIT_BAD_ARGUMENT(basicBlock, 0);
691 
692     return basicBlock->impl->GetSuccsBlocks().size();
693 }
694 
BBgetIdStatic(AbckitBasicBlock * basicBlock)695 uint32_t BBgetIdStatic([[maybe_unused]] AbckitBasicBlock *basicBlock)
696 {
697     LIBABCKIT_LOG_FUNC;
698     LIBABCKIT_BAD_ARGUMENT(basicBlock, 0);
699 
700     return basicBlock->impl->GetId();
701 }
702 
BBgetPredBlockStatic(AbckitBasicBlock * basicBlock,uint32_t index)703 AbckitBasicBlock *BBgetPredBlockStatic(AbckitBasicBlock *basicBlock, uint32_t index)
704 {
705     LIBABCKIT_LOG_FUNC;
706     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
707 
708     if (index >= basicBlock->impl->GetPredsBlocks().size()) {
709         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
710         return nullptr;
711     }
712 
713     auto *predImpl = basicBlock->impl->GetPredsBlocks()[index];
714 
715     return basicBlock->graph->implToBB.at(predImpl);
716 }
717 
BBgetPredBlockCountStatic(AbckitBasicBlock * basicBlock)718 uint64_t BBgetPredBlockCountStatic(AbckitBasicBlock *basicBlock)
719 {
720     LIBABCKIT_LOG_FUNC;
721     LIBABCKIT_BAD_ARGUMENT(basicBlock, 0);
722 
723     return basicBlock->impl->GetPredsBlocks().size();
724 }
725 
BBisStartStatic(AbckitBasicBlock * basicBlock)726 bool BBisStartStatic(AbckitBasicBlock *basicBlock)
727 {
728     LIBABCKIT_LOG_FUNC;
729     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
730 
731     return basicBlock->impl->IsStartBlock();
732 }
733 
BBisEndStatic(AbckitBasicBlock * basicBlock)734 bool BBisEndStatic(AbckitBasicBlock *basicBlock)
735 {
736     LIBABCKIT_LOG_FUNC;
737     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
738 
739     return basicBlock->impl->IsEndBlock();
740 }
741 
BBgetNumberOfInstructionsStatic(AbckitBasicBlock * basicBlock)742 uint32_t BBgetNumberOfInstructionsStatic(AbckitBasicBlock *basicBlock)
743 {
744     LIBABCKIT_LOG_FUNC;
745     LIBABCKIT_BAD_ARGUMENT(basicBlock, 0);
746 
747     return basicBlock->impl->CountInsts();
748 }
749 
BBisLoopHeadStatic(AbckitBasicBlock * basicBlock)750 bool BBisLoopHeadStatic(AbckitBasicBlock *basicBlock)
751 {
752     LIBABCKIT_LOG_FUNC;
753     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
754 
755     return basicBlock->impl->IsLoopHeader();
756 }
757 
BBisLoopPreheadStatic(AbckitBasicBlock * basicBlock)758 bool BBisLoopPreheadStatic(AbckitBasicBlock *basicBlock)
759 {
760     LIBABCKIT_LOG_FUNC;
761     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
762 
763     return basicBlock->impl->IsLoopPreHeader();
764 }
765 
BBisTryBeginStatic(AbckitBasicBlock * basicBlock)766 bool BBisTryBeginStatic(AbckitBasicBlock *basicBlock)
767 {
768     LIBABCKIT_LOG_FUNC;
769     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
770 
771     return basicBlock->impl->IsTryBegin();
772 }
773 
BBisTryStatic(AbckitBasicBlock * basicBlock)774 bool BBisTryStatic(AbckitBasicBlock *basicBlock)
775 {
776     LIBABCKIT_LOG_FUNC;
777     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
778 
779     return basicBlock->impl->IsTry();
780 }
781 
BBisTryEndStatic(AbckitBasicBlock * basicBlock)782 bool BBisTryEndStatic(AbckitBasicBlock *basicBlock)
783 {
784     LIBABCKIT_LOG_FUNC;
785     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
786 
787     return basicBlock->impl->IsTryEnd();
788 }
789 
BBisCatchBeginStatic(AbckitBasicBlock * basicBlock)790 bool BBisCatchBeginStatic(AbckitBasicBlock *basicBlock)
791 {
792     LIBABCKIT_LOG_FUNC;
793     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
794 
795     return basicBlock->impl->IsCatchBegin();
796 }
797 
BBisCatchStatic(AbckitBasicBlock * basicBlock)798 bool BBisCatchStatic(AbckitBasicBlock *basicBlock)
799 {
800     LIBABCKIT_LOG_FUNC;
801     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
802 
803     return basicBlock->impl->IsCatch();
804 }
805 
BBdumpStatic(AbckitBasicBlock * basicBlock,int)806 void BBdumpStatic(AbckitBasicBlock *basicBlock, int /*fd*/)
807 {
808     LIBABCKIT_LOG_FUNC;
809     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
810 
811     std::stringstream ss;
812     LIBABCKIT_LOG_DUMP(basicBlock->impl->Dump(&ss), DEBUG);
813 }
814 
BBcheckDominanceStatic(AbckitBasicBlock * basicBlock,AbckitBasicBlock * dominator)815 bool BBcheckDominanceStatic(AbckitBasicBlock *basicBlock, AbckitBasicBlock *dominator)
816 {
817     LIBABCKIT_LOG_FUNC;
818     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
819     LIBABCKIT_BAD_ARGUMENT(dominator, false);
820 
821     LIBABCKIT_WRONG_CTX(basicBlock->graph, dominator->graph, false);
822 
823     if (!GraphDominatorsTreeAnalysisIsValid(basicBlock->graph->impl)) {
824         LIBABCKIT_LOG(DEBUG) << "DominatorsTree analysis is not valid\n";
825         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
826         return false;
827     }
828 
829     return dominator->impl->IsDominate(basicBlock->impl);
830 }
831 
BBgetImmediateDominatorStatic(AbckitBasicBlock * basicBlock)832 AbckitBasicBlock *BBgetImmediateDominatorStatic(AbckitBasicBlock *basicBlock)
833 {
834     LIBABCKIT_LOG_FUNC;
835     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
836 
837     if (!GraphDominatorsTreeAnalysisIsValid(basicBlock->graph->impl)) {
838         LIBABCKIT_LOG(DEBUG) << "DominatorsTree analysis is not valid\n";
839         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
840         return nullptr;
841     }
842 
843     auto *bb = basicBlock->impl->GetDominator();
844     return basicBlock->graph->implToBB.at(bb);
845 }
846 
BBvisitDominatedBlocksStatic(AbckitBasicBlock * basicBlock,void * data,bool (* cb)(AbckitBasicBlock * dominatedBasicBlock,void * data))847 bool BBvisitDominatedBlocksStatic(AbckitBasicBlock *basicBlock, void *data,
848                                   bool (*cb)(AbckitBasicBlock *dominatedBasicBlock, void *data))
849 {
850     LIBABCKIT_LOG_FUNC;
851     LIBABCKIT_BAD_ARGUMENT(basicBlock, false)
852     LIBABCKIT_BAD_ARGUMENT(cb, false)
853 
854     if (!GraphDominatorsTreeAnalysisIsValid(basicBlock->graph->impl)) {
855         LIBABCKIT_LOG(DEBUG) << "DominatorsTree analysis is not valid\n";
856         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
857         return false;
858     }
859 
860     for (auto *bbImpl : basicBlock->impl->GetDominatedBlocks()) {
861         auto *bb = basicBlock->graph->implToBB.at(bbImpl);
862         if (!cb(bb, data)) {
863             return false;
864         }
865     }
866     return true;
867 }
868 
BBinsertSuccBlockStatic(AbckitBasicBlock * basicBlock,AbckitBasicBlock * succBlock,uint32_t index)869 void BBinsertSuccBlockStatic(AbckitBasicBlock *basicBlock, AbckitBasicBlock *succBlock, uint32_t index)
870 {
871     LIBABCKIT_LOG_FUNC;
872     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
873     LIBABCKIT_BAD_ARGUMENT_VOID(succBlock)
874 
875     LIBABCKIT_WRONG_CTX_VOID(basicBlock->graph, succBlock->graph);
876 
877     auto &bbs = basicBlock->impl->GetSuccsBlocks();
878     if (index > bbs.size()) {
879         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
880         return;
881     }
882 
883     if (index == bbs.size()) {
884         bbs.emplace_back(succBlock->impl);
885     } else {
886         bbs.resize(bbs.size() + 1);
887         for (size_t i = index + 1; i < bbs.size(); i++) {
888             bbs[i] = bbs[i - 1];
889         }
890         bbs[index] = succBlock->impl;
891     }
892 
893     succBlock->impl->GetPredsBlocks().emplace_back(basicBlock->impl);
894     GraphInvalidateAnalyses(basicBlock->graph->impl);
895 }
896 
BBappendSuccBlockStatic(AbckitBasicBlock * basicBlock,AbckitBasicBlock * succBlock)897 void BBappendSuccBlockStatic(AbckitBasicBlock *basicBlock, AbckitBasicBlock *succBlock)
898 {
899     LIBABCKIT_LOG_FUNC;
900     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
901     LIBABCKIT_BAD_ARGUMENT_VOID(succBlock)
902 
903     LIBABCKIT_WRONG_CTX_VOID(basicBlock->graph, succBlock->graph);
904 
905     basicBlock->impl->GetSuccsBlocks().emplace_back(succBlock->impl);
906     succBlock->impl->GetPredsBlocks().emplace_back(basicBlock->impl);
907     GraphInvalidateAnalyses(basicBlock->graph->impl);
908 }
909 
BBgetTrueBranchStatic(AbckitBasicBlock * bb)910 AbckitBasicBlock *BBgetTrueBranchStatic(AbckitBasicBlock *bb)
911 {
912     LIBABCKIT_LOG_FUNC;
913     LIBABCKIT_BAD_ARGUMENT(bb, nullptr);
914 
915     if (bb->impl->GetSuccsBlocks().empty()) {
916         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
917         return nullptr;
918     }
919     auto *tb = bb->impl->GetTrueSuccessor();
920     ASSERT(tb != nullptr);
921 
922     return bb->graph->implToBB.at(tb);
923 }
924 
BBgetFalseBranchStatic(AbckitBasicBlock * bb)925 AbckitBasicBlock *BBgetFalseBranchStatic(AbckitBasicBlock *bb)
926 {
927     LIBABCKIT_LOG_FUNC;
928     LIBABCKIT_BAD_ARGUMENT(bb, nullptr);
929 
930     if (bb->impl->GetSuccsBlocks().size() < 2U) {
931         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
932         return nullptr;
933     }
934     auto *fb = bb->impl->GetFalseSuccessor();
935     ASSERT(fb != nullptr);
936 
937     return bb->graph->implToBB.at(fb);
938 }
939 
BBcreatePhiStatic(AbckitBasicBlock * bb,size_t argCount,std::va_list args)940 AbckitInst *BBcreatePhiStatic(AbckitBasicBlock *bb, size_t argCount, std::va_list args)
941 {
942     LIBABCKIT_LOG_FUNC;
943 
944     LIBABCKIT_LOG(DEBUG) << argCount << '\n';
945     if (argCount < 1) {
946         LIBABCKIT_LOG(DEBUG) << "not enough inputs\n";
947         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
948         return nullptr;
949     }
950 
951     std::vector<AbckitInst *> inputs;
952 
953     for (size_t index = 0; index < argCount; ++index) {
954         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
955         AbckitInst *input = va_arg(args, AbckitInst *);
956         LIBABCKIT_BAD_ARGUMENT(input, nullptr);
957         inputs.emplace_back(input);
958     }
959 
960     ark::compiler::DataType::Type type = inputs[0]->impl->GetType();
961     if (IsDynamic(bb->graph->function->owningModule->target)) {
962         type = ark::compiler::DataType::ANY;
963     }
964 
965     for (auto *inst : inputs) {
966         if (IsDynamic(bb->graph->function->owningModule->target)) {
967             if (inst->impl->GetType() != ark::compiler::DataType::INT64 &&
968                 inst->impl->GetType() != ark::compiler::DataType::ANY) {
969                 LIBABCKIT_LOG(DEBUG) << "inconsistent input types\n";
970                 SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
971                 return nullptr;
972             }
973         } else {
974             if (type != inst->impl->GetType()) {
975                 LIBABCKIT_LOG(DEBUG) << "inconsistent input types\n";
976                 SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
977                 return nullptr;
978             }
979         }
980     }
981 
982     auto phiImpl = bb->graph->impl->CreateInstPhi(type, 0);
983     bb->impl->AppendPhi(phiImpl);
984     auto *phi = CreateInstFromImpl(bb->graph, phiImpl);
985     for (auto *inst : inputs) {
986         phiImpl->AppendInput(inst->impl);
987     }
988     return phi;
989 }
990 
BBcreateCatchPhiStatic(AbckitBasicBlock * catchBegin,size_t argCount,std::va_list args)991 AbckitInst *BBcreateCatchPhiStatic(AbckitBasicBlock *catchBegin, size_t argCount, std::va_list args)
992 {
993     auto *instImpl = catchBegin->graph->impl->CreateInstCatchPhi();
994     auto *catchPhi = CreateInstFromImpl(catchBegin->graph, instImpl);
995 
996     BBaddInstFrontStatic(catchBegin, catchPhi);
997 
998     if (argCount == 0) {
999         auto type = IsDynamic(catchBegin->graph->function->owningModule->target) ? ark::compiler::DataType::ANY
1000                                                                                  : ark::compiler::DataType::REFERENCE;
1001         instImpl->SetIsAcc();
1002         instImpl->SetType(type);
1003         return catchPhi;
1004     }
1005 
1006     std::vector<ark::compiler::DataType::Type> types;
1007 
1008     for (size_t index = 0; index < argCount; ++index) {
1009         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
1010         AbckitInst *inputOrThrowable = va_arg(args, AbckitInst *);
1011         if (index % 2U == 0) {
1012             types.push_back(inputOrThrowable->impl->GetType());
1013             catchPhi->impl->AppendInput(inputOrThrowable->impl);
1014         } else {
1015             catchPhi->impl->CastToCatchPhi()->AppendThrowableInst(inputOrThrowable->impl);
1016         }
1017     }
1018 
1019     ASSERT(!types.empty());
1020 
1021     if (IsDynamic(catchBegin->graph->function->owningModule->target)) {
1022         catchPhi->impl->SetType(ark::compiler::DataType::ANY);
1023     } else {
1024         for (int i = 1, j = types.size(); i < j; ++i) {
1025             if (types[0] != types[i]) {
1026                 LIBABCKIT_LOG(DEBUG) << "All inputs of a catchPhi should be of the same type " << '\n';
1027                 SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1028                 catchBegin->impl->EraseInst(instImpl, true);
1029                 return nullptr;
1030             }
1031         }
1032         catchPhi->impl->SetType(types[0]);
1033     }
1034 
1035     return catchPhi;
1036 }
1037 
1038 // ========================================
1039 // Api for instruction manipulation
1040 // ========================================
1041 
IremoveStatic(AbckitInst * inst)1042 void IremoveStatic(AbckitInst *inst)
1043 {
1044     LIBABCKIT_LOG_FUNC;
1045 
1046     auto bbImpl = inst->impl->GetBasicBlock();
1047     LIBABCKIT_BAD_ARGUMENT_VOID(bbImpl)
1048 
1049     bbImpl->RemoveInst(inst->impl);
1050 }
1051 
IgetIdStatic(AbckitInst * inst)1052 uint32_t IgetIdStatic(AbckitInst *inst)
1053 {
1054     LIBABCKIT_LOG_FUNC;
1055     auto id = inst->impl->GetId();
1056     LIBABCKIT_LOG(DEBUG) << id << '\n';
1057     return id;
1058 }
1059 
IgetLiteralArrayStatic(AbckitInst * inst)1060 AbckitLiteralArray *IgetLiteralArrayStatic(AbckitInst *inst)
1061 {
1062     LIBABCKIT_LOG_FUNC;
1063     size_t idx = 0;
1064     if (IsDynamic(inst->graph->function->owningModule->target)) {
1065         auto instOpcode = GetDynamicOpcode(inst->impl);
1066         if (!HasLiteralArrayIdOperandDynamic(instOpcode)) {
1067             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1068             return nullptr;
1069         }
1070         idx = GetLiteralArrayIdOperandIndexDynamic(instOpcode);
1071     } else {
1072         auto instOpcode = GetStaticOpcode(inst->impl);
1073         if (!HasLiteralArrayIdOperandStatic(instOpcode)) {
1074             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1075             return nullptr;
1076         }
1077         idx = GetLiteralArrayIdOperandIndexStatic(instOpcode);
1078     }
1079     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1080     ASSERT(!imms.empty());
1081     auto arrName = inst->graph->irInterface->literalarrays.at(imms[idx]);
1082     std::variant<ark::pandasm::LiteralArray *, panda::pandasm::LiteralArray *> arrImpl {
1083         (panda::pandasm::LiteralArray *)nullptr};
1084     if (IsDynamic(inst->graph->function->owningModule->target)) {
1085         arrImpl = reinterpret_cast<panda::pandasm::LiteralArray *>(
1086             PandasmWrapper::GetUnwrappedLiteralArrayTable(inst->graph->file->GetDynamicProgram()).at(arrName));
1087     } else {
1088         arrImpl = &inst->graph->file->GetStaticProgram()->literalarrayTable.at(arrName);
1089     }
1090 
1091     // Search through already created litarrs
1092     auto &abckitLitArrs = inst->graph->file->litarrs;
1093     for (auto &item : abckitLitArrs) {
1094         if (item->impl == arrImpl) {
1095             return item.get();
1096         }
1097     }
1098 
1099     // Create new litarr
1100     auto litarr = std::make_unique<AbckitLiteralArray>();
1101     litarr->file = inst->graph->file;
1102     litarr->impl = arrImpl;
1103     return abckitLitArrs.emplace_back(std::move(litarr)).get();
1104 }
1105 
IsetLiteralArrayStatic(AbckitInst * inst,AbckitLiteralArray * la)1106 void IsetLiteralArrayStatic(AbckitInst *inst, AbckitLiteralArray *la)
1107 {
1108     LIBABCKIT_LOG_FUNC;
1109     size_t idx = 0;
1110     if (IsDynamic(inst->graph->function->owningModule->target)) {
1111         auto instOpcode = GetDynamicOpcode(inst->impl);
1112         if (!HasLiteralArrayIdOperandDynamic(instOpcode)) {
1113             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1114             return;
1115         }
1116         idx = GetLiteralArrayIdOperandIndexDynamic(instOpcode);
1117     } else {
1118         auto instOpcode = GetStaticOpcode(inst->impl);
1119         if (!HasLiteralArrayIdOperandStatic(instOpcode)) {
1120             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1121             return;
1122         }
1123         idx = GetLiteralArrayIdOperandIndexStatic(instOpcode);
1124     }
1125 
1126     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1127     ASSERT(imms.size() == 2U);
1128     imms[idx] = GetLiteralArrayOffset(inst->graph, la);
1129 }
1130 
IgetStringStatic(AbckitInst * inst)1131 AbckitString *IgetStringStatic(AbckitInst *inst)
1132 {
1133     LIBABCKIT_LOG_FUNC;
1134     size_t idx = 0;
1135     if (IsDynamic(inst->graph->function->owningModule->target)) {
1136         auto instOpcode = GetDynamicOpcode(inst->impl);
1137         if (!HasStringIdOperandDynamic(instOpcode)) {
1138             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1139             return nullptr;
1140         }
1141         idx = GetStringIdOperandIndexDynamic(instOpcode);
1142     } else {
1143         auto instOpcode = GetStaticOpcode(inst->impl);
1144         if (!HasStringIdOperandStatic(instOpcode)) {
1145             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1146             return nullptr;
1147         }
1148         idx = GetStringIdOperandIndexStatic(instOpcode);
1149     }
1150 
1151     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1152     auto strName = inst->graph->irInterface->strings.at(imms[idx]);
1153     auto strImpl = inst->graph->file->strings.at(strName).get();
1154     return strImpl;
1155 }
1156 
IsetStringStatic(AbckitInst * inst,AbckitString * str)1157 void IsetStringStatic(AbckitInst *inst, AbckitString *str)
1158 {
1159     LIBABCKIT_LOG_FUNC;
1160     size_t idx = 0;
1161     if (IsDynamic(inst->graph->function->owningModule->target)) {
1162         auto instOpcode = GetDynamicOpcode(inst->impl);
1163         if (!HasStringIdOperandDynamic(instOpcode)) {
1164             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1165             return;
1166         }
1167         idx = GetStringIdOperandIndexDynamic(instOpcode);
1168     } else {
1169         auto instOpcode = GetStaticOpcode(inst->impl);
1170         if (!HasStringIdOperandStatic(instOpcode)) {
1171             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1172             return;
1173         }
1174         idx = GetStringIdOperandIndexStatic(instOpcode);
1175     }
1176 
1177     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1178     imms[idx] = GetStringOffset(inst->graph, str);
1179 }
1180 
IgetOpcodeStaticStatic(AbckitInst * inst)1181 AbckitIsaApiStaticOpcode IgetOpcodeStaticStatic(AbckitInst *inst)
1182 {
1183     LIBABCKIT_LOG_FUNC;
1184     auto opc = inst->impl->GetOpcode();
1185     if (opc == ark::compiler::Opcode::Intrinsic) {
1186         return GetStaticIntrinsicOpcode(inst->impl->CastToIntrinsic());
1187     }
1188     return GetStaticOpcode(inst->impl);
1189 }
1190 
IgetOpcodeDynamicStatic(AbckitInst * inst)1191 AbckitIsaApiDynamicOpcode IgetOpcodeDynamicStatic(AbckitInst *inst)
1192 {
1193     LIBABCKIT_LOG_FUNC;
1194     auto opc = inst->impl->GetOpcode();
1195     if (opc == ark::compiler::Opcode::Intrinsic) {
1196         switch (inst->impl->CastToIntrinsic()->GetIntrinsicId()) {
1197             case ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_STRING:
1198                 return ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING;
1199             default:
1200                 break;
1201         }
1202         return GetDynamicIntrinsicOpcode(inst->impl->CastToIntrinsic());
1203     }
1204     return GetDynamicOpcode(inst->impl);
1205 }
1206 
IgetNextStatic(AbckitInst * inst)1207 AbckitInst *IgetNextStatic(AbckitInst *inst)
1208 {
1209     LIBABCKIT_LOG_FUNC;
1210 
1211     auto *nextInstImpl = inst->impl->GetNext();
1212     if (nextInstImpl == nullptr) {
1213         return nullptr;
1214     }
1215     auto *nextInst = inst->graph->implToInst.at(nextInstImpl);
1216     return nextInst;
1217 }
1218 
IgetPrevStatic(AbckitInst * inst)1219 AbckitInst *IgetPrevStatic(AbckitInst *inst)
1220 {
1221     LIBABCKIT_LOG_FUNC;
1222     auto *nextInstImpl = inst->impl->GetPrev();
1223     if (nextInstImpl == nullptr) {
1224         return nullptr;
1225     }
1226     auto *nextInst = inst->graph->implToInst.at(nextInstImpl);
1227     return nextInst;
1228 }
1229 
IinsertAfterStatic(AbckitInst * inst,AbckitInst * next)1230 void IinsertAfterStatic(AbckitInst *inst, AbckitInst *next)
1231 {
1232     LIBABCKIT_LOG_FUNC;
1233     LIBABCKIT_BAD_ARGUMENT_VOID(inst)
1234     LIBABCKIT_BAD_ARGUMENT_VOID(next)
1235 
1236     LIBABCKIT_WRONG_CTX_VOID(inst->graph, next->graph);
1237 
1238     auto *bb = IgetBasicBlockStatic(next);
1239     LIBABCKIT_BAD_ARGUMENT_VOID(bb)
1240 
1241     if (inst->impl->IsConst() || next->impl->IsConst()) {
1242         LIBABCKIT_LOG(DEBUG) << "can't use constant instruction as an argument";
1243         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1244         return;
1245     }
1246 
1247     bb->impl->InsertAfter(inst->impl, next->impl);
1248 }
1249 
IinsertBeforeStatic(AbckitInst * inst,AbckitInst * prev)1250 void IinsertBeforeStatic(AbckitInst *inst, AbckitInst *prev)
1251 {
1252     LIBABCKIT_LOG_FUNC;
1253     LIBABCKIT_BAD_ARGUMENT_VOID(inst)
1254     LIBABCKIT_BAD_ARGUMENT_VOID(prev)
1255 
1256     LIBABCKIT_WRONG_CTX_VOID(inst->graph, prev->graph);
1257 
1258     auto *bb = IgetBasicBlockStatic(prev);
1259     LIBABCKIT_BAD_ARGUMENT_VOID(bb)
1260 
1261     if (inst->impl->IsConst() || prev->impl->IsConst()) {
1262         LIBABCKIT_LOG(DEBUG) << "can't use constant instruction as an argument";
1263         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1264         return;
1265     }
1266     bb->impl->InsertBefore(inst->impl, prev->impl);
1267 }
1268 
IcheckDominanceStatic(AbckitInst * inst,AbckitInst * dominator)1269 bool IcheckDominanceStatic(AbckitInst *inst, AbckitInst *dominator)
1270 {
1271     LIBABCKIT_LOG_FUNC;
1272 
1273     LIBABCKIT_WRONG_CTX(inst->graph, dominator->graph, false);
1274 
1275     return inst->impl->IsDominate(dominator->impl);
1276 }
1277 
IvisitUsersStatic(AbckitInst * inst,void * data,bool (* cb)(AbckitInst * user,void * data))1278 bool IvisitUsersStatic(AbckitInst *inst, void *data, bool (*cb)(AbckitInst *user, void *data))
1279 {
1280     LIBABCKIT_LOG_FUNC;
1281 
1282     auto *user = inst->impl->GetFirstUser();
1283 
1284     while (user != nullptr) {
1285         auto *userInst = inst->graph->implToInst.at(user->GetInst());
1286         if (!cb(userInst, data)) {
1287             return false;
1288         }
1289         user = user->GetNext();
1290     }
1291     return true;
1292 }
1293 
IgetUserCountStatic(AbckitInst * inst)1294 uint32_t IgetUserCountStatic(AbckitInst *inst)
1295 {
1296     LIBABCKIT_LOG_FUNC;
1297     uint32_t count = 0;
1298 
1299     auto *user = inst->impl->GetFirstUser();
1300 
1301     while (user != nullptr) {
1302         count++;
1303         user = user->GetNext();
1304     }
1305     return count;
1306 }
1307 
IvisitInputsStatic(AbckitInst * inst,void * data,bool (* cb)(AbckitInst * input,size_t inputIdx,void * data))1308 bool IvisitInputsStatic(AbckitInst *inst, void *data, bool (*cb)(AbckitInst *input, size_t inputIdx, void *data))
1309 {
1310     LIBABCKIT_LOG_FUNC;
1311     for (size_t i = 0; i < inst->impl->GetInputsCount(); i++) {
1312         auto *inputImpl = inst->impl->GetInput(i).GetInst();
1313         auto *input = inst->graph->implToInst.at(inputImpl);
1314         if (!cb(input, i, data)) {
1315             return false;
1316         }
1317     }
1318     return true;
1319 }
1320 
IgetInputCountStatic(AbckitInst * inst)1321 uint64_t IgetInputCountStatic(AbckitInst *inst)
1322 {
1323     LIBABCKIT_LOG_FUNC;
1324 
1325     return inst->impl->GetInputsCount();
1326 }
1327 
IgetInputStatic(AbckitInst * inst,size_t index)1328 AbckitInst *IgetInputStatic(AbckitInst *inst, size_t index)
1329 {
1330     LIBABCKIT_LOG_FUNC;
1331     if (inst->impl->GetInputsCount() <= index) {
1332         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1333         return nullptr;
1334     }
1335 
1336     auto *inputImpl = inst->impl->GetInput(index).GetInst();
1337     auto *input = inst->graph->implToInst.at(inputImpl);
1338     return input;
1339 }
1340 
IsetInputStatic(AbckitInst * inst,AbckitInst * input,int32_t index)1341 void IsetInputStatic(AbckitInst *inst, AbckitInst *input, int32_t index)
1342 {
1343     LIBABCKIT_LOG_FUNC;
1344     LIBABCKIT_LOG(DEBUG) << index << '\n';
1345     LIBABCKIT_LOG(DEBUG) << inst->impl->GetInputs().size() << '\n';
1346     inst->impl->SetInput(index, input->impl);
1347 }
1348 
IsetInputsStatic(AbckitInst * inst,size_t argCount,std::va_list args)1349 void IsetInputsStatic(AbckitInst *inst, size_t argCount, std::va_list args)
1350 {
1351     LIBABCKIT_LOG_FUNC;
1352     LIBABCKIT_LOG(DEBUG) << argCount << '\n';
1353     LIBABCKIT_LOG(DEBUG) << inst->impl->GetInputs().size() << '\n';
1354     for (size_t index = 0; index < argCount; ++index) {
1355         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
1356         AbckitInst *input = va_arg(args, AbckitInst *);
1357         inst->impl->SetInput(index, input->impl);
1358     }
1359 }
1360 
IappendInputStatic(AbckitInst * inst,AbckitInst * input)1361 void IappendInputStatic(AbckitInst *inst, AbckitInst *input)
1362 {
1363     LIBABCKIT_LOG_FUNC;
1364     auto instImpl = inst->impl;
1365     static size_t rangeInputsCount = -1;
1366 
1367     if (instImpl->IsOperandsDynamic()) {
1368         switch (instImpl->GetOpcode()) {
1369             case ark::compiler::Opcode::CallStatic: {
1370                 instImpl->CastToCallStatic()->AppendInput(input->impl, input->impl->GetType());
1371                 return;
1372             }
1373             case ark::compiler::Opcode::CallVirtual: {
1374                 instImpl->CastToCallVirtual()->AppendInput(input->impl, input->impl->GetType());
1375                 return;
1376             }
1377             case ark::compiler::Opcode::Intrinsic: {
1378                 if (GetIntrinicMaxInputsCount(inst) == rangeInputsCount) {
1379                     instImpl->CastToIntrinsic()->AppendInput(input->impl, input->impl->GetType());
1380                     return;
1381                 }
1382                 if (instImpl->GetInputsCount() >= GetIntrinicMaxInputsCount(inst)) {
1383                     LIBABCKIT_LOG(DEBUG) << "The maximum number of inputs has been reached for the instruction\n";
1384                     SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1385                     return;
1386                 }
1387                 instImpl->CastToIntrinsic()->AppendInput(input->impl, input->impl->GetType());
1388                 return;
1389             }
1390             case ark::compiler::Opcode::Phi: {
1391                 instImpl->AppendInput(input->impl);
1392                 return;
1393             }
1394             default:
1395                 break;
1396         }
1397     }
1398 
1399     LIBABCKIT_LOG(DEBUG) << "The instruction does not have the ability to add inputs\n";
1400     SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1401 }
1402 
1403 // Type helpers
1404 
CreateGeneralType(AbckitFile * file,AbckitTypeId typeId,AbckitCoreClass * klass)1405 static AbckitType *CreateGeneralType(AbckitFile *file, AbckitTypeId typeId, AbckitCoreClass *klass)
1406 {
1407     return GetOrCreateType(file, typeId, 0, klass);
1408 }
1409 
IgetTypeStatic(AbckitInst * inst)1410 AbckitType *IgetTypeStatic(AbckitInst *inst)
1411 {
1412     LIBABCKIT_LOG_FUNC;
1413     AbckitTypeId typeId = TypeToTypeId(inst->impl->GetType());
1414     AbckitCoreClass *klass = nullptr;
1415     if (typeId != ABCKIT_TYPE_ID_REFERENCE) {
1416         return CreateGeneralType(inst->graph->file, typeId, klass);
1417     }
1418     // Add get of ABCKIT_TYPE_ID_REFERENCE NOTE(ymolokanov)
1419     return CreateGeneralType(inst->graph->file, typeId, klass);
1420 }
1421 
IgetTargetTypeStatic(AbckitInst * inst)1422 AbckitTypeId IgetTargetTypeStatic(AbckitInst *inst)
1423 {
1424     LIBABCKIT_LOG_FUNC;
1425     if (inst->impl->GetOpcode() != ark::compiler::Opcode::Cast) {
1426         LIBABCKIT_LOG(DEBUG) << "Instruction is not a cast\n";
1427         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1428         return AbckitTypeId::ABCKIT_TYPE_ID_INVALID;
1429     }
1430 
1431     return TypeToTypeId(static_cast<ark::compiler::CastInst *>(inst->impl)->GetType());
1432 }
1433 
IsetTargetTypeStatic(AbckitInst * inst,AbckitTypeId type)1434 void IsetTargetTypeStatic(AbckitInst *inst, AbckitTypeId type)
1435 {
1436     LIBABCKIT_LOG_FUNC;
1437     if (inst->impl->GetOpcode() != ark::compiler::Opcode::Cast) {
1438         LIBABCKIT_LOG(DEBUG) << "Instruction is not a cast\n";
1439         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1440         return;
1441     }
1442 
1443     inst->impl->SetType(TypeIdToType(type));
1444 }
1445 
IcheckIsCallStatic(AbckitInst * inst)1446 bool IcheckIsCallStatic(AbckitInst *inst)
1447 {
1448     LIBABCKIT_LOG_FUNC;
1449     return IsCallInst(inst);
1450 }
1451 
IgetBasicBlockStatic(AbckitInst * inst)1452 AbckitBasicBlock *IgetBasicBlockStatic(AbckitInst *inst)
1453 {
1454     LIBABCKIT_LOG_FUNC;
1455     auto *graph = inst->graph;
1456     auto *implBB = inst->impl->GetBasicBlock();
1457     auto it = graph->implToBB.find(implBB);
1458     if (it != graph->implToBB.end()) {
1459         return it->second;
1460     }
1461     return nullptr;
1462 }
1463 
IgetGraphStatic(AbckitInst * inst)1464 AbckitGraph *IgetGraphStatic(AbckitInst *inst)
1465 {
1466     LIBABCKIT_LOG_FUNC;
1467     return inst->graph;
1468 }
1469 
IgetFunctionStatic(AbckitInst * inst)1470 AbckitCoreFunction *IgetFunctionStatic(AbckitInst *inst)
1471 {
1472     LIBABCKIT_LOG_FUNC;
1473     auto *graph = inst->graph;
1474 
1475     ark::compiler::RuntimeInterface::MethodPtr methodPtr = nullptr;
1476     if (inst->impl->IsCall()) {
1477         auto *callInst = static_cast<ark::compiler::CallInst *>(inst->impl);
1478         methodPtr = callInst->GetCallMethod();
1479     } else if (inst->impl->IsIntrinsic()) {
1480         size_t idx = 0;
1481         if (IsDynamic(inst->graph->function->owningModule->target)) {
1482             auto instOpcode = GetDynamicOpcode(inst->impl);
1483             if (!HasMethodIdOperandDynamic(instOpcode)) {
1484                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1485                 return nullptr;
1486             }
1487             idx = GetMethodIdOperandIndexDynamic(instOpcode);
1488         } else {
1489             auto instOpcode = GetStaticOpcode(inst->impl);
1490             if (!HasMethodIdOperandStatic(instOpcode)) {
1491                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1492                 return nullptr;
1493             }
1494             idx = GetMethodIdOperandIndexStatic(instOpcode);
1495         }
1496 
1497         auto *intrinsic = inst->impl->CastToIntrinsic();
1498         methodPtr = reinterpret_cast<ark::compiler::RuntimeInterface::MethodPtr>(intrinsic->GetImm(idx));
1499     } else {
1500         LIBABCKIT_LOG(DEBUG) << "Instruction is not a call or intrinsic\n";
1501         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1502         return nullptr;
1503     }
1504 
1505     auto it = graph->irInterface->methods.find(reinterpret_cast<uintptr_t>(methodPtr));
1506     if (it == graph->irInterface->methods.end()) {
1507         LIBABCKIT_LOG(DEBUG) << "No requested call exists in current graph context\n";
1508         SetLastError(ABCKIT_STATUS_UNSUPPORTED);
1509         return nullptr;
1510     }
1511 
1512     if (graph->file->nameToFunction.count(it->second) == 0) {
1513         statuses::SetLastError(ABCKIT_STATUS_UNSUPPORTED);
1514         return nullptr;
1515     }
1516     return graph->file->nameToFunction[it->second];
1517 }
1518 
IsetFunctionStatic(AbckitInst * inst,AbckitCoreFunction * function)1519 void IsetFunctionStatic(AbckitInst *inst, AbckitCoreFunction *function)
1520 {
1521     LIBABCKIT_LOG_FUNC;
1522     auto *graph = inst->graph;
1523 
1524     auto methodOffset = GetMethodOffset(graph, function);
1525 
1526     if (inst->impl->IsCall()) {
1527         auto *callInst = static_cast<ark::compiler::CallInst *>(inst->impl);
1528         callInst->SetCallMethodId(methodOffset);
1529     } else if (inst->impl->IsIntrinsic()) {
1530         size_t idx = 0;
1531         if (IsDynamic(inst->graph->function->owningModule->target)) {
1532             auto instOpcode = GetDynamicOpcode(inst->impl);
1533             if (!HasMethodIdOperandDynamic(instOpcode)) {
1534                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1535                 return;
1536             }
1537             idx = GetMethodIdOperandIndexDynamic(instOpcode);
1538         } else {
1539             auto instOpcode = GetStaticOpcode(inst->impl);
1540             if (!HasMethodIdOperandStatic(instOpcode)) {
1541                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1542                 return;
1543             }
1544             idx = GetMethodIdOperandIndexStatic(instOpcode);
1545         }
1546 
1547         auto *intrinsic = inst->impl->CastToIntrinsic();
1548         intrinsic->SetImm(idx, methodOffset);
1549     } else {
1550         LIBABCKIT_LOG(DEBUG) << "Instruction is not a call or intrinsic\n";
1551         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1552         return;
1553     }
1554 }
1555 
IsetClassStatic(AbckitInst * inst,AbckitCoreClass * klass)1556 void IsetClassStatic(AbckitInst *inst, AbckitCoreClass *klass)
1557 {
1558     LIBABCKIT_LOG_FUNC;
1559     auto *graph = inst->graph;
1560     auto *intrinsic = inst->impl->CastToIntrinsic();
1561     auto instOpcode = GetStaticOpcode(inst->impl);
1562     if (!HasTypeIdOperandStatic(instOpcode)) {
1563         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1564         return;
1565     }
1566     size_t idx = GetTypeIdOperandIndexStatic(instOpcode);
1567     auto klassOffset = GetClassOffset(graph, klass);
1568     intrinsic->SetImm(idx, klassOffset);
1569 }
1570 
IgetClassStatic(AbckitInst * inst)1571 AbckitCoreClass *IgetClassStatic(AbckitInst *inst)
1572 {
1573     LIBABCKIT_LOG_FUNC;
1574     auto *graph = inst->graph;
1575     auto *intrinsic = inst->impl->CastToIntrinsic();
1576     auto instOpcode = IgetOpcodeStaticStatic(inst);
1577     if (!HasTypeIdOperandStatic(instOpcode)) {
1578         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1579         return nullptr;
1580     }
1581     size_t idx = GetTypeIdOperandIndexStatic(instOpcode);
1582     auto classPtr = reinterpret_cast<ark::compiler::RuntimeInterface::ClassPtr>(intrinsic->GetImm(idx));
1583 
1584     auto it = graph->ptrToClass.find(reinterpret_cast<uintptr_t>(classPtr));
1585     if (it == graph->ptrToClass.end()) {
1586         LIBABCKIT_LOG(DEBUG) << "No requested class exists in current graph context\n";
1587         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1588         return nullptr;
1589     }
1590     return it->second;
1591 }
1592 
GcreateNullPtrStatic(AbckitGraph * graph)1593 AbckitInst *GcreateNullPtrStatic(AbckitGraph *graph)
1594 {
1595     auto instImpl = graph->impl->CreateInstNullPtr(ark::compiler::DataType::REFERENCE);
1596     auto *inst = CreateInstFromImpl(graph, instImpl);
1597     graph->impl->GetStartBlock()->AppendInst(instImpl);
1598     return inst;
1599 }
1600 
IgetConstantValueI32Static(AbckitInst * inst)1601 int32_t IgetConstantValueI32Static(AbckitInst *inst)
1602 {
1603     if (!inst->impl->IsConst()) {
1604         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1605                              << '\n';
1606     }
1607     if (inst->impl->GetType() != ark::compiler::DataType::INT32 &&
1608         inst->impl->GetType() != ark::compiler::DataType::UINT32) {
1609         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1610     }
1611     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetInt32Value();
1612 }
1613 
IgetConstantValueI64Static(AbckitInst * inst)1614 int64_t IgetConstantValueI64Static(AbckitInst *inst)
1615 {
1616     if (!inst->impl->IsConst()) {
1617         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1618                              << '\n';
1619     }
1620     if (inst->impl->GetType() != ark::compiler::DataType::INT64 &&
1621         inst->impl->GetType() != ark::compiler::DataType::UINT64) {
1622         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1623     }
1624     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetInt64Value();
1625 }
1626 
IgetConstantValueU64Static(AbckitInst * inst)1627 uint64_t IgetConstantValueU64Static(AbckitInst *inst)
1628 {
1629     if (!inst->impl->IsConst()) {
1630         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1631                              << '\n';
1632         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1633     }
1634     if (inst->impl->GetType() != ark::compiler::DataType::INT64 &&
1635         inst->impl->GetType() != ark::compiler::DataType::UINT64) {
1636         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1637         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1638     }
1639     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetInt64Value();
1640 }
1641 
IgetConstantValueF64Static(AbckitInst * inst)1642 double IgetConstantValueF64Static(AbckitInst *inst)
1643 {
1644     if (!inst->impl->IsConst()) {
1645         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1646                              << '\n';
1647         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1648     }
1649     if (inst->impl->GetType() != ark::compiler::DataType::FLOAT64) {
1650         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1651         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1652     }
1653     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetDoubleValue();
1654 }
1655 
IgetImmediateStatic(AbckitInst * inst,size_t idx)1656 uint64_t IgetImmediateStatic(AbckitInst *inst, size_t idx)
1657 {
1658     LIBABCKIT_LOG_FUNC;
1659 
1660     if (IgetImmediateCountStatic(inst) <= idx) {
1661         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1662         return 0;
1663     }
1664 
1665     uint64_t ret = 0;
1666 
1667     if (inst->impl->IsBinaryImmInst()) {
1668         ret = (static_cast<ark::compiler::BinaryImmOperation *>(inst->impl))->GetImm();
1669     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1670         ret = inst->impl->CastToIntrinsic()->GetImm(idx);
1671     } else {
1672         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1673         return 0;
1674     }
1675     return ret;
1676 }
1677 
IsetImmediateStatic(AbckitInst * inst,size_t idx,uint64_t imm)1678 void IsetImmediateStatic(AbckitInst *inst, size_t idx, uint64_t imm)
1679 {
1680     LIBABCKIT_LOG_FUNC;
1681 
1682     if (IgetImmediateCountStatic(inst) <= idx) {
1683         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1684         return;
1685     }
1686 
1687     if (inst->impl->IsBinaryImmInst()) {
1688         if (GetBitLengthUnsigned(imm) <= GetBinaryImmOperationSize(inst->impl->GetOpcode())) {
1689             (static_cast<ark::compiler::BinaryImmOperation *>(inst->impl))->SetImm(imm);
1690         } else {
1691             LIBABCKIT_LOG(DEBUG) << "Immediate type overflow\n";
1692             SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1693         }
1694     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1695         auto instr = inst->impl->CastToIntrinsic();
1696         if (GetBitLengthUnsigned(imm) <= GetIntrinsicBitImmSize(instr->GetIntrinsicId(), idx)) {
1697             instr->SetImm(idx, imm);
1698         } else {
1699             LIBABCKIT_LOG(DEBUG) << "Immediate type overflow\n";
1700             SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1701         }
1702     } else {
1703         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1704     }
1705 }
1706 
IgetImmediateSizeStatic(AbckitInst * inst,size_t idx)1707 AbckitBitImmSize IgetImmediateSizeStatic(AbckitInst *inst, size_t idx)
1708 {
1709     LIBABCKIT_LOG_FUNC;
1710 
1711     if (IgetImmediateCountStatic(inst) <= idx) {
1712         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1713         return AbckitBitImmSize::BITSIZE_0;
1714     }
1715 
1716     auto immBitSize = AbckitBitImmSize::BITSIZE_0;
1717     if (inst->impl->IsBinaryImmInst()) {
1718         immBitSize = GetBinaryImmOperationSize(inst->impl->GetOpcode());
1719     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1720         auto instr = inst->impl->CastToIntrinsic();
1721         immBitSize = GetIntrinsicBitImmSize(instr->GetIntrinsicId(), idx);
1722     } else {
1723         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1724     }
1725     return immBitSize;
1726 }
1727 
IgetImmediateCountStatic(AbckitInst * inst)1728 uint64_t IgetImmediateCountStatic(AbckitInst *inst)
1729 {
1730     LIBABCKIT_LOG_FUNC;
1731 
1732     uint64_t ret = 0;
1733 
1734     if (inst->impl->IsBinaryImmInst()) {
1735         ret = 1;
1736     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1737         auto instr = inst->impl->CastToIntrinsic();
1738         return instr->HasImms() ? instr->GetImms().size() : 0;
1739     }
1740     return ret;
1741 }
1742 
IgetModuleStatic(AbckitInst * inst)1743 AbckitCoreModule *IgetModuleStatic(AbckitInst *inst)
1744 {
1745     LIBABCKIT_LOG_FUNC;
1746 
1747     if (!inst->impl->IsIntrinsic()) {
1748         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1749         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1750         return nullptr;
1751     }
1752 
1753     auto intrInst = inst->impl->CastToIntrinsic();
1754     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1755     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_GETMODULENAMESPACE &&
1756         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_GETMODULENAMESPACE) {
1757         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1758         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1759         return nullptr;
1760     }
1761 
1762     return inst->graph->function->owningModule->md[intrInst->GetImm(0)];
1763 }
1764 
GetModuleIndex(AbckitGraph * graph,AbckitCoreModule * md)1765 uint64_t GetModuleIndex(AbckitGraph *graph, AbckitCoreModule *md)
1766 {
1767     uint64_t imm = 0;
1768     for (auto m : graph->function->owningModule->md) {
1769         if (m == md) {
1770             break;
1771         }
1772         imm++;
1773     }
1774     if (imm == graph->function->owningModule->md.size()) {
1775         LIBABCKIT_LOG(DEBUG) << "Can not find module descriptor for module with name '" << md->moduleName->impl
1776                              << "'\n";
1777         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1778         return 0;
1779     }
1780     return imm;
1781 }
1782 
IsetModuleStatic(AbckitInst * inst,AbckitCoreModule * md)1783 void IsetModuleStatic(AbckitInst *inst, AbckitCoreModule *md)
1784 {
1785     LIBABCKIT_LOG_FUNC;
1786 
1787     if (!inst->impl->IsIntrinsic()) {
1788         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1789         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1790         return;
1791     }
1792 
1793     auto intrInst = inst->impl->CastToIntrinsic();
1794     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1795     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_GETMODULENAMESPACE &&
1796         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_GETMODULENAMESPACE) {
1797         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1798         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1799         return;
1800     }
1801 
1802     uint64_t imm = GetModuleIndex(inst->graph, md);
1803     if (statuses::GetLastError() != ABCKIT_STATUS_NO_ERROR) {
1804         return;
1805     }
1806     intrInst->SetImm(0, imm);
1807 }
1808 
GetImportDescriptorDynamic(AbckitInst * inst,uint64_t idx)1809 AbckitCoreImportDescriptor *GetImportDescriptorDynamic(AbckitInst *inst, uint64_t idx)
1810 {
1811     auto *module = inst->graph->function->owningModule;
1812     for (auto &id : module->id) {
1813         auto idPayload = GetDynImportDescriptorPayload(id.get());
1814         if (!idPayload->isRegularImport) {
1815             continue;
1816         }
1817         if (idPayload->moduleRecordIndexOff == idx) {
1818             return id.get();
1819         }
1820     }
1821     UNREACHABLE();
1822 }
1823 
IgetImportDescriptorStatic(AbckitInst * inst)1824 AbckitCoreImportDescriptor *IgetImportDescriptorStatic(AbckitInst *inst)
1825 {
1826     LIBABCKIT_LOG_FUNC;
1827     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1828 
1829     if (!inst->impl->IsIntrinsic()) {
1830         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1831         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1832         return nullptr;
1833     }
1834 
1835     auto intrInst = inst->impl->CastToIntrinsic();
1836     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1837     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDEXTERNALMODULEVAR &&
1838         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDEXTERNALMODULEVAR) {
1839         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1840         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1841         return nullptr;
1842     }
1843 
1844     return GetImportDescriptorDynamic(inst, intrInst->GetImm(0));
1845 }
1846 
GetImportDescriptorIdxDynamic(AbckitGraph * graph,AbckitCoreImportDescriptor * id)1847 uint32_t GetImportDescriptorIdxDynamic(AbckitGraph *graph, AbckitCoreImportDescriptor *id)
1848 {
1849     AbckitCoreModule *m = graph->function->owningModule;
1850     auto found = std::find_if(m->id.begin(), m->id.end(),
1851                               [&](std::unique_ptr<AbckitCoreImportDescriptor> const &d) { return d.get() == id; });
1852     if (found == m->id.end()) {
1853         LIBABCKIT_LOG(DEBUG) << "Can not find the import in module imports\n";
1854         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1855         return 0;
1856     }
1857     return GetDynImportDescriptorPayload(found->get())->moduleRecordIndexOff;
1858 }
1859 
IsetImportDescriptorStatic(AbckitInst * inst,AbckitCoreImportDescriptor * id)1860 void IsetImportDescriptorStatic(AbckitInst *inst, AbckitCoreImportDescriptor *id)
1861 {
1862     LIBABCKIT_LOG_FUNC;
1863     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1864 
1865     if (!inst->impl->IsIntrinsic()) {
1866         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1867         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1868         return;
1869     }
1870 
1871     auto intrInst = inst->impl->CastToIntrinsic();
1872     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1873     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDEXTERNALMODULEVAR &&
1874         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDEXTERNALMODULEVAR) {
1875         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1876         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1877         return;
1878     }
1879 
1880     uint32_t imm = GetImportDescriptorIdxDynamic(inst->graph, id);
1881     if (statuses::GetLastError() != ABCKIT_STATUS_NO_ERROR) {
1882         return;
1883     }
1884     intrInst->SetImm(0, imm);
1885 }
1886 
GetExportDescriptorDynamic(AbckitInst * inst,uint64_t idx)1887 AbckitCoreExportDescriptor *GetExportDescriptorDynamic(AbckitInst *inst, uint64_t idx)
1888 {
1889     auto *module = inst->graph->function->owningModule;
1890     for (auto &ed : module->ed) {
1891         auto edPayload = GetDynExportDescriptorPayload(ed.get());
1892         if (edPayload->kind != AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT) {
1893             continue;
1894         }
1895         if (edPayload->moduleRecordIndexOff == idx) {
1896             return ed.get();
1897         }
1898     }
1899     UNREACHABLE();
1900 }
1901 
IgetExportDescriptorStatic(AbckitInst * inst)1902 AbckitCoreExportDescriptor *IgetExportDescriptorStatic(AbckitInst *inst)
1903 {
1904     LIBABCKIT_LOG_FUNC;
1905     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1906 
1907     if (!inst->impl->IsIntrinsic()) {
1908         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1909         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1910         return nullptr;
1911     }
1912 
1913     auto intrInst = inst->impl->CastToIntrinsic();
1914     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1915     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLOCALMODULEVAR &&
1916         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDLOCALMODULEVAR &&
1917         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_STMODULEVAR &&
1918         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_STMODULEVAR) {
1919         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1920         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1921         return nullptr;
1922     }
1923 
1924     return GetExportDescriptorDynamic(inst, intrInst->GetImm(0));
1925 }
1926 
GetExportDescriptorIdxDynamic(AbckitGraph * graph,AbckitCoreExportDescriptor * ed)1927 uint32_t GetExportDescriptorIdxDynamic(AbckitGraph *graph, AbckitCoreExportDescriptor *ed)
1928 {
1929     AbckitCoreModule *m = graph->function->owningModule;
1930     auto found = std::find_if(m->ed.begin(), m->ed.end(),
1931                               [&](std::unique_ptr<AbckitCoreExportDescriptor> const &d) { return d.get() == ed; });
1932     if (found == m->ed.end()) {
1933         LIBABCKIT_LOG(DEBUG) << "Can not find the import in module imports\n";
1934         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1935         return 0;
1936     }
1937     return GetDynExportDescriptorPayload(found->get())->moduleRecordIndexOff;
1938 }
1939 
IsetExportDescriptorStatic(AbckitInst * inst,AbckitCoreExportDescriptor * ed)1940 void IsetExportDescriptorStatic(AbckitInst *inst, AbckitCoreExportDescriptor *ed)
1941 {
1942     LIBABCKIT_LOG_FUNC;
1943     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1944 
1945     if (!inst->impl->IsIntrinsic()) {
1946         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1947         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1948         return;
1949     }
1950 
1951     auto intrInst = inst->impl->CastToIntrinsic();
1952     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1953     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLOCALMODULEVAR &&
1954         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDLOCALMODULEVAR &&
1955         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_STMODULEVAR &&
1956         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_STMODULEVAR) {
1957         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1958         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1959         return;
1960     }
1961 
1962     uint32_t imm = GetExportDescriptorIdxDynamic(inst->graph, ed);
1963     if (statuses::GetLastError() != ABCKIT_STATUS_NO_ERROR) {
1964         return;
1965     }
1966     intrInst->SetImm(0, imm);
1967 }
1968 
IgetConditionCodeStaticStatic(AbckitInst * inst)1969 AbckitIsaApiStaticConditionCode IgetConditionCodeStaticStatic(AbckitInst *inst)
1970 {
1971     return CcToStaticCc(inst->impl->CastToIf()->GetCc());
1972 }
1973 
IgetConditionCodeDynamicStatic(AbckitInst * inst)1974 AbckitIsaApiDynamicConditionCode IgetConditionCodeDynamicStatic(AbckitInst *inst)
1975 {
1976     return CcToDynamicCc(inst->impl->CastToIf()->GetCc());
1977 }
1978 
IsetConditionCodeStaticStatic(AbckitInst * inst,AbckitIsaApiStaticConditionCode cc)1979 void IsetConditionCodeStaticStatic(AbckitInst *inst, AbckitIsaApiStaticConditionCode cc)
1980 {
1981     inst->impl->CastToIf()->SetCc(CcToCc(cc));
1982 }
1983 
IsetConditionCodeDynamicStatic(AbckitInst * inst,AbckitIsaApiDynamicConditionCode cc)1984 void IsetConditionCodeDynamicStatic(AbckitInst *inst, AbckitIsaApiDynamicConditionCode cc)
1985 {
1986     inst->impl->CastToIf()->SetCc(CcToCc(cc));
1987 }
1988 
1989 }  // namespace libabckit
1990