• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024-2025 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 fd)806 void BBdumpStatic(AbckitBasicBlock *basicBlock, int fd)
807 {
808     LIBABCKIT_LOG_FUNC;
809     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
810 
811     std::stringstream ss;
812     basicBlock->impl->Dump(&ss);
813     write(fd, ss.str().data(), ss.str().size());
814 }
815 
BBcheckDominanceStatic(AbckitBasicBlock * basicBlock,AbckitBasicBlock * dominator)816 bool BBcheckDominanceStatic(AbckitBasicBlock *basicBlock, AbckitBasicBlock *dominator)
817 {
818     LIBABCKIT_LOG_FUNC;
819     LIBABCKIT_BAD_ARGUMENT(basicBlock, false);
820     LIBABCKIT_BAD_ARGUMENT(dominator, false);
821 
822     LIBABCKIT_WRONG_CTX(basicBlock->graph, dominator->graph, false);
823 
824     if (!GraphDominatorsTreeAnalysisIsValid(basicBlock->graph->impl)) {
825         LIBABCKIT_LOG(DEBUG) << "DominatorsTree analysis is not valid\n";
826         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
827         return false;
828     }
829 
830     return dominator->impl->IsDominate(basicBlock->impl);
831 }
832 
BBgetImmediateDominatorStatic(AbckitBasicBlock * basicBlock)833 AbckitBasicBlock *BBgetImmediateDominatorStatic(AbckitBasicBlock *basicBlock)
834 {
835     LIBABCKIT_LOG_FUNC;
836     LIBABCKIT_BAD_ARGUMENT(basicBlock, nullptr);
837 
838     if (!GraphDominatorsTreeAnalysisIsValid(basicBlock->graph->impl)) {
839         LIBABCKIT_LOG(DEBUG) << "DominatorsTree analysis is not valid\n";
840         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
841         return nullptr;
842     }
843 
844     auto *bb = basicBlock->impl->GetDominator();
845     if (bb == nullptr) {
846         return nullptr;
847     }
848     return basicBlock->graph->implToBB.at(bb);
849 }
850 
BBvisitDominatedBlocksStatic(AbckitBasicBlock * basicBlock,void * data,bool (* cb)(AbckitBasicBlock * dominatedBasicBlock,void * data))851 bool BBvisitDominatedBlocksStatic(AbckitBasicBlock *basicBlock, void *data,
852                                   bool (*cb)(AbckitBasicBlock *dominatedBasicBlock, void *data))
853 {
854     LIBABCKIT_LOG_FUNC;
855     LIBABCKIT_BAD_ARGUMENT(basicBlock, false)
856     LIBABCKIT_BAD_ARGUMENT(cb, false)
857 
858     if (!GraphDominatorsTreeAnalysisIsValid(basicBlock->graph->impl)) {
859         LIBABCKIT_LOG(DEBUG) << "DominatorsTree analysis is not valid\n";
860         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
861         return false;
862     }
863 
864     for (auto *bbImpl : basicBlock->impl->GetDominatedBlocks()) {
865         auto *bb = basicBlock->graph->implToBB.at(bbImpl);
866         if (!cb(bb, data)) {
867             return false;
868         }
869     }
870     return true;
871 }
872 
BBinsertSuccBlockStatic(AbckitBasicBlock * basicBlock,AbckitBasicBlock * succBlock,uint32_t index)873 void BBinsertSuccBlockStatic(AbckitBasicBlock *basicBlock, AbckitBasicBlock *succBlock, uint32_t index)
874 {
875     LIBABCKIT_LOG_FUNC;
876     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
877     LIBABCKIT_BAD_ARGUMENT_VOID(succBlock)
878 
879     LIBABCKIT_WRONG_CTX_VOID(basicBlock->graph, succBlock->graph);
880 
881     auto &bbs = basicBlock->impl->GetSuccsBlocks();
882     if (index > bbs.size()) {
883         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
884         return;
885     }
886 
887     if (index == bbs.size()) {
888         bbs.emplace_back(succBlock->impl);
889     } else {
890         bbs.resize(bbs.size() + 1);
891         for (size_t i = index + 1; i < bbs.size(); i++) {
892             bbs[i] = bbs[i - 1];
893         }
894         bbs[index] = succBlock->impl;
895     }
896 
897     succBlock->impl->GetPredsBlocks().emplace_back(basicBlock->impl);
898     GraphInvalidateAnalyses(basicBlock->graph->impl);
899 }
900 
BBappendSuccBlockStatic(AbckitBasicBlock * basicBlock,AbckitBasicBlock * succBlock)901 void BBappendSuccBlockStatic(AbckitBasicBlock *basicBlock, AbckitBasicBlock *succBlock)
902 {
903     LIBABCKIT_LOG_FUNC;
904     LIBABCKIT_BAD_ARGUMENT_VOID(basicBlock)
905     LIBABCKIT_BAD_ARGUMENT_VOID(succBlock)
906 
907     LIBABCKIT_WRONG_CTX_VOID(basicBlock->graph, succBlock->graph);
908 
909     basicBlock->impl->GetSuccsBlocks().emplace_back(succBlock->impl);
910     succBlock->impl->GetPredsBlocks().emplace_back(basicBlock->impl);
911     GraphInvalidateAnalyses(basicBlock->graph->impl);
912 }
913 
BBgetTrueBranchStatic(AbckitBasicBlock * bb)914 AbckitBasicBlock *BBgetTrueBranchStatic(AbckitBasicBlock *bb)
915 {
916     LIBABCKIT_LOG_FUNC;
917     LIBABCKIT_BAD_ARGUMENT(bb, nullptr);
918 
919     if (bb->impl->GetSuccsBlocks().empty()) {
920         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
921         return nullptr;
922     }
923     auto *tb = bb->impl->GetTrueSuccessor();
924     ASSERT(tb != nullptr);
925 
926     return bb->graph->implToBB.at(tb);
927 }
928 
BBgetFalseBranchStatic(AbckitBasicBlock * bb)929 AbckitBasicBlock *BBgetFalseBranchStatic(AbckitBasicBlock *bb)
930 {
931     LIBABCKIT_LOG_FUNC;
932     LIBABCKIT_BAD_ARGUMENT(bb, nullptr);
933 
934     if (bb->impl->GetSuccsBlocks().size() < 2U) {
935         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
936         return nullptr;
937     }
938     auto *fb = bb->impl->GetFalseSuccessor();
939     ASSERT(fb != nullptr);
940 
941     return bb->graph->implToBB.at(fb);
942 }
943 
BBcreatePhiStatic(AbckitBasicBlock * bb,size_t argCount,std::va_list args)944 AbckitInst *BBcreatePhiStatic(AbckitBasicBlock *bb, size_t argCount, std::va_list args)
945 {
946     LIBABCKIT_LOG_FUNC;
947 
948     LIBABCKIT_LOG(DEBUG) << argCount << '\n';
949     if (argCount < 1) {
950         LIBABCKIT_LOG(DEBUG) << "not enough inputs\n";
951         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
952         return nullptr;
953     }
954 
955     std::vector<AbckitInst *> inputs;
956 
957     for (size_t index = 0; index < argCount; ++index) {
958         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
959         AbckitInst *input = va_arg(args, AbckitInst *);
960         LIBABCKIT_BAD_ARGUMENT(input, nullptr);
961         inputs.emplace_back(input);
962     }
963 
964     ark::compiler::DataType::Type type = inputs[0]->impl->GetType();
965     if (IsDynamic(bb->graph->function->owningModule->target)) {
966         type = ark::compiler::DataType::ANY;
967     }
968 
969     for (auto *inst : inputs) {
970         if (IsDynamic(bb->graph->function->owningModule->target)) {
971             if (inst->impl->GetType() != ark::compiler::DataType::INT64 &&
972                 inst->impl->GetType() != ark::compiler::DataType::ANY) {
973                 LIBABCKIT_LOG(DEBUG) << "inconsistent input types\n";
974                 SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
975                 return nullptr;
976             }
977         } else {
978             if (type != inst->impl->GetType()) {
979                 LIBABCKIT_LOG(DEBUG) << "inconsistent input types\n";
980                 SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
981                 return nullptr;
982             }
983         }
984     }
985 
986     auto phiImpl = bb->graph->impl->CreateInstPhi(type, 0);
987     bb->impl->AppendPhi(phiImpl);
988     auto *phi = CreateInstFromImpl(bb->graph, phiImpl);
989     for (auto *inst : inputs) {
990         phiImpl->AppendInput(inst->impl);
991     }
992     return phi;
993 }
994 
BBcreateCatchPhiStatic(AbckitBasicBlock * catchBegin,size_t argCount,std::va_list args)995 AbckitInst *BBcreateCatchPhiStatic(AbckitBasicBlock *catchBegin, size_t argCount, std::va_list args)
996 {
997     auto *instImpl = catchBegin->graph->impl->CreateInstCatchPhi();
998     auto *catchPhi = CreateInstFromImpl(catchBegin->graph, instImpl);
999 
1000     BBaddInstFrontStatic(catchBegin, catchPhi);
1001 
1002     if (argCount == 0) {
1003         auto type = IsDynamic(catchBegin->graph->function->owningModule->target) ? ark::compiler::DataType::ANY
1004                                                                                  : ark::compiler::DataType::REFERENCE;
1005         instImpl->SetIsAcc();
1006         instImpl->SetType(type);
1007         return catchPhi;
1008     }
1009 
1010     std::vector<ark::compiler::DataType::Type> types;
1011 
1012     for (size_t index = 0; index < argCount; ++index) {
1013         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
1014         AbckitInst *inputOrThrowable = va_arg(args, AbckitInst *);
1015         if (index % 2U == 0) {
1016             types.push_back(inputOrThrowable->impl->GetType());
1017             catchPhi->impl->AppendInput(inputOrThrowable->impl);
1018         } else {
1019             catchPhi->impl->CastToCatchPhi()->AppendThrowableInst(inputOrThrowable->impl);
1020         }
1021     }
1022 
1023     ASSERT(!types.empty());
1024 
1025     if (IsDynamic(catchBegin->graph->function->owningModule->target)) {
1026         catchPhi->impl->SetType(ark::compiler::DataType::ANY);
1027     } else {
1028         for (int i = 1, j = types.size(); i < j; ++i) {
1029             if (types[0] != types[i]) {
1030                 LIBABCKIT_LOG(DEBUG) << "All inputs of a catchPhi should be of the same type " << '\n';
1031                 SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1032                 catchBegin->impl->EraseInst(instImpl, true);
1033                 return nullptr;
1034             }
1035         }
1036         catchPhi->impl->SetType(types[0]);
1037     }
1038 
1039     return catchPhi;
1040 }
1041 
1042 // ========================================
1043 // Api for instruction manipulation
1044 // ========================================
1045 
IremoveStatic(AbckitInst * inst)1046 void IremoveStatic(AbckitInst *inst)
1047 {
1048     LIBABCKIT_LOG_FUNC;
1049 
1050     auto bbImpl = inst->impl->GetBasicBlock();
1051     LIBABCKIT_BAD_ARGUMENT_VOID(bbImpl)
1052 
1053     bbImpl->RemoveInst(inst->impl);
1054 }
1055 
IgetIdStatic(AbckitInst * inst)1056 uint32_t IgetIdStatic(AbckitInst *inst)
1057 {
1058     LIBABCKIT_LOG_FUNC;
1059     auto id = inst->impl->GetId();
1060     LIBABCKIT_LOG(DEBUG) << id << '\n';
1061     return id;
1062 }
1063 
IgetLiteralArrayStatic(AbckitInst * inst)1064 AbckitLiteralArray *IgetLiteralArrayStatic(AbckitInst *inst)
1065 {
1066     LIBABCKIT_LOG_FUNC;
1067     size_t idx = 0;
1068     if (IsDynamic(inst->graph->function->owningModule->target)) {
1069         auto instOpcode = GetDynamicOpcode(inst->impl);
1070         if (!HasLiteralArrayIdOperandDynamic(instOpcode)) {
1071             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1072             return nullptr;
1073         }
1074         idx = GetLiteralArrayIdOperandIndexDynamic(instOpcode);
1075     } else {
1076         auto instOpcode = GetStaticOpcode(inst->impl);
1077         if (!HasLiteralArrayIdOperandStatic(instOpcode)) {
1078             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1079             return nullptr;
1080         }
1081         idx = GetLiteralArrayIdOperandIndexStatic(instOpcode);
1082     }
1083     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1084     ASSERT(!imms.empty());
1085     auto arrName = inst->graph->irInterface->literalarrays.at(imms[idx]);
1086     std::variant<ark::pandasm::LiteralArray *, panda::pandasm::LiteralArray *> arrImpl {
1087         (panda::pandasm::LiteralArray *)nullptr};
1088     if (IsDynamic(inst->graph->function->owningModule->target)) {
1089         arrImpl = reinterpret_cast<panda::pandasm::LiteralArray *>(
1090             PandasmWrapper::GetUnwrappedLiteralArrayTable(inst->graph->file->GetDynamicProgram()).at(arrName));
1091     } else {
1092         arrImpl = &inst->graph->file->GetStaticProgram()->literalarrayTable.at(arrName);
1093     }
1094 
1095     // Search through already created litarrs
1096     auto &abckitLitArrs = inst->graph->file->litarrs;
1097     for (auto &item : abckitLitArrs) {
1098         if (item->impl == arrImpl) {
1099             return item.get();
1100         }
1101     }
1102 
1103     // Create new litarr
1104     auto litarr = std::make_unique<AbckitLiteralArray>();
1105     litarr->file = inst->graph->file;
1106     litarr->impl = arrImpl;
1107     return abckitLitArrs.emplace_back(std::move(litarr)).get();
1108 }
1109 
IsetLiteralArrayStatic(AbckitInst * inst,AbckitLiteralArray * la)1110 void IsetLiteralArrayStatic(AbckitInst *inst, AbckitLiteralArray *la)
1111 {
1112     LIBABCKIT_LOG_FUNC;
1113     size_t idx = 0;
1114     if (IsDynamic(inst->graph->function->owningModule->target)) {
1115         auto instOpcode = GetDynamicOpcode(inst->impl);
1116         if (!HasLiteralArrayIdOperandDynamic(instOpcode)) {
1117             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1118             return;
1119         }
1120         idx = GetLiteralArrayIdOperandIndexDynamic(instOpcode);
1121     } else {
1122         auto instOpcode = GetStaticOpcode(inst->impl);
1123         if (!HasLiteralArrayIdOperandStatic(instOpcode)) {
1124             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1125             return;
1126         }
1127         idx = GetLiteralArrayIdOperandIndexStatic(instOpcode);
1128     }
1129 
1130     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1131     ASSERT(imms.size() == 2U);
1132     imms[idx] = GetLiteralArrayOffset(inst->graph, la);
1133 }
1134 
IgetStringStatic(AbckitInst * inst)1135 AbckitString *IgetStringStatic(AbckitInst *inst)
1136 {
1137     LIBABCKIT_LOG_FUNC;
1138     size_t idx = 0;
1139     if (IsDynamic(inst->graph->function->owningModule->target)) {
1140         auto instOpcode = GetDynamicOpcode(inst->impl);
1141         if (!HasStringIdOperandDynamic(instOpcode)) {
1142             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1143             return nullptr;
1144         }
1145         idx = GetStringIdOperandIndexDynamic(instOpcode);
1146     } else {
1147         auto instOpcode = GetStaticOpcode(inst->impl);
1148         if (!HasStringIdOperandStatic(instOpcode)) {
1149             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1150             return nullptr;
1151         }
1152         idx = GetStringIdOperandIndexStatic(instOpcode);
1153     }
1154 
1155     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1156     auto strName = inst->graph->irInterface->strings.at(imms[idx]);
1157     auto strImpl = inst->graph->file->strings.at(strName).get();
1158     return strImpl;
1159 }
1160 
IsetStringStatic(AbckitInst * inst,AbckitString * str)1161 void IsetStringStatic(AbckitInst *inst, AbckitString *str)
1162 {
1163     LIBABCKIT_LOG_FUNC;
1164     size_t idx = 0;
1165     if (IsDynamic(inst->graph->function->owningModule->target)) {
1166         auto instOpcode = GetDynamicOpcode(inst->impl);
1167         if (!HasStringIdOperandDynamic(instOpcode)) {
1168             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1169             return;
1170         }
1171         idx = GetStringIdOperandIndexDynamic(instOpcode);
1172     } else {
1173         auto instOpcode = GetStaticOpcode(inst->impl);
1174         if (!HasStringIdOperandStatic(instOpcode)) {
1175             statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1176             return;
1177         }
1178         idx = GetStringIdOperandIndexStatic(instOpcode);
1179     }
1180 
1181     auto &imms = inst->impl->CastToIntrinsic()->GetImms();
1182     imms[idx] = GetStringOffset(inst->graph, str);
1183 }
1184 
IgetOpcodeStaticStatic(AbckitInst * inst)1185 AbckitIsaApiStaticOpcode IgetOpcodeStaticStatic(AbckitInst *inst)
1186 {
1187     LIBABCKIT_LOG_FUNC;
1188     auto opc = inst->impl->GetOpcode();
1189     if (opc == ark::compiler::Opcode::Intrinsic) {
1190         return GetStaticIntrinsicOpcode(inst->impl->CastToIntrinsic());
1191     }
1192     return GetStaticOpcode(inst->impl);
1193 }
1194 
IgetOpcodeDynamicStatic(AbckitInst * inst)1195 AbckitIsaApiDynamicOpcode IgetOpcodeDynamicStatic(AbckitInst *inst)
1196 {
1197     LIBABCKIT_LOG_FUNC;
1198     auto opc = inst->impl->GetOpcode();
1199     if (opc == ark::compiler::Opcode::Intrinsic) {
1200         switch (inst->impl->CastToIntrinsic()->GetIntrinsicId()) {
1201             case ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_STRING:
1202                 return ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING;
1203             default:
1204                 break;
1205         }
1206         return GetDynamicIntrinsicOpcode(inst->impl->CastToIntrinsic());
1207     }
1208     return GetDynamicOpcode(inst->impl);
1209 }
1210 
IgetNextStatic(AbckitInst * inst)1211 AbckitInst *IgetNextStatic(AbckitInst *inst)
1212 {
1213     LIBABCKIT_LOG_FUNC;
1214 
1215     auto *nextInstImpl = inst->impl->GetNext();
1216     if (nextInstImpl == nullptr) {
1217         return nullptr;
1218     }
1219     auto *nextInst = inst->graph->implToInst.at(nextInstImpl);
1220     return nextInst;
1221 }
1222 
IgetPrevStatic(AbckitInst * inst)1223 AbckitInst *IgetPrevStatic(AbckitInst *inst)
1224 {
1225     LIBABCKIT_LOG_FUNC;
1226     auto *nextInstImpl = inst->impl->GetPrev();
1227     if (nextInstImpl == nullptr) {
1228         return nullptr;
1229     }
1230     auto *nextInst = inst->graph->implToInst.at(nextInstImpl);
1231     return nextInst;
1232 }
1233 
IinsertAfterStatic(AbckitInst * inst,AbckitInst * next)1234 void IinsertAfterStatic(AbckitInst *inst, AbckitInst *next)
1235 {
1236     LIBABCKIT_LOG_FUNC;
1237     LIBABCKIT_BAD_ARGUMENT_VOID(inst)
1238     LIBABCKIT_BAD_ARGUMENT_VOID(next)
1239 
1240     LIBABCKIT_WRONG_CTX_VOID(inst->graph, next->graph);
1241 
1242     auto *bb = IgetBasicBlockStatic(next);
1243     LIBABCKIT_BAD_ARGUMENT_VOID(bb)
1244 
1245     if (inst->impl->IsConst() || next->impl->IsConst()) {
1246         LIBABCKIT_LOG(DEBUG) << "can't use constant instruction as an argument";
1247         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1248         return;
1249     }
1250 
1251     bb->impl->InsertAfter(inst->impl, next->impl);
1252 }
1253 
IinsertBeforeStatic(AbckitInst * inst,AbckitInst * prev)1254 void IinsertBeforeStatic(AbckitInst *inst, AbckitInst *prev)
1255 {
1256     LIBABCKIT_LOG_FUNC;
1257     LIBABCKIT_BAD_ARGUMENT_VOID(inst)
1258     LIBABCKIT_BAD_ARGUMENT_VOID(prev)
1259 
1260     LIBABCKIT_WRONG_CTX_VOID(inst->graph, prev->graph);
1261 
1262     auto *bb = IgetBasicBlockStatic(prev);
1263     LIBABCKIT_BAD_ARGUMENT_VOID(bb)
1264 
1265     if (inst->impl->IsConst() || prev->impl->IsConst()) {
1266         LIBABCKIT_LOG(DEBUG) << "can't use constant instruction as an argument";
1267         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1268         return;
1269     }
1270     bb->impl->InsertBefore(inst->impl, prev->impl);
1271 }
1272 
IcheckDominanceStatic(AbckitInst * inst,AbckitInst * dominator)1273 bool IcheckDominanceStatic(AbckitInst *inst, AbckitInst *dominator)
1274 {
1275     LIBABCKIT_LOG_FUNC;
1276 
1277     LIBABCKIT_WRONG_CTX(inst->graph, dominator->graph, false);
1278 
1279     return inst->impl->IsDominate(dominator->impl);
1280 }
1281 
IvisitUsersStatic(AbckitInst * inst,void * data,bool (* cb)(AbckitInst * user,void * data))1282 bool IvisitUsersStatic(AbckitInst *inst, void *data, bool (*cb)(AbckitInst *user, void *data))
1283 {
1284     LIBABCKIT_LOG_FUNC;
1285 
1286     auto *user = inst->impl->GetFirstUser();
1287 
1288     while (user != nullptr) {
1289         auto *userInst = inst->graph->implToInst.at(user->GetInst());
1290         if (!cb(userInst, data)) {
1291             return false;
1292         }
1293         user = user->GetNext();
1294     }
1295     return true;
1296 }
1297 
IgetUserCountStatic(AbckitInst * inst)1298 uint32_t IgetUserCountStatic(AbckitInst *inst)
1299 {
1300     LIBABCKIT_LOG_FUNC;
1301     uint32_t count = 0;
1302 
1303     auto *user = inst->impl->GetFirstUser();
1304 
1305     while (user != nullptr) {
1306         count++;
1307         user = user->GetNext();
1308     }
1309     return count;
1310 }
1311 
IvisitInputsStatic(AbckitInst * inst,void * data,bool (* cb)(AbckitInst * input,size_t inputIdx,void * data))1312 bool IvisitInputsStatic(AbckitInst *inst, void *data, bool (*cb)(AbckitInst *input, size_t inputIdx, void *data))
1313 {
1314     LIBABCKIT_LOG_FUNC;
1315     for (size_t i = 0; i < inst->impl->GetInputsCount(); i++) {
1316         auto *inputImpl = inst->impl->GetInput(i).GetInst();
1317         auto *input = inst->graph->implToInst.at(inputImpl);
1318         if (!cb(input, i, data)) {
1319             return false;
1320         }
1321     }
1322     return true;
1323 }
1324 
IgetInputCountStatic(AbckitInst * inst)1325 uint64_t IgetInputCountStatic(AbckitInst *inst)
1326 {
1327     LIBABCKIT_LOG_FUNC;
1328 
1329     return inst->impl->GetInputsCount();
1330 }
1331 
IgetInputStatic(AbckitInst * inst,size_t index)1332 AbckitInst *IgetInputStatic(AbckitInst *inst, size_t index)
1333 {
1334     LIBABCKIT_LOG_FUNC;
1335     if (inst->impl->GetInputsCount() <= index) {
1336         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1337         return nullptr;
1338     }
1339 
1340     auto *inputImpl = inst->impl->GetInput(index).GetInst();
1341     auto *input = inst->graph->implToInst.at(inputImpl);
1342     return input;
1343 }
1344 
IsetInputStatic(AbckitInst * inst,AbckitInst * input,int32_t index)1345 void IsetInputStatic(AbckitInst *inst, AbckitInst *input, int32_t index)
1346 {
1347     LIBABCKIT_LOG_FUNC;
1348     LIBABCKIT_LOG(DEBUG) << index << '\n';
1349     LIBABCKIT_LOG(DEBUG) << inst->impl->GetInputs().size() << '\n';
1350     inst->impl->SetInput(index, input->impl);
1351 }
1352 
IsetInputsStatic(AbckitInst * inst,size_t argCount,std::va_list args)1353 void IsetInputsStatic(AbckitInst *inst, size_t argCount, std::va_list args)
1354 {
1355     LIBABCKIT_LOG_FUNC;
1356     LIBABCKIT_LOG(DEBUG) << argCount << '\n';
1357     LIBABCKIT_LOG(DEBUG) << inst->impl->GetInputs().size() << '\n';
1358     for (size_t index = 0; index < argCount; ++index) {
1359         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
1360         AbckitInst *input = va_arg(args, AbckitInst *);
1361         inst->impl->SetInput(index, input->impl);
1362     }
1363 }
1364 
IappendInputStatic(AbckitInst * inst,AbckitInst * input)1365 void IappendInputStatic(AbckitInst *inst, AbckitInst *input)
1366 {
1367     LIBABCKIT_LOG_FUNC;
1368     auto instImpl = inst->impl;
1369     static size_t rangeInputsCount = -1;
1370 
1371     if (instImpl->IsOperandsDynamic()) {
1372         switch (instImpl->GetOpcode()) {
1373             case ark::compiler::Opcode::CallStatic: {
1374                 instImpl->CastToCallStatic()->AppendInput(input->impl, input->impl->GetType());
1375                 return;
1376             }
1377             case ark::compiler::Opcode::CallVirtual: {
1378                 instImpl->CastToCallVirtual()->AppendInput(input->impl, input->impl->GetType());
1379                 return;
1380             }
1381             case ark::compiler::Opcode::Intrinsic: {
1382                 if (GetIntrinicMaxInputsCount(inst) == rangeInputsCount) {
1383                     instImpl->CastToIntrinsic()->AppendInput(input->impl, input->impl->GetType());
1384                     return;
1385                 }
1386                 if (instImpl->GetInputsCount() >= GetIntrinicMaxInputsCount(inst)) {
1387                     LIBABCKIT_LOG(DEBUG) << "The maximum number of inputs has been reached for the instruction\n";
1388                     SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1389                     return;
1390                 }
1391                 instImpl->CastToIntrinsic()->AppendInput(input->impl, input->impl->GetType());
1392                 return;
1393             }
1394             case ark::compiler::Opcode::Phi: {
1395                 instImpl->AppendInput(input->impl);
1396                 return;
1397             }
1398             default:
1399                 break;
1400         }
1401     }
1402 
1403     LIBABCKIT_LOG(DEBUG) << "The instruction does not have the ability to add inputs\n";
1404     SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1405 }
1406 
1407 // Type helpers
1408 
CreateGeneralType(AbckitFile * file,AbckitTypeId typeId,AbckitCoreClass * klass)1409 static AbckitType *CreateGeneralType(AbckitFile *file, AbckitTypeId typeId, AbckitCoreClass *klass)
1410 {
1411     return GetOrCreateType(file, typeId, 0, klass);
1412 }
1413 
IgetTypeStatic(AbckitInst * inst)1414 AbckitType *IgetTypeStatic(AbckitInst *inst)
1415 {
1416     LIBABCKIT_LOG_FUNC;
1417     AbckitTypeId typeId = TypeToTypeId(inst->impl->GetType());
1418     AbckitCoreClass *klass = nullptr;
1419     if (typeId != ABCKIT_TYPE_ID_REFERENCE) {
1420         return CreateGeneralType(inst->graph->file, typeId, klass);
1421     }
1422     // Add get of ABCKIT_TYPE_ID_REFERENCE NOTE(ymolokanov)
1423     return CreateGeneralType(inst->graph->file, typeId, klass);
1424 }
1425 
IgetTargetTypeStatic(AbckitInst * inst)1426 AbckitTypeId IgetTargetTypeStatic(AbckitInst *inst)
1427 {
1428     LIBABCKIT_LOG_FUNC;
1429     if (inst->impl->GetOpcode() != ark::compiler::Opcode::Cast) {
1430         LIBABCKIT_LOG(DEBUG) << "Instruction is not a cast\n";
1431         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1432         return AbckitTypeId::ABCKIT_TYPE_ID_INVALID;
1433     }
1434 
1435     return TypeToTypeId(static_cast<ark::compiler::CastInst *>(inst->impl)->GetType());
1436 }
1437 
IsetTargetTypeStatic(AbckitInst * inst,AbckitTypeId type)1438 void IsetTargetTypeStatic(AbckitInst *inst, AbckitTypeId type)
1439 {
1440     LIBABCKIT_LOG_FUNC;
1441     if (inst->impl->GetOpcode() != ark::compiler::Opcode::Cast) {
1442         LIBABCKIT_LOG(DEBUG) << "Instruction is not a cast\n";
1443         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1444         return;
1445     }
1446 
1447     inst->impl->SetType(TypeIdToType(type));
1448 }
1449 
IcheckIsCallStatic(AbckitInst * inst)1450 bool IcheckIsCallStatic(AbckitInst *inst)
1451 {
1452     LIBABCKIT_LOG_FUNC;
1453     return IsCallInst(inst);
1454 }
1455 
IgetBasicBlockStatic(AbckitInst * inst)1456 AbckitBasicBlock *IgetBasicBlockStatic(AbckitInst *inst)
1457 {
1458     LIBABCKIT_LOG_FUNC;
1459     auto *graph = inst->graph;
1460     auto *implBB = inst->impl->GetBasicBlock();
1461     auto it = graph->implToBB.find(implBB);
1462     if (it != graph->implToBB.end()) {
1463         return it->second;
1464     }
1465     return nullptr;
1466 }
1467 
IgetGraphStatic(AbckitInst * inst)1468 AbckitGraph *IgetGraphStatic(AbckitInst *inst)
1469 {
1470     LIBABCKIT_LOG_FUNC;
1471     return inst->graph;
1472 }
1473 
IgetFunctionStatic(AbckitInst * inst)1474 AbckitCoreFunction *IgetFunctionStatic(AbckitInst *inst)
1475 {
1476     LIBABCKIT_LOG_FUNC;
1477     auto *graph = inst->graph;
1478 
1479     ark::compiler::RuntimeInterface::MethodPtr methodPtr = nullptr;
1480     if (inst->impl->IsCall()) {
1481         auto *callInst = static_cast<ark::compiler::CallInst *>(inst->impl);
1482         methodPtr = callInst->GetCallMethod();
1483     } else if (inst->impl->IsIntrinsic()) {
1484         size_t idx = 0;
1485         if (IsDynamic(inst->graph->function->owningModule->target)) {
1486             auto instOpcode = GetDynamicOpcode(inst->impl);
1487             if (!HasMethodIdOperandDynamic(instOpcode)) {
1488                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1489                 return nullptr;
1490             }
1491             idx = GetMethodIdOperandIndexDynamic(instOpcode);
1492         } else {
1493             auto instOpcode = GetStaticOpcode(inst->impl);
1494             if (!HasMethodIdOperandStatic(instOpcode)) {
1495                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1496                 return nullptr;
1497             }
1498             idx = GetMethodIdOperandIndexStatic(instOpcode);
1499         }
1500 
1501         auto *intrinsic = inst->impl->CastToIntrinsic();
1502         methodPtr = reinterpret_cast<ark::compiler::RuntimeInterface::MethodPtr>(intrinsic->GetImm(idx));
1503     } else {
1504         LIBABCKIT_LOG(DEBUG) << "Instruction is not a call or intrinsic\n";
1505         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1506         return nullptr;
1507     }
1508 
1509     auto it = graph->irInterface->methods.find(reinterpret_cast<uintptr_t>(methodPtr));
1510     if (it == graph->irInterface->methods.end()) {
1511         LIBABCKIT_LOG(DEBUG) << "No requested call exists in current graph context\n";
1512         SetLastError(ABCKIT_STATUS_UNSUPPORTED);
1513         return nullptr;
1514     }
1515 
1516     auto &nameToFunction = reinterpret_cast<CtxGInternal *>(graph->internal)->runtimeAdapter->IsMethodStatic(methodPtr)
1517                                ? graph->file->nameToFunctionStatic
1518                                : graph->file->nameToFunctionInstance;
1519     if (nameToFunction.count(it->second) == 0) {
1520         statuses::SetLastError(ABCKIT_STATUS_UNSUPPORTED);
1521         return nullptr;
1522     }
1523     return nameToFunction[it->second];
1524 }
1525 
IsetFunctionStatic(AbckitInst * inst,AbckitCoreFunction * function)1526 void IsetFunctionStatic(AbckitInst *inst, AbckitCoreFunction *function)
1527 {
1528     LIBABCKIT_LOG_FUNC;
1529     auto *graph = inst->graph;
1530 
1531     auto methodOffset = GetMethodOffset(graph, function);
1532 
1533     if (inst->impl->IsCall()) {
1534         auto *callInst = static_cast<ark::compiler::CallInst *>(inst->impl);
1535         callInst->SetCallMethodId(methodOffset);
1536     } else if (inst->impl->IsIntrinsic()) {
1537         size_t idx = 0;
1538         if (IsDynamic(inst->graph->function->owningModule->target)) {
1539             auto instOpcode = GetDynamicOpcode(inst->impl);
1540             if (!HasMethodIdOperandDynamic(instOpcode)) {
1541                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1542                 return;
1543             }
1544             idx = GetMethodIdOperandIndexDynamic(instOpcode);
1545         } else {
1546             auto instOpcode = GetStaticOpcode(inst->impl);
1547             if (!HasMethodIdOperandStatic(instOpcode)) {
1548                 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1549                 return;
1550             }
1551             idx = GetMethodIdOperandIndexStatic(instOpcode);
1552         }
1553 
1554         auto *intrinsic = inst->impl->CastToIntrinsic();
1555         intrinsic->SetImm(idx, methodOffset);
1556     } else {
1557         LIBABCKIT_LOG(DEBUG) << "Instruction is not a call or intrinsic\n";
1558         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1559         return;
1560     }
1561 }
1562 
IsetClassStatic(AbckitInst * inst,AbckitCoreClass * klass)1563 void IsetClassStatic(AbckitInst *inst, AbckitCoreClass *klass)
1564 {
1565     LIBABCKIT_LOG_FUNC;
1566     auto *graph = inst->graph;
1567     auto *intrinsic = inst->impl->CastToIntrinsic();
1568     auto instOpcode = GetStaticOpcode(inst->impl);
1569     if (!HasTypeIdOperandStatic(instOpcode)) {
1570         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1571         return;
1572     }
1573     size_t idx = GetTypeIdOperandIndexStatic(instOpcode);
1574     auto klassOffset = GetClassOffset(graph, klass);
1575     intrinsic->SetImm(idx, klassOffset);
1576 }
1577 
IgetClassStatic(AbckitInst * inst)1578 AbckitCoreClass *IgetClassStatic(AbckitInst *inst)
1579 {
1580     LIBABCKIT_LOG_FUNC;
1581     auto *graph = inst->graph;
1582     auto *intrinsic = inst->impl->CastToIntrinsic();
1583     auto instOpcode = IgetOpcodeStaticStatic(inst);
1584     if (!HasTypeIdOperandStatic(instOpcode)) {
1585         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1586         return nullptr;
1587     }
1588     size_t idx = GetTypeIdOperandIndexStatic(instOpcode);
1589     auto classPtr = reinterpret_cast<ark::compiler::RuntimeInterface::ClassPtr>(intrinsic->GetImm(idx));
1590 
1591     auto it = graph->ptrToClass.find(reinterpret_cast<uintptr_t>(classPtr));
1592     if (it == graph->ptrToClass.end()) {
1593         LIBABCKIT_LOG(DEBUG) << "No requested class exists in current graph context\n";
1594         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1595         return nullptr;
1596     }
1597     return it->second;
1598 }
1599 
GcreateNullPtrStatic(AbckitGraph * graph)1600 AbckitInst *GcreateNullPtrStatic(AbckitGraph *graph)
1601 {
1602     auto instImpl = graph->impl->CreateInstNullPtr(ark::compiler::DataType::REFERENCE);
1603     auto *inst = CreateInstFromImpl(graph, instImpl);
1604     graph->impl->GetStartBlock()->AppendInst(instImpl);
1605     return inst;
1606 }
1607 
IgetConstantValueI32Static(AbckitInst * inst)1608 int32_t IgetConstantValueI32Static(AbckitInst *inst)
1609 {
1610     if (!inst->impl->IsConst()) {
1611         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1612                              << '\n';
1613     }
1614     if (inst->impl->GetType() != ark::compiler::DataType::INT32 &&
1615         inst->impl->GetType() != ark::compiler::DataType::UINT32) {
1616         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1617     }
1618     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetInt32Value();
1619 }
1620 
IgetConstantValueI64Static(AbckitInst * inst)1621 int64_t IgetConstantValueI64Static(AbckitInst *inst)
1622 {
1623     if (!inst->impl->IsConst()) {
1624         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1625                              << '\n';
1626     }
1627     if (inst->impl->GetType() != ark::compiler::DataType::INT64 &&
1628         inst->impl->GetType() != ark::compiler::DataType::UINT64) {
1629         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1630     }
1631     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetInt64Value();
1632 }
1633 
IgetConstantValueU64Static(AbckitInst * inst)1634 uint64_t IgetConstantValueU64Static(AbckitInst *inst)
1635 {
1636     if (!inst->impl->IsConst()) {
1637         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1638                              << '\n';
1639         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1640     }
1641     if (inst->impl->GetType() != ark::compiler::DataType::INT64 &&
1642         inst->impl->GetType() != ark::compiler::DataType::UINT64) {
1643         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1644         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1645     }
1646     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetInt64Value();
1647 }
1648 
IgetConstantValueF64Static(AbckitInst * inst)1649 double IgetConstantValueF64Static(AbckitInst *inst)
1650 {
1651     if (!inst->impl->IsConst()) {
1652         LIBABCKIT_LOG(DEBUG) << "Input instruction of " << LIBABCKIT_FUNC_NAME << " must be constant instruction"
1653                              << '\n';
1654         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1655     }
1656     if (inst->impl->GetType() != ark::compiler::DataType::FLOAT64) {
1657         LIBABCKIT_LOG(DEBUG) << "Type of input constant instruction in " << LIBABCKIT_FUNC_NAME << " is wrong" << '\n';
1658         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1659     }
1660     return static_cast<ark::compiler::ConstantInst *>(inst->impl)->GetDoubleValue();
1661 }
1662 
IgetImmediateStatic(AbckitInst * inst,size_t idx)1663 uint64_t IgetImmediateStatic(AbckitInst *inst, size_t idx)
1664 {
1665     LIBABCKIT_LOG_FUNC;
1666 
1667     if (IgetImmediateCountStatic(inst) <= idx) {
1668         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1669         return 0;
1670     }
1671 
1672     uint64_t ret = 0;
1673 
1674     if (inst->impl->IsBinaryImmInst()) {
1675         ret = (static_cast<ark::compiler::BinaryImmOperation *>(inst->impl))->GetImm();
1676     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1677         ret = inst->impl->CastToIntrinsic()->GetImm(idx);
1678     } else {
1679         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1680         return 0;
1681     }
1682     return ret;
1683 }
1684 
IsetImmediateStatic(AbckitInst * inst,size_t idx,uint64_t imm)1685 void IsetImmediateStatic(AbckitInst *inst, size_t idx, uint64_t imm)
1686 {
1687     LIBABCKIT_LOG_FUNC;
1688 
1689     if (IgetImmediateCountStatic(inst) <= idx) {
1690         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1691         return;
1692     }
1693 
1694     if (inst->impl->IsBinaryImmInst()) {
1695         if (GetBitLengthUnsigned(imm) <= GetBinaryImmOperationSize(inst->impl->GetOpcode())) {
1696             (static_cast<ark::compiler::BinaryImmOperation *>(inst->impl))->SetImm(imm);
1697         } else {
1698             LIBABCKIT_LOG(DEBUG) << "Immediate type overflow\n";
1699             SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1700         }
1701     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1702         auto instr = inst->impl->CastToIntrinsic();
1703         if (GetBitLengthUnsigned(imm) <= GetIntrinsicBitImmSize(instr->GetIntrinsicId(), idx)) {
1704             instr->SetImm(idx, imm);
1705         } else {
1706             LIBABCKIT_LOG(DEBUG) << "Immediate type overflow\n";
1707             SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1708         }
1709     } else {
1710         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1711     }
1712 }
1713 
IgetImmediateSizeStatic(AbckitInst * inst,size_t idx)1714 AbckitBitImmSize IgetImmediateSizeStatic(AbckitInst *inst, size_t idx)
1715 {
1716     LIBABCKIT_LOG_FUNC;
1717 
1718     if (IgetImmediateCountStatic(inst) <= idx) {
1719         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1720         return AbckitBitImmSize::BITSIZE_0;
1721     }
1722 
1723     auto immBitSize = AbckitBitImmSize::BITSIZE_0;
1724     if (inst->impl->IsBinaryImmInst()) {
1725         immBitSize = GetBinaryImmOperationSize(inst->impl->GetOpcode());
1726     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1727         auto instr = inst->impl->CastToIntrinsic();
1728         immBitSize = GetIntrinsicBitImmSize(instr->GetIntrinsicId(), idx);
1729     } else {
1730         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1731     }
1732     return immBitSize;
1733 }
1734 
IgetImmediateCountStatic(AbckitInst * inst)1735 uint64_t IgetImmediateCountStatic(AbckitInst *inst)
1736 {
1737     LIBABCKIT_LOG_FUNC;
1738 
1739     uint64_t ret = 0;
1740 
1741     if (inst->impl->IsBinaryImmInst()) {
1742         ret = 1;
1743     } else if (inst->impl->GetOpcode() == ark::compiler::Opcode::Intrinsic) {
1744         auto instr = inst->impl->CastToIntrinsic();
1745         return instr->HasImms() ? instr->GetImms().size() : 0;
1746     }
1747     return ret;
1748 }
1749 
IgetModuleStatic(AbckitInst * inst)1750 AbckitCoreModule *IgetModuleStatic(AbckitInst *inst)
1751 {
1752     LIBABCKIT_LOG_FUNC;
1753 
1754     if (!inst->impl->IsIntrinsic()) {
1755         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1756         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1757         return nullptr;
1758     }
1759 
1760     auto intrInst = inst->impl->CastToIntrinsic();
1761     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1762     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_GETMODULENAMESPACE &&
1763         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_GETMODULENAMESPACE) {
1764         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1765         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1766         return nullptr;
1767     }
1768 
1769     return inst->graph->function->owningModule->md[intrInst->GetImm(0)];
1770 }
1771 
GetModuleIndex(AbckitGraph * graph,AbckitCoreModule * md)1772 uint64_t GetModuleIndex(AbckitGraph *graph, AbckitCoreModule *md)
1773 {
1774     uint64_t imm = 0;
1775     for (auto m : graph->function->owningModule->md) {
1776         if (m == md) {
1777             break;
1778         }
1779         imm++;
1780     }
1781     if (imm == graph->function->owningModule->md.size()) {
1782         LIBABCKIT_LOG(DEBUG) << "Can not find module descriptor for module with name '" << md->moduleName->impl
1783                              << "'\n";
1784         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1785         return 0;
1786     }
1787     return imm;
1788 }
1789 
IsetModuleStatic(AbckitInst * inst,AbckitCoreModule * md)1790 void IsetModuleStatic(AbckitInst *inst, AbckitCoreModule *md)
1791 {
1792     LIBABCKIT_LOG_FUNC;
1793 
1794     if (!inst->impl->IsIntrinsic()) {
1795         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1796         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1797         return;
1798     }
1799 
1800     auto intrInst = inst->impl->CastToIntrinsic();
1801     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1802     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_GETMODULENAMESPACE &&
1803         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_GETMODULENAMESPACE) {
1804         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have module id\n";
1805         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1806         return;
1807     }
1808 
1809     uint64_t imm = GetModuleIndex(inst->graph, md);
1810     if (statuses::GetLastError() != ABCKIT_STATUS_NO_ERROR) {
1811         return;
1812     }
1813     intrInst->SetImm(0, imm);
1814 }
1815 
GetImportDescriptorDynamic(AbckitInst * inst,uint64_t idx)1816 AbckitCoreImportDescriptor *GetImportDescriptorDynamic(AbckitInst *inst, uint64_t idx)
1817 {
1818     auto *module = inst->graph->function->owningModule;
1819     for (auto &id : module->id) {
1820         auto idPayload = GetDynImportDescriptorPayload(id.get());
1821         if (!idPayload->isRegularImport) {
1822             continue;
1823         }
1824         if (idPayload->moduleRecordIndexOff == idx) {
1825             return id.get();
1826         }
1827     }
1828     UNREACHABLE();
1829 }
1830 
IgetImportDescriptorStatic(AbckitInst * inst)1831 AbckitCoreImportDescriptor *IgetImportDescriptorStatic(AbckitInst *inst)
1832 {
1833     LIBABCKIT_LOG_FUNC;
1834     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1835 
1836     if (!inst->impl->IsIntrinsic()) {
1837         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1838         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1839         return nullptr;
1840     }
1841 
1842     auto intrInst = inst->impl->CastToIntrinsic();
1843     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1844     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDEXTERNALMODULEVAR &&
1845         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDEXTERNALMODULEVAR) {
1846         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1847         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1848         return nullptr;
1849     }
1850 
1851     return GetImportDescriptorDynamic(inst, intrInst->GetImm(0));
1852 }
1853 
GetImportDescriptorIdxDynamic(AbckitGraph * graph,AbckitCoreImportDescriptor * id)1854 uint32_t GetImportDescriptorIdxDynamic(AbckitGraph *graph, AbckitCoreImportDescriptor *id)
1855 {
1856     AbckitCoreModule *m = graph->function->owningModule;
1857     auto found = std::find_if(m->id.begin(), m->id.end(),
1858                               [&](std::unique_ptr<AbckitCoreImportDescriptor> const &d) { return d.get() == id; });
1859     if (found == m->id.end()) {
1860         LIBABCKIT_LOG(DEBUG) << "Can not find the import in module imports\n";
1861         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1862         return 0;
1863     }
1864     return GetDynImportDescriptorPayload(found->get())->moduleRecordIndexOff;
1865 }
1866 
IsetImportDescriptorStatic(AbckitInst * inst,AbckitCoreImportDescriptor * id)1867 void IsetImportDescriptorStatic(AbckitInst *inst, AbckitCoreImportDescriptor *id)
1868 {
1869     LIBABCKIT_LOG_FUNC;
1870     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1871 
1872     if (!inst->impl->IsIntrinsic()) {
1873         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1874         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1875         return;
1876     }
1877 
1878     auto intrInst = inst->impl->CastToIntrinsic();
1879     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1880     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDEXTERNALMODULEVAR &&
1881         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDEXTERNALMODULEVAR) {
1882         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have import descriptor\n";
1883         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1884         return;
1885     }
1886 
1887     uint32_t imm = GetImportDescriptorIdxDynamic(inst->graph, id);
1888     if (statuses::GetLastError() != ABCKIT_STATUS_NO_ERROR) {
1889         return;
1890     }
1891     intrInst->SetImm(0, imm);
1892 }
1893 
GetExportDescriptorDynamic(AbckitInst * inst,uint64_t idx)1894 AbckitCoreExportDescriptor *GetExportDescriptorDynamic(AbckitInst *inst, uint64_t idx)
1895 {
1896     auto *module = inst->graph->function->owningModule;
1897     for (auto &ed : module->ed) {
1898         auto edPayload = GetDynExportDescriptorPayload(ed.get());
1899         if (edPayload->kind != AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT) {
1900             continue;
1901         }
1902         if (edPayload->moduleRecordIndexOff == idx) {
1903             return ed.get();
1904         }
1905     }
1906     UNREACHABLE();
1907 }
1908 
IgetExportDescriptorStatic(AbckitInst * inst)1909 AbckitCoreExportDescriptor *IgetExportDescriptorStatic(AbckitInst *inst)
1910 {
1911     LIBABCKIT_LOG_FUNC;
1912     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1913 
1914     if (!inst->impl->IsIntrinsic()) {
1915         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1916         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1917         return nullptr;
1918     }
1919 
1920     auto intrInst = inst->impl->CastToIntrinsic();
1921     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1922     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLOCALMODULEVAR &&
1923         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDLOCALMODULEVAR &&
1924         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_STMODULEVAR &&
1925         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_STMODULEVAR) {
1926         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1927         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1928         return nullptr;
1929     }
1930 
1931     return GetExportDescriptorDynamic(inst, intrInst->GetImm(0));
1932 }
1933 
GetExportDescriptorIdxDynamic(AbckitGraph * graph,AbckitCoreExportDescriptor * ed)1934 uint32_t GetExportDescriptorIdxDynamic(AbckitGraph *graph, AbckitCoreExportDescriptor *ed)
1935 {
1936     AbckitCoreModule *m = graph->function->owningModule;
1937     auto found = std::find_if(m->ed.begin(), m->ed.end(),
1938                               [&](std::unique_ptr<AbckitCoreExportDescriptor> const &d) { return d.get() == ed; });
1939     if (found == m->ed.end()) {
1940         LIBABCKIT_LOG(DEBUG) << "Can not find the import in module imports\n";
1941         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1942         return 0;
1943     }
1944     return GetDynExportDescriptorPayload(found->get())->moduleRecordIndexOff;
1945 }
1946 
IsetExportDescriptorStatic(AbckitInst * inst,AbckitCoreExportDescriptor * ed)1947 void IsetExportDescriptorStatic(AbckitInst *inst, AbckitCoreExportDescriptor *ed)
1948 {
1949     LIBABCKIT_LOG_FUNC;
1950     ASSERT(IsDynamic(inst->graph->function->owningModule->target));
1951 
1952     if (!inst->impl->IsIntrinsic()) {
1953         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1954         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1955         return;
1956     }
1957 
1958     auto intrInst = inst->impl->CastToIntrinsic();
1959     auto opcode = GetDynamicIntrinsicOpcode(intrInst);
1960     if (opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_LDLOCALMODULEVAR &&
1961         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_LDLOCALMODULEVAR &&
1962         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_STMODULEVAR &&
1963         opcode != ABCKIT_ISA_API_DYNAMIC_OPCODE_WIDE_STMODULEVAR) {
1964         LIBABCKIT_LOG(DEBUG) << "Instruction doesn't have export descriptor\n";
1965         SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1966         return;
1967     }
1968 
1969     uint32_t imm = GetExportDescriptorIdxDynamic(inst->graph, ed);
1970     if (statuses::GetLastError() != ABCKIT_STATUS_NO_ERROR) {
1971         return;
1972     }
1973     intrInst->SetImm(0, imm);
1974 }
1975 
IgetConditionCodeStaticStatic(AbckitInst * inst)1976 AbckitIsaApiStaticConditionCode IgetConditionCodeStaticStatic(AbckitInst *inst)
1977 {
1978     return CcToStaticCc(inst->impl->CastToIf()->GetCc());
1979 }
1980 
IgetConditionCodeDynamicStatic(AbckitInst * inst)1981 AbckitIsaApiDynamicConditionCode IgetConditionCodeDynamicStatic(AbckitInst *inst)
1982 {
1983     return CcToDynamicCc(inst->impl->CastToIf()->GetCc());
1984 }
1985 
IsetConditionCodeStaticStatic(AbckitInst * inst,AbckitIsaApiStaticConditionCode cc)1986 void IsetConditionCodeStaticStatic(AbckitInst *inst, AbckitIsaApiStaticConditionCode cc)
1987 {
1988     inst->impl->CastToIf()->SetCc(CcToCc(cc));
1989 }
1990 
IsetConditionCodeDynamicStatic(AbckitInst * inst,AbckitIsaApiDynamicConditionCode cc)1991 void IsetConditionCodeDynamicStatic(AbckitInst *inst, AbckitIsaApiDynamicConditionCode cc)
1992 {
1993     inst->impl->CastToIf()->SetCc(CcToCc(cc));
1994 }
1995 
1996 }  // namespace libabckit
1997