• 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 
17 #include "libabckit/src/adapter_static/helpers_static.h"
18 #include "libabckit/src/helpers_common.h"
19 #include "libabckit/src/macros.h"
20 #include "libabckit/src/logger.h"
21 #include "libabckit/src/ir_impl.h"
22 #include "libabckit/src/wrappers/pandasm_wrapper.h"
23 
24 #include "static_core/assembler/assembly-program.h"
25 #include "static_core/assembler/mangling.h"
26 #include "static_core/bytecode_optimizer/reg_acc_alloc.h"
27 #include "static_core/compiler/optimizer/ir/graph.h"
28 #include "static_core/compiler/optimizer/ir/basicblock.h"
29 #include "static_core/compiler/optimizer/ir/marker.h"
30 #include "static_core/compiler/optimizer/optimizations/regalloc/reg_alloc_graph_coloring.h"
31 #include "static_core/compiler/optimizer/optimizations/regalloc/reg_alloc_resolver.h"
32 #include "static_core/compiler/optimizer/analysis/loop_analyzer.h"
33 #include "static_core/compiler/optimizer/analysis/dominators_tree.h"
34 #include "static_core/compiler/optimizer/analysis/linear_order.h"
35 #include "static_core/compiler/optimizer/analysis/rpo.h"
36 
37 #include "abckit_intrinsics_opcodes.inc"
38 
39 static constexpr uint32_t IC_SLOT_VALUE = 0xF;
40 
41 namespace libabckit {
42 
ClassGetNames(const std::string & fullName)43 std::tuple<std::string, std::string> ClassGetNames(const std::string &fullName)
44 {
45     static const std::string GLOBAL_CLASS_NAME = "ETSGLOBAL";
46     std::string::size_type pos = fullName.rfind('.');
47     if (pos == std::string::npos) {
48         return {".", fullName};
49     }
50     if (pos < GLOBAL_CLASS_NAME.size()) {
51         return {fullName.substr(0, pos), fullName.substr(pos + 1)};
52     }
53     auto rawModuleName = fullName.substr(pos - GLOBAL_CLASS_NAME.size(), GLOBAL_CLASS_NAME.size());
54     if (rawModuleName == GLOBAL_CLASS_NAME) {
55         std::string::size_type pos2 = fullName.substr(0, pos).rfind('.');
56         return {fullName.substr(0, pos2), fullName.substr(pos2 + 1)};
57     }
58     return {fullName.substr(0, pos), fullName.substr(pos + 1)};
59 }
60 
FuncGetNames(const std::string & fullSig)61 std::tuple<std::string, std::string> FuncGetNames(const std::string &fullSig)
62 {
63     auto fullName = fullSig.substr(0, fullSig.find(':'));
64     std::string::size_type pos = fullName.rfind('.');
65     if (pos == std::string::npos) {
66         return {".", "ETSGLOBAL"};
67     }
68     return ClassGetNames(fullName.substr(0, pos));
69 }
70 
FuncNameCropModule(const std::string & fullSig)71 std::string FuncNameCropModule(const std::string &fullSig)
72 {
73     auto fullName = fullSig.substr(0, fullSig.find(':'));
74     std::string::size_type dotPos = fullName.rfind('.');
75     if (dotPos != std::string::npos) {
76         return fullSig.substr(dotPos + 1);
77     }
78     return fullSig;
79 }
80 
CheckInvalidOpcodes(ark::compiler::Graph * graph,bool isDynamic)81 void CheckInvalidOpcodes([[maybe_unused]] ark::compiler::Graph *graph, [[maybe_unused]] bool isDynamic)
82 {
83 #ifndef NDEBUG
84     for (auto *bb : graph->GetBlocksRPO()) {
85         for (auto *inst : bb->AllInsts()) {
86             bool isInvalid = isDynamic ? (GetDynamicOpcode(inst) == ABCKIT_ISA_API_DYNAMIC_OPCODE_INVALID)
87                                        : (GetStaticOpcode(inst) == ABCKIT_ISA_API_STATIC_OPCODE_INVALID);
88             if (isInvalid) {
89                 std::ostringstream out;
90                 LIBABCKIT_LOG_DUMP(inst->DumpOpcode(&out), DEBUG);
91                 LIBABCKIT_LOG(DEBUG) << "ASSERTION FAILED: Invalid opcode encountered: " << out.str() << std::endl;
92                 ASSERT(false);
93             }
94         }
95     }
96 #endif
97 }
98 
99 // CC-OFFNXT(G.FUD.05) huge function, big switch-case
100 // CC-OFFNXT(G.FUN.01-CPP) huge function, big switch-case
GetStaticOpcode(ark::compiler::Inst * inst)101 AbckitIsaApiStaticOpcode GetStaticOpcode(ark::compiler::Inst *inst)
102 {
103     auto opcode = inst->GetOpcode();
104     switch (opcode) {
105         case ark::compiler::Opcode::CallStatic:
106             return ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC;
107         case ark::compiler::Opcode::CallVirtual:
108             return ABCKIT_ISA_API_STATIC_OPCODE_CALL_VIRTUAL;
109         case ark::compiler::Opcode::LoadStatic:
110             return ABCKIT_ISA_API_STATIC_OPCODE_LOADSTATIC;
111         case ark::compiler::Opcode::LoadString:
112             return ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING;
113         case ark::compiler::Opcode::LoadObject:
114             return ABCKIT_ISA_API_STATIC_OPCODE_LOADOBJECT;
115         case ark::compiler::Opcode::Sub:
116             return ABCKIT_ISA_API_STATIC_OPCODE_SUB;
117         case ark::compiler::Opcode::ReturnVoid:
118             return ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID;
119         case ark::compiler::Opcode::Parameter:
120             return ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER;
121         case ark::compiler::Opcode::Constant:
122             return ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT;
123         case ark::compiler::Opcode::Cmp:
124             return ABCKIT_ISA_API_STATIC_OPCODE_CMP;
125         case ark::compiler::Opcode::Cast:
126             return ABCKIT_ISA_API_STATIC_OPCODE_CAST;
127         case ark::compiler::Opcode::Return:
128             return ABCKIT_ISA_API_STATIC_OPCODE_RETURN;
129         case ark::compiler::Opcode::Add:
130             return ABCKIT_ISA_API_STATIC_OPCODE_ADD;
131         case ark::compiler::Opcode::Mul:
132             return ABCKIT_ISA_API_STATIC_OPCODE_MUL;
133         case ark::compiler::Opcode::Mod:
134             return ABCKIT_ISA_API_STATIC_OPCODE_MOD;
135         case ark::compiler::Opcode::Div:
136             return ABCKIT_ISA_API_STATIC_OPCODE_DIV;
137         case ark::compiler::Opcode::Neg:
138             return ABCKIT_ISA_API_STATIC_OPCODE_NEG;
139         case ark::compiler::Opcode::AddI:
140             return ABCKIT_ISA_API_STATIC_OPCODE_ADDI;
141         case ark::compiler::Opcode::DivI:
142             return ABCKIT_ISA_API_STATIC_OPCODE_DIVI;
143         case ark::compiler::Opcode::SubI:
144             return ABCKIT_ISA_API_STATIC_OPCODE_SUBI;
145         case ark::compiler::Opcode::MulI:
146             return ABCKIT_ISA_API_STATIC_OPCODE_MULI;
147         case ark::compiler::Opcode::ModI:
148             return ABCKIT_ISA_API_STATIC_OPCODE_MODI;
149         case ark::compiler::Opcode::Shl:
150             return ABCKIT_ISA_API_STATIC_OPCODE_SHL;
151         case ark::compiler::Opcode::Shr:
152             return ABCKIT_ISA_API_STATIC_OPCODE_SHR;
153         case ark::compiler::Opcode::AShr:
154             return ABCKIT_ISA_API_STATIC_OPCODE_ASHR;
155         case ark::compiler::Opcode::ShlI:
156             return ABCKIT_ISA_API_STATIC_OPCODE_SHLI;
157         case ark::compiler::Opcode::ShrI:
158             return ABCKIT_ISA_API_STATIC_OPCODE_SHRI;
159         case ark::compiler::Opcode::AShrI:
160             return ABCKIT_ISA_API_STATIC_OPCODE_ASHRI;
161         case ark::compiler::Opcode::And:
162             return ABCKIT_ISA_API_STATIC_OPCODE_AND;
163         case ark::compiler::Opcode::Or:
164             return ABCKIT_ISA_API_STATIC_OPCODE_OR;
165         case ark::compiler::Opcode::Xor:
166             return ABCKIT_ISA_API_STATIC_OPCODE_XOR;
167         case ark::compiler::Opcode::AndI:
168             return ABCKIT_ISA_API_STATIC_OPCODE_ANDI;
169         case ark::compiler::Opcode::OrI:
170             return ABCKIT_ISA_API_STATIC_OPCODE_ORI;
171         case ark::compiler::Opcode::XorI:
172             return ABCKIT_ISA_API_STATIC_OPCODE_XORI;
173         case ark::compiler::Opcode::Not:
174             return ABCKIT_ISA_API_STATIC_OPCODE_NOT;
175         case ark::compiler::Opcode::LenArray:
176             return ABCKIT_ISA_API_STATIC_OPCODE_LENARRAY;
177         case ark::compiler::Opcode::If:
178             return ABCKIT_ISA_API_STATIC_OPCODE_IF;
179         case ark::compiler::Opcode::NullPtr:
180             return ABCKIT_ISA_API_STATIC_OPCODE_NULLPTR;
181         case ark::compiler::Opcode::Phi:
182             return ABCKIT_ISA_API_STATIC_OPCODE_PHI;
183         case ark::compiler::Opcode::LoadUndefined:
184             return ABCKIT_ISA_API_STATIC_OPCODE_LOADUNDEFINED;
185         case ark::compiler::Opcode::Try:
186             return ABCKIT_ISA_API_STATIC_OPCODE_TRY;
187         case ark::compiler::Opcode::CatchPhi:
188             return ABCKIT_ISA_API_STATIC_OPCODE_CATCHPHI;
189         case ark::compiler::Opcode::Intrinsic:
190             return GetStaticIntrinsicOpcode(inst->CastToIntrinsic());
191         default:
192             LIBABCKIT_LOG(DEBUG) << "compiler->abckit INVALID\n";
193             return ABCKIT_ISA_API_STATIC_OPCODE_INVALID;
194     }
195     LIBABCKIT_UNREACHABLE;
196 }
197 
GetDynamicOpcode(ark::compiler::Inst * inst)198 AbckitIsaApiDynamicOpcode GetDynamicOpcode(ark::compiler::Inst *inst)
199 {
200     auto opcode = inst->GetOpcode();
201     switch (opcode) {
202         case ark::compiler::Opcode::LoadString:
203             return ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING;
204         case ark::compiler::Opcode::Parameter:
205             return ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER;
206         case ark::compiler::Opcode::Constant:
207             return ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT;
208         case ark::compiler::Opcode::If:
209             return ABCKIT_ISA_API_DYNAMIC_OPCODE_IF;
210         case ark::compiler::Opcode::Phi:
211             return ABCKIT_ISA_API_DYNAMIC_OPCODE_PHI;
212         case ark::compiler::Opcode::Try:
213             return ABCKIT_ISA_API_DYNAMIC_OPCODE_TRY;
214         case ark::compiler::Opcode::CatchPhi:
215             return ABCKIT_ISA_API_DYNAMIC_OPCODE_CATCHPHI;
216         case ark::compiler::Opcode::Intrinsic:
217             switch (inst->CastToIntrinsic()->GetIntrinsicId()) {
218                 case ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_STRING:
219                     return ABCKIT_ISA_API_DYNAMIC_OPCODE_LOADSTRING;
220                 default:
221                     break;
222             }
223             return GetDynamicIntrinsicOpcode(inst->CastToIntrinsic());
224         default:
225             LIBABCKIT_LOG(DEBUG) << "compiler->abckit INVALID\n";
226             return ABCKIT_ISA_API_DYNAMIC_OPCODE_INVALID;
227     }
228     LIBABCKIT_UNREACHABLE;
229 }
230 
GetIntrinicMaxInputsCount(AbckitInst * inst)231 size_t GetIntrinicMaxInputsCount(AbckitInst *inst)
232 {
233     ASSERT(inst->impl->IsIntrinsic());
234     if (IsDynamic(inst->graph->function->owningModule->target)) {
235         return GetIntrinicMaxInputsCountDyn(inst->impl->CastToIntrinsic());
236     }
237     return GetIntrinicMaxInputsCountStatic(inst->impl->CastToIntrinsic());
238 }
239 
IsCallInst(AbckitInst * inst)240 bool IsCallInst(AbckitInst *inst)
241 {
242     if (IsDynamic(inst->graph->function->owningModule->target)) {
243         return IsCallInstDyn(inst->impl);
244     }
245     return IsCallInstStatic(inst->impl);
246 }
247 
TypeToTypeId(ark::compiler::DataType::Type type)248 AbckitTypeId TypeToTypeId(ark::compiler::DataType::Type type)
249 {
250     LIBABCKIT_LOG(DEBUG) << "compiler->abckit\n";
251     switch (type) {
252         case ark::compiler::DataType::Type::REFERENCE:
253             return AbckitTypeId::ABCKIT_TYPE_ID_REFERENCE;
254         case ark::compiler::DataType::Type::BOOL:
255             return AbckitTypeId::ABCKIT_TYPE_ID_U1;
256         case ark::compiler::DataType::Type::UINT8:
257             return AbckitTypeId::ABCKIT_TYPE_ID_U8;
258         case ark::compiler::DataType::Type::INT8:
259             return AbckitTypeId::ABCKIT_TYPE_ID_I8;
260         case ark::compiler::DataType::Type::UINT16:
261             return AbckitTypeId::ABCKIT_TYPE_ID_U16;
262         case ark::compiler::DataType::Type::INT16:
263             return AbckitTypeId::ABCKIT_TYPE_ID_I16;
264         case ark::compiler::DataType::Type::UINT32:
265             return AbckitTypeId::ABCKIT_TYPE_ID_U32;
266         case ark::compiler::DataType::Type::INT32:
267             return AbckitTypeId::ABCKIT_TYPE_ID_I32;
268         case ark::compiler::DataType::Type::UINT64:
269             return AbckitTypeId::ABCKIT_TYPE_ID_U64;
270         case ark::compiler::DataType::Type::INT64:
271             return AbckitTypeId::ABCKIT_TYPE_ID_I64;
272         case ark::compiler::DataType::Type::FLOAT32:
273             return AbckitTypeId::ABCKIT_TYPE_ID_F32;
274         case ark::compiler::DataType::Type::FLOAT64:
275             return AbckitTypeId::ABCKIT_TYPE_ID_F64;
276         case ark::compiler::DataType::Type::ANY:
277             return AbckitTypeId::ABCKIT_TYPE_ID_ANY;
278         case ark::compiler::DataType::Type::VOID:
279             return AbckitTypeId::ABCKIT_TYPE_ID_VOID;
280         case ark::compiler::DataType::Type::POINTER:
281         case ark::compiler::DataType::Type::NO_TYPE:
282         default:
283             LIBABCKIT_LOG(DEBUG) << "compiler->abckit INVALID\n";
284             return AbckitTypeId::ABCKIT_TYPE_ID_INVALID;
285     }
286     LIBABCKIT_UNREACHABLE;
287 }
288 
TypeIdToType(AbckitTypeId typeId)289 ark::compiler::DataType::Type TypeIdToType(AbckitTypeId typeId)
290 {
291     LIBABCKIT_LOG(DEBUG) << "abckit->compiler\n";
292     switch (typeId) {
293         case AbckitTypeId::ABCKIT_TYPE_ID_REFERENCE:
294             return ark::compiler::DataType::Type::REFERENCE;
295         case AbckitTypeId::ABCKIT_TYPE_ID_U1:
296             return ark::compiler::DataType::Type::BOOL;
297         case AbckitTypeId::ABCKIT_TYPE_ID_U8:
298             return ark::compiler::DataType::Type::UINT8;
299         case AbckitTypeId::ABCKIT_TYPE_ID_I8:
300             return ark::compiler::DataType::Type::INT8;
301         case AbckitTypeId::ABCKIT_TYPE_ID_U16:
302             return ark::compiler::DataType::Type::UINT16;
303         case AbckitTypeId::ABCKIT_TYPE_ID_I16:
304             return ark::compiler::DataType::Type::INT16;
305         case AbckitTypeId::ABCKIT_TYPE_ID_U32:
306             return ark::compiler::DataType::Type::UINT32;
307         case AbckitTypeId::ABCKIT_TYPE_ID_I32:
308             return ark::compiler::DataType::Type::INT32;
309         case AbckitTypeId::ABCKIT_TYPE_ID_U64:
310             return ark::compiler::DataType::Type::UINT64;
311         case AbckitTypeId::ABCKIT_TYPE_ID_I64:
312             return ark::compiler::DataType::Type::INT64;
313         case AbckitTypeId::ABCKIT_TYPE_ID_F32:
314             return ark::compiler::DataType::Type::FLOAT32;
315         case AbckitTypeId::ABCKIT_TYPE_ID_F64:
316             return ark::compiler::DataType::Type::FLOAT64;
317         case AbckitTypeId::ABCKIT_TYPE_ID_ANY:
318             return ark::compiler::DataType::Type::ANY;
319         case AbckitTypeId::ABCKIT_TYPE_ID_VOID:
320             return ark::compiler::DataType::Type::VOID;
321         case AbckitTypeId::ABCKIT_TYPE_ID_INVALID:
322         default:
323             LIBABCKIT_LOG(DEBUG) << "abckit->compiler INVALID\n";
324             return ark::compiler::DataType::Type::NO_TYPE;
325     }
326     LIBABCKIT_UNREACHABLE;
327 }
328 
CcToCc(AbckitIsaApiDynamicConditionCode cc)329 ark::compiler::ConditionCode CcToCc(AbckitIsaApiDynamicConditionCode cc)
330 {
331     LIBABCKIT_LOG(DEBUG) << "abckit->compiler\n";
332     switch (cc) {
333         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_EQ:
334             return ark::compiler::ConditionCode::CC_EQ;
335         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE:
336             return ark::compiler::ConditionCode::CC_NE;
337         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_LT:
338             return ark::compiler::ConditionCode::CC_LT;
339         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_LE:
340             return ark::compiler::ConditionCode::CC_LE;
341         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_GT:
342             return ark::compiler::ConditionCode::CC_GT;
343         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_GE:
344             return ark::compiler::ConditionCode::CC_GE;
345         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_B:
346             return ark::compiler::ConditionCode::CC_B;
347         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_BE:
348             return ark::compiler::ConditionCode::CC_BE;
349         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_A:
350             return ark::compiler::ConditionCode::CC_A;
351         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_AE:
352             return ark::compiler::ConditionCode::CC_AE;
353         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_TST_EQ:
354             return ark::compiler::ConditionCode::CC_TST_EQ;
355         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_TST_NE:
356             return ark::compiler::ConditionCode::CC_TST_NE;
357         case AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NONE:
358             break;
359     }
360     LIBABCKIT_LOG(DEBUG) << "abckit->compiler CcToCc INVALID\n";
361     LIBABCKIT_UNREACHABLE;
362 }
363 
CcToCc(AbckitIsaApiStaticConditionCode cc)364 ark::compiler::ConditionCode CcToCc(AbckitIsaApiStaticConditionCode cc)
365 {
366     LIBABCKIT_LOG(DEBUG) << "abckit->compiler\n";
367     switch (cc) {
368         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ:
369             return ark::compiler::ConditionCode::CC_EQ;
370         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NE:
371             return ark::compiler::ConditionCode::CC_NE;
372         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_LT:
373             return ark::compiler::ConditionCode::CC_LT;
374         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_LE:
375             return ark::compiler::ConditionCode::CC_LE;
376         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_GT:
377             return ark::compiler::ConditionCode::CC_GT;
378         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_GE:
379             return ark::compiler::ConditionCode::CC_GE;
380         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_B:
381             return ark::compiler::ConditionCode::CC_B;
382         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_BE:
383             return ark::compiler::ConditionCode::CC_BE;
384         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_A:
385             return ark::compiler::ConditionCode::CC_A;
386         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_AE:
387             return ark::compiler::ConditionCode::CC_AE;
388         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_TST_EQ:
389             return ark::compiler::ConditionCode::CC_TST_EQ;
390         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_TST_NE:
391             return ark::compiler::ConditionCode::CC_TST_NE;
392         case AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NONE:
393             break;
394     }
395     LIBABCKIT_LOG(DEBUG) << "abckit->compiler CcToCc INVALID\n";
396     LIBABCKIT_UNREACHABLE;
397 }
398 
CcToDynamicCc(ark::compiler::ConditionCode cc)399 AbckitIsaApiDynamicConditionCode CcToDynamicCc(ark::compiler::ConditionCode cc)
400 {
401     LIBABCKIT_LOG(DEBUG) << "abckit->compiler\n";
402     switch (cc) {
403         case ark::compiler::ConditionCode::CC_EQ:
404             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_EQ;
405         case ark::compiler::ConditionCode::CC_NE:
406             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE;
407         case ark::compiler::ConditionCode::CC_LT:
408             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_LT;
409         case ark::compiler::ConditionCode::CC_LE:
410             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_LE;
411         case ark::compiler::ConditionCode::CC_GT:
412             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_GT;
413         case ark::compiler::ConditionCode::CC_GE:
414             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_GE;
415         case ark::compiler::ConditionCode::CC_B:
416             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_B;
417         case ark::compiler::ConditionCode::CC_BE:
418             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_BE;
419         case ark::compiler::ConditionCode::CC_A:
420             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_A;
421         case ark::compiler::ConditionCode::CC_AE:
422             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_AE;
423         case ark::compiler::ConditionCode::CC_TST_EQ:
424             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_TST_EQ;
425         case ark::compiler::ConditionCode::CC_TST_NE:
426             return AbckitIsaApiDynamicConditionCode::ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_TST_NE;
427         default:
428             break;
429     }
430     LIBABCKIT_LOG(DEBUG) << "compiler->abckit CcToDynamicCc INVALID\n";
431     LIBABCKIT_UNREACHABLE;
432 }
433 
CcToStaticCc(ark::compiler::ConditionCode cc)434 AbckitIsaApiStaticConditionCode CcToStaticCc(ark::compiler::ConditionCode cc)
435 {
436     LIBABCKIT_LOG(DEBUG) << "abckit->compiler\n";
437     switch (cc) {
438         case ark::compiler::ConditionCode::CC_EQ:
439             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ;
440         case ark::compiler::ConditionCode::CC_NE:
441             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NE;
442         case ark::compiler::ConditionCode::CC_LT:
443             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_LT;
444         case ark::compiler::ConditionCode::CC_LE:
445             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_LE;
446         case ark::compiler::ConditionCode::CC_GT:
447             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_GT;
448         case ark::compiler::ConditionCode::CC_GE:
449             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_GE;
450         case ark::compiler::ConditionCode::CC_B:
451             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_B;
452         case ark::compiler::ConditionCode::CC_BE:
453             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_BE;
454         case ark::compiler::ConditionCode::CC_A:
455             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_A;
456         case ark::compiler::ConditionCode::CC_AE:
457             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_AE;
458         case ark::compiler::ConditionCode::CC_TST_EQ:
459             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_TST_EQ;
460         case ark::compiler::ConditionCode::CC_TST_NE:
461             return AbckitIsaApiStaticConditionCode::ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_TST_NE;
462         default:
463             break;
464     }
465     LIBABCKIT_LOG(DEBUG) << "compiler->abckit CcToStaticCc INVALID\n";
466     LIBABCKIT_UNREACHABLE;
467 }
468 
SetLastError(AbckitStatus err)469 void SetLastError(AbckitStatus err)
470 {
471     LIBABCKIT_LOG(DEBUG) << "error code: " << err << std::endl;
472     statuses::SetLastError(err);
473 }
474 
GetClassOffset(AbckitGraph * graph,AbckitCoreClass * klass)475 uint32_t GetClassOffset(AbckitGraph *graph, AbckitCoreClass *klass)
476 {
477     ASSERT(!IsDynamic(graph->function->owningModule->target));
478 
479     auto *rec = klass->GetArkTSImpl()->impl.GetStaticClass();
480     LIBABCKIT_LOG(DEBUG) << "className: " << rec->name << "\n";
481 
482     uint32_t classOffset = 0;
483     for (auto &[id, s] : graph->irInterface->classes) {
484         if (s == rec->name) {
485             classOffset = id;
486         }
487     }
488     if (classOffset == 0) {
489         LIBABCKIT_LOG(DEBUG) << "classOffset == 0\n";
490         LIBABCKIT_UNREACHABLE;
491     }
492     LIBABCKIT_LOG(DEBUG) << "classOffset: " << classOffset << "\n";
493     return classOffset;
494 }
495 
GetFuncName(AbckitCoreFunction * function)496 std::string GetFuncName(AbckitCoreFunction *function)
497 {
498     std::string funcName = "__ABCKIT_INVALID__";
499 
500     if (IsDynamic(function->owningModule->target)) {
501         auto *func = PandasmWrapper::GetWrappedFunction(GetDynFunction(function));
502         funcName = func->name;
503         delete func;
504     } else {
505         auto *func = reinterpret_cast<const ark::pandasm::Function *>(function->GetArkTSImpl()->GetStaticImpl());
506         funcName = func->name;
507     }
508 
509     return funcName;
510 }
511 
GetMangleFuncName(AbckitCoreFunction * function)512 std::string GetMangleFuncName(AbckitCoreFunction *function)
513 {
514     std::string funcName = "__ABCKIT_INVALID__";
515 
516     if (IsDynamic(function->owningModule->target)) {
517         auto *func = PandasmWrapper::GetWrappedFunction(GetDynFunction(function));
518         funcName = func->name;
519         delete func;
520     } else {
521         auto *func = reinterpret_cast<const ark::pandasm::Function *>(function->GetArkTSImpl()->GetStaticImpl());
522         funcName = MangleFunctionName(ark::pandasm::DeMangleName(func->name), func->params, func->returnType);
523     }
524     return funcName;
525 }
526 
GetMethodOffset(AbckitGraph * graph,AbckitCoreFunction * function)527 uint32_t GetMethodOffset(AbckitGraph *graph, AbckitCoreFunction *function)
528 {
529     std::string funcName = GetMangleFuncName(function);
530     ASSERT(funcName != "__ABCKIT_INVALID__");
531     LIBABCKIT_LOG(DEBUG) << "functionName: " << funcName << "\n";
532 
533     uint32_t methodOffset = 0;
534     for (auto &[id, s] : graph->irInterface->methods) {
535         if (s == funcName) {
536             methodOffset = id;
537             break;
538         }
539     }
540     if (methodOffset == 0) {
541         LIBABCKIT_LOG(DEBUG) << "methodOffset == 0\n";
542         LIBABCKIT_UNREACHABLE;
543     }
544     LIBABCKIT_LOG(DEBUG) << "methodOffset: " << methodOffset << "\n";
545     return methodOffset;
546 }
547 
GetStringOffset(AbckitGraph * graph,AbckitString * string)548 uint32_t GetStringOffset(AbckitGraph *graph, AbckitString *string)
549 {
550     uint32_t stringOffset = 0;
551     for (auto &[id, s] : graph->irInterface->strings) {
552         if (s == string->impl) {
553             stringOffset = id;
554         }
555     }
556 
557     if (stringOffset == 0) {
558         // Newly created string
559         // NOLINTNEXTLINE(cert-msc51-cpp)
560         do {
561             LIBABCKIT_LOG(DEBUG) << "generating new stringOffset\n";
562             // NOLINTNEXTLINE(cert-msc50-cpp)
563             stringOffset++;
564         } while (graph->irInterface->strings.find(stringOffset) != graph->irInterface->strings.end());
565         // insert new string id
566         graph->irInterface->strings.insert({stringOffset, string->impl.data()});
567     }
568 
569     LIBABCKIT_LOG(DEBUG) << "stringOffset: " << stringOffset << "\n";
570     return stringOffset;
571 }
572 
GetLiteralArrayOffset(AbckitGraph * graph,AbckitLiteralArray * arr)573 uint32_t GetLiteralArrayOffset(AbckitGraph *graph, AbckitLiteralArray *arr)
574 {
575     std::string arrName = "__ABCKIT_INVALID__";
576     if (IsDynamic(graph->function->owningModule->target)) {
577         auto litarrTable = PandasmWrapper::GetUnwrappedLiteralArrayTable(graph->file->GetDynamicProgram());
578         for (auto &[id, s] : litarrTable) {
579             if (s == arr->GetDynamicImpl()) {
580                 arrName = id;
581             }
582         }
583     } else {
584         auto *prog = graph->file->GetStaticProgram();
585         for (auto &[id, s] : prog->literalarrayTable) {
586             if (&s == arr->GetStaticImpl()) {
587                 arrName = id;
588             }
589         }
590     }
591     ASSERT(arrName != "__ABCKIT_INVALID__");
592 
593     uint32_t arrayOffset = 0;
594     for (auto &[id, s] : graph->irInterface->literalarrays) {
595         if (s == arrName) {
596             arrayOffset = id;
597         }
598     }
599 
600     if (arrayOffset == 0) {
601         // Newly created literal array
602         // NOLINTNEXTLINE(cert-msc51-cpp)
603         do {
604             LIBABCKIT_LOG(DEBUG) << "generating new arrayOffset\n";
605             // NOLINTNEXTLINE(cert-msc50-cpp)
606             arrayOffset++;
607         } while (graph->irInterface->literalarrays.find(arrayOffset) != graph->irInterface->literalarrays.end());
608         // insert new literal array
609         graph->irInterface->literalarrays.insert({arrayOffset, arrName});
610     }
611     return arrayOffset;
612 }
613 
FindOrCreateInstFromImpl(AbckitGraph * graph,ark::compiler::Inst * impl)614 AbckitInst *FindOrCreateInstFromImpl(AbckitGraph *graph, ark::compiler::Inst *impl)
615 {
616     if (graph->implToInst.find(impl) != graph->implToInst.end()) {
617         return graph->implToInst.at(impl);
618     }
619 
620     return CreateInstFromImpl(graph, impl);
621 }
622 
CreateInstFromImpl(AbckitGraph * graph,ark::compiler::Inst * impl)623 AbckitInst *CreateInstFromImpl(AbckitGraph *graph, ark::compiler::Inst *impl)
624 {
625     AbckitInst *newInst = graph->impl->GetLocalAllocator()->New<AbckitInst>(graph, impl);
626     graph->implToInst.insert({impl, newInst});
627     return newInst;
628 }
629 
CreateDynInst(AbckitGraph * graph,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)630 AbckitInst *CreateDynInst(AbckitGraph *graph, ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
631 {
632     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
633     if (hasIC) {
634         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
635     }
636     return CreateInstFromImpl(graph, intrImpl);
637 }
638 
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)639 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,
640                           bool hasIC)
641 {
642     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
643     size_t argsCount {1U};
644     intrImpl->ReserveInputs(argsCount);
645     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
646     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
647     if (hasIC) {
648         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
649     }
650     return CreateInstFromImpl(graph, intrImpl);
651 }
652 
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,AbckitInst * input1,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)653 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, AbckitInst *input1,
654                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
655 {
656     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
657     size_t argsCount {2U};
658     intrImpl->ReserveInputs(argsCount);
659     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
660     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
661     intrImpl->AppendInput(input1->impl, ark::compiler::DataType::ANY);
662     if (hasIC) {
663         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
664     }
665     return CreateInstFromImpl(graph, intrImpl);
666 }
667 
668 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,AbckitInst * input1,AbckitInst * input2,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)669 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, AbckitInst *input1, AbckitInst *input2,
670                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
671 {
672     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
673     size_t argsCount {3U};
674     intrImpl->ReserveInputs(argsCount);
675     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
676     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
677     intrImpl->AppendInput(input1->impl, ark::compiler::DataType::ANY);
678     intrImpl->AppendInput(input2->impl, ark::compiler::DataType::ANY);
679     if (hasIC) {
680         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
681     }
682     return CreateInstFromImpl(graph, intrImpl);
683 }
684 
685 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,AbckitInst * input1,uint64_t imm0,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)686 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, AbckitInst *input1, uint64_t imm0,
687                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
688 {
689     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
690     size_t argsCount {2U};
691     intrImpl->ReserveInputs(argsCount);
692     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
693     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
694     intrImpl->AppendInput(input1->impl, ark::compiler::DataType::ANY);
695     if (hasIC) {
696         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
697     }
698     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
699     return CreateInstFromImpl(graph, intrImpl);
700 }
701 
CreateDynInst(AbckitGraph * graph,uint64_t imm0,ark::compiler::DataType::Type retType,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)702 AbckitInst *CreateDynInst(AbckitGraph *graph, uint64_t imm0, ark::compiler::DataType::Type retType,
703                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
704 {
705     auto intrImpl = graph->impl->CreateInstIntrinsic(retType, 0, intrinsicId);
706     if (hasIC) {
707         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
708     }
709     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
710     return CreateInstFromImpl(graph, intrImpl);
711 }
712 
CreateDynInst(AbckitGraph * graph,uint64_t imm0,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)713 AbckitInst *CreateDynInst(AbckitGraph *graph, uint64_t imm0, ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,
714                           bool hasIC)
715 {
716     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
717     if (hasIC) {
718         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
719     }
720     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
721     return CreateInstFromImpl(graph, intrImpl);
722 }
723 
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,uint64_t imm0,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)724 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, uint64_t imm0,
725                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
726 {
727     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
728     size_t argsCount {1U};
729     intrImpl->ReserveInputs(argsCount);
730     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
731     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
732     if (hasIC) {
733         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
734     }
735     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
736     return CreateInstFromImpl(graph, intrImpl);
737 }
738 
739 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,uint64_t imm0,uint64_t imm1,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)740 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, uint64_t imm0, uint64_t imm1,
741                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
742 {
743     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
744     size_t argsCount {1U};
745     intrImpl->ReserveInputs(argsCount);
746     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
747     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
748     if (hasIC) {
749         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
750     }
751     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
752     intrImpl->AddImm(graph->impl->GetAllocator(), imm1);
753     return CreateInstFromImpl(graph, intrImpl);
754 }
755 
CreateDynInst(AbckitGraph * graph,uint64_t imm0,uint64_t imm1,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)756 AbckitInst *CreateDynInst(AbckitGraph *graph, uint64_t imm0, uint64_t imm1,
757                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
758 {
759     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
760     if (hasIC) {
761         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
762     }
763     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
764     intrImpl->AddImm(graph->impl->GetAllocator(), imm1);
765     return CreateInstFromImpl(graph, intrImpl);
766 }
767 
768 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,AbckitInst * input1,uint64_t imm0,uint64_t imm1,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)769 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, AbckitInst *input1, uint64_t imm0, uint64_t imm1,
770                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
771 {
772     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
773     size_t argsCount {2U};
774     intrImpl->ReserveInputs(argsCount);
775     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
776     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
777     intrImpl->AppendInput(input1->impl, ark::compiler::DataType::ANY);
778     if (hasIC) {
779         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
780     }
781     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
782     intrImpl->AddImm(graph->impl->GetAllocator(), imm1);
783     return CreateInstFromImpl(graph, intrImpl);
784 }
785 
786 // CC-OFFNXT(G.FUN.01-CPP) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * acc,AbckitInst * input0,AbckitInst * input1,AbckitInst * input2,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)787 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *acc, AbckitInst *input0, AbckitInst *input1,
788                           AbckitInst *input2, ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
789 {
790     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
791     size_t argsCount {4U};
792     intrImpl->ReserveInputs(argsCount);
793     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
794     intrImpl->AppendInput(acc->impl, ark::compiler::DataType::ANY);
795     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
796     intrImpl->AppendInput(input1->impl, ark::compiler::DataType::ANY);
797     intrImpl->AppendInput(input2->impl, ark::compiler::DataType::ANY);
798     if (hasIC) {
799         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
800     }
801     return CreateInstFromImpl(graph, intrImpl);
802 }
803 
804 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,uint64_t imm0,uint64_t imm1,uint64_t imm2,AbckitInst * input0,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)805 AbckitInst *CreateDynInst(AbckitGraph *graph, uint64_t imm0, uint64_t imm1, uint64_t imm2, AbckitInst *input0,
806                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
807 {
808     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
809     size_t argsCount {1U};
810     intrImpl->ReserveInputs(argsCount);
811     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
812     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
813     if (hasIC) {
814         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
815     }
816     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
817     intrImpl->AddImm(graph->impl->GetAllocator(), imm1);
818     intrImpl->AddImm(graph->impl->GetAllocator(), imm2);
819     return CreateInstFromImpl(graph, intrImpl);
820 }
821 
822 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * acc,AbckitInst * input0,AbckitInst * input1,AbckitInst * input2,AbckitInst * input3,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)823 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *acc, AbckitInst *input0, AbckitInst *input1,
824                           AbckitInst *input2, AbckitInst *input3, ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,
825                           bool hasIC)
826 {
827     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
828     size_t argsCount {5U};
829     intrImpl->ReserveInputs(argsCount);
830     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
831     intrImpl->AppendInput(acc->impl, ark::compiler::DataType::ANY);
832     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
833     intrImpl->AppendInput(input1->impl, ark::compiler::DataType::ANY);
834     intrImpl->AppendInput(input2->impl, ark::compiler::DataType::ANY);
835     intrImpl->AppendInput(input3->impl, ark::compiler::DataType::ANY);
836     if (hasIC) {
837         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
838     }
839     return CreateInstFromImpl(graph, intrImpl);
840 }
841 
842 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * input0,AbckitInst * input1,uint64_t imm0,std::va_list args,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)843 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *input0, AbckitInst *input1, uint64_t imm0, std::va_list args,
844                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
845 {
846     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
847     size_t argsCount {imm0 + 2U};
848     intrImpl->ReserveInputs(imm0 + 2U);
849     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
850     intrImpl->AppendInput(input0->impl, ark::compiler::DataType::ANY);
851     intrImpl->AppendInput(input1->impl, ark::compiler::DataType::ANY);
852     for (size_t index = 0; index < imm0; index++) {
853         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
854         AbckitInst *input = va_arg(args, AbckitInst *);
855         intrImpl->AppendInput(input->impl, ark::compiler::DataType::ANY);
856     }
857     if (hasIC) {
858         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
859     }
860     intrImpl->AddImm(graph->impl->GetAllocator(), imm0);
861     return CreateInstFromImpl(graph, intrImpl);
862 }
863 
864 // CC-OFFNXT(G.FUN.01) helper function
CreateDynInst(AbckitGraph * graph,AbckitInst * acc,size_t argCount,std::va_list args,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)865 AbckitInst *CreateDynInst(AbckitGraph *graph, AbckitInst *acc, size_t argCount, std::va_list args,
866                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
867 {
868     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
869     size_t argsCount {argCount + 1};
870     intrImpl->ReserveInputs(argCount + 1);
871     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
872     intrImpl->AppendInput(acc->impl, ark::compiler::DataType::ANY);
873     for (size_t index = 0; index < argCount; ++index) {
874         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
875         AbckitInst *input = va_arg(args, AbckitInst *);
876         intrImpl->AppendInput(input->impl, ark::compiler::DataType::ANY);
877     }
878     if (hasIC) {
879         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
880     }
881     intrImpl->AddImm(graph->impl->GetAllocator(), argCount);
882     return CreateInstFromImpl(graph, intrImpl);
883 }
884 
CreateDynInst(AbckitGraph * graph,size_t argCount,std::va_list args,ark::compiler::IntrinsicInst::IntrinsicId intrinsicId,bool hasIC)885 AbckitInst *CreateDynInst(AbckitGraph *graph, size_t argCount, std::va_list args,
886                           ark::compiler::IntrinsicInst::IntrinsicId intrinsicId, bool hasIC)
887 {
888     auto intrImpl = graph->impl->CreateInstIntrinsic(ark::compiler::DataType::ANY, 0, intrinsicId);
889     size_t argsCount {argCount};
890     intrImpl->ReserveInputs(argCount);
891     intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount);
892     for (size_t index = 0; index < argCount; ++index) {
893         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
894         AbckitInst *input = va_arg(args, AbckitInst *);
895         intrImpl->AppendInput(input->impl, ark::compiler::DataType::ANY);
896     }
897     if (hasIC) {
898         intrImpl->AddImm(graph->impl->GetAllocator(), IC_SLOT_VALUE);
899     }
900     intrImpl->AddImm(graph->impl->GetAllocator(), argCount);
901     return CreateInstFromImpl(graph, intrImpl);
902 }
903 
904 template <class T>
FindOrCreateLiteral(AbckitFile * file,std::unordered_map<T,std::unique_ptr<AbckitLiteral>> & cache,T value,ark::panda_file::LiteralTag tagImpl)905 static AbckitLiteral *FindOrCreateLiteral(AbckitFile *file,
906                                           std::unordered_map<T, std::unique_ptr<AbckitLiteral>> &cache, T value,
907                                           ark::panda_file::LiteralTag tagImpl)
908 {
909     if (cache.count(value) == 1) {
910         return cache[value].get();
911     }
912 
913     auto literalDeleter = [](pandasm_Literal *p) -> void {
914         delete reinterpret_cast<ark::pandasm::LiteralArray::Literal *>(p);
915     };
916 
917     auto *literal = new ark::pandasm::LiteralArray::Literal();
918     literal->tag = tagImpl;
919     literal->value = value;
920     auto abcLit = std::make_unique<AbckitLiteral>(
921         file, AbckitLiteralImplT(reinterpret_cast<pandasm_Literal *>(literal), literalDeleter));
922     cache.insert({value, std::move(abcLit)});
923     return cache[value].get();
924 }
925 
FindOrCreateLiteralBoolStaticImpl(AbckitFile * file,bool value)926 AbckitLiteral *FindOrCreateLiteralBoolStaticImpl(AbckitFile *file, bool value)
927 {
928     return FindOrCreateLiteral(file, file->literals.boolLits, value, ark::panda_file::LiteralTag::ARRAY_U1);
929 }
930 
FindOrCreateLiteralU8StaticImpl(AbckitFile * file,uint8_t value)931 AbckitLiteral *FindOrCreateLiteralU8StaticImpl(AbckitFile *file, uint8_t value)
932 {
933     return FindOrCreateLiteral(file, file->literals.u8Lits, value, ark::panda_file::LiteralTag::ARRAY_U8);
934 }
935 
FindOrCreateLiteralU16StaticImpl(AbckitFile * file,uint16_t value)936 AbckitLiteral *FindOrCreateLiteralU16StaticImpl(AbckitFile *file, uint16_t value)
937 {
938     return FindOrCreateLiteral(file, file->literals.u16Lits, value, ark::panda_file::LiteralTag::ARRAY_U16);
939 }
940 
FindOrCreateLiteralMethodAffiliateStaticImpl(AbckitFile * file,uint16_t value)941 AbckitLiteral *FindOrCreateLiteralMethodAffiliateStaticImpl(AbckitFile *file, uint16_t value)
942 {
943     return FindOrCreateLiteral(file, file->literals.methodAffilateLits, value,
944                                ark::panda_file::LiteralTag::METHODAFFILIATE);
945 }
946 
FindOrCreateLiteralU32StaticImpl(AbckitFile * file,uint32_t value)947 AbckitLiteral *FindOrCreateLiteralU32StaticImpl(AbckitFile *file, uint32_t value)
948 {
949     return FindOrCreateLiteral(file, file->literals.u32Lits, value, ark::panda_file::LiteralTag::ARRAY_U32);
950 }
951 
FindOrCreateLiteralU64StaticImpl(AbckitFile * file,uint64_t value)952 AbckitLiteral *FindOrCreateLiteralU64StaticImpl(AbckitFile *file, uint64_t value)
953 {
954     return FindOrCreateLiteral(file, file->literals.u64Lits, value, ark::panda_file::LiteralTag::ARRAY_U64);
955 }
956 
FindOrCreateLiteralFloatStaticImpl(AbckitFile * file,float value)957 AbckitLiteral *FindOrCreateLiteralFloatStaticImpl(AbckitFile *file, float value)
958 {
959     return FindOrCreateLiteral(file, file->literals.floatLits, value, ark::panda_file::LiteralTag::FLOAT);
960 }
961 
FindOrCreateLiteralDoubleStaticImpl(AbckitFile * file,double value)962 AbckitLiteral *FindOrCreateLiteralDoubleStaticImpl(AbckitFile *file, double value)
963 {
964     return FindOrCreateLiteral(file, file->literals.doubleLits, value, ark::panda_file::LiteralTag::DOUBLE);
965 }
966 
FindOrCreateLiteralStringStaticImpl(AbckitFile * file,const std::string & value)967 AbckitLiteral *FindOrCreateLiteralStringStaticImpl(AbckitFile *file, const std::string &value)
968 {
969     return FindOrCreateLiteral(file, file->literals.stringLits, value, ark::panda_file::LiteralTag::STRING);
970 }
971 
FindOrCreateLiteralMethodStaticImpl(AbckitFile * file,const std::string & value)972 AbckitLiteral *FindOrCreateLiteralMethodStaticImpl(AbckitFile *file, const std::string &value)
973 {
974     return FindOrCreateLiteral(file, file->literals.methodLits, value, ark::panda_file::LiteralTag::METHOD);
975 }
976 
977 template <class T, ark::pandasm::Value::Type PANDASM_VALUE_TYPE>
FindOrCreateScalarValue(AbckitFile * file,std::unordered_map<T,std::unique_ptr<AbckitValue>> & cache,T value)978 static AbckitValue *FindOrCreateScalarValue(AbckitFile *file,
979                                             std::unordered_map<T, std::unique_ptr<AbckitValue>> &cache, T value)
980 {
981     if (cache.count(value) == 1) {
982         return cache[value].get();
983     }
984 
985     auto valueDeleter = [](pandasm_Value *val) -> void { delete reinterpret_cast<ark::pandasm::ScalarValue *>(val); };
986 
987     auto *pval = new ark::pandasm::ScalarValue(ark::pandasm::ScalarValue::Create<PANDASM_VALUE_TYPE>(value));
988     auto abcVal =
989         std::make_unique<AbckitValue>(file, AbckitValueImplT(reinterpret_cast<pandasm_Value *>(pval), valueDeleter));
990     cache.insert({value, std::move(abcVal)});
991     return cache[value].get();
992 }
993 
FindOrCreateValueU1StaticImpl(AbckitFile * file,bool value)994 AbckitValue *FindOrCreateValueU1StaticImpl(AbckitFile *file, bool value)
995 {
996     return FindOrCreateScalarValue<bool, ark::pandasm::Value::Type::U1>(file, file->values.boolVals, value);
997 }
998 
FindOrCreateValueDoubleStaticImpl(AbckitFile * file,double value)999 AbckitValue *FindOrCreateValueDoubleStaticImpl(AbckitFile *file, double value)
1000 {
1001     return FindOrCreateScalarValue<double, ark::pandasm::Value::Type::F64>(file, file->values.doubleVals, value);
1002 }
1003 
FindOrCreateValueStringStaticImpl(AbckitFile * file,const std::string & value)1004 AbckitValue *FindOrCreateValueStringStaticImpl(AbckitFile *file, const std::string &value)
1005 {
1006     return FindOrCreateScalarValue<std::string, ark::pandasm::Value::Type::STRING>(file, file->values.stringVals,
1007                                                                                    value);
1008 }
1009 
FindOrCreateLiteralArrayValueStaticImpl(AbckitFile * file,const std::string & value)1010 AbckitValue *FindOrCreateLiteralArrayValueStaticImpl(AbckitFile *file, const std::string &value)
1011 {
1012     return FindOrCreateScalarValue<std::string, ark::pandasm::Value::Type::LITERALARRAY>(file, file->values.litarrVals,
1013                                                                                          value);
1014 }
1015 
FindOrCreateValueStatic(AbckitFile * file,const ark::pandasm::Value & value)1016 AbckitValue *FindOrCreateValueStatic(AbckitFile *file, const ark::pandasm::Value &value)
1017 {
1018     switch (value.GetType()) {
1019         case ark::pandasm::Value::Type::U1:
1020             return FindOrCreateValueU1StaticImpl(file, value.GetAsScalar()->GetValue<bool>());
1021         case ark::pandasm::Value::Type::F64:
1022             return FindOrCreateValueDoubleStaticImpl(file, value.GetAsScalar()->GetValue<double>());
1023         case ark::pandasm::Value::Type::STRING:
1024             return FindOrCreateValueStringStaticImpl(file, value.GetAsScalar()->GetValue<std::string>());
1025         case ark::pandasm::Value::Type::LITERALARRAY:
1026             return FindOrCreateLiteralArrayValueStaticImpl(file, value.GetAsScalar()->GetValue<std::string>());
1027         case ark::pandasm::Value::Type::I8:
1028         case ark::pandasm::Value::Type::U8:
1029         case ark::pandasm::Value::Type::I16:
1030         case ark::pandasm::Value::Type::U16:
1031         case ark::pandasm::Value::Type::I32:
1032         case ark::pandasm::Value::Type::U32:
1033         case ark::pandasm::Value::Type::I64:
1034         case ark::pandasm::Value::Type::U64:
1035         case ark::pandasm::Value::Type::F32:
1036         case ark::pandasm::Value::Type::STRING_NULLPTR:
1037         case ark::pandasm::Value::Type::RECORD:
1038         case ark::pandasm::Value::Type::METHOD:
1039         case ark::pandasm::Value::Type::ENUM:
1040         case ark::pandasm::Value::Type::ANNOTATION:
1041         case ark::pandasm::Value::Type::ARRAY:
1042         case ark::pandasm::Value::Type::VOID:
1043         case ark::pandasm::Value::Type::METHOD_HANDLE:
1044         case ark::pandasm::Value::Type::UNKNOWN:
1045         default:
1046             LIBABCKIT_UNREACHABLE;
1047     }
1048 }
1049 
FixPreassignedRegisters(ark::compiler::Inst * inst,ark::compiler::Register reg,ark::compiler::Register regLarge)1050 void FixPreassignedRegisters(ark::compiler::Inst *inst, ark::compiler::Register reg, ark::compiler::Register regLarge)
1051 {
1052     for (size_t idx = 0; idx < inst->GetInputsCount(); idx++) {
1053         if (inst->GetSrcReg(idx) == reg) {
1054             inst->SetSrcReg(idx, regLarge);
1055         }
1056     }
1057     if (inst->GetDstReg() == reg) {
1058         inst->SetDstReg(regLarge);
1059     }
1060 }
1061 
FixPreassignedRegisters(ark::compiler::Graph * graph)1062 void FixPreassignedRegisters(ark::compiler::Graph *graph)
1063 {
1064     for (auto bb : graph->GetBlocksRPO()) {
1065         for (auto inst : bb->AllInsts()) {
1066             FixPreassignedRegisters(inst, ark::compiler::INVALID_REG, ark::compiler::INVALID_REG_LARGE);
1067             FixPreassignedRegisters(inst, ark::compiler::INVALID_REG - 1U,
1068                                     ark::compiler::INVALID_REG_LARGE - 1U);  // ACC_REG
1069         }
1070     }
1071 }
1072 
AllocateRegisters(ark::compiler::Graph * graph,uint8_t reservedReg)1073 bool AllocateRegisters(ark::compiler::Graph *graph, uint8_t reservedReg)
1074 {
1075     graph->RunPass<ark::bytecodeopt::RegAccAlloc>();
1076     ark::compiler::RegAllocResolver(graph).ResolveCatchPhis();
1077     if (!ark::compiler::IsFrameSizeLarge()) {
1078         return graph->RunPass<ark::compiler::RegAllocGraphColoring>(ark::compiler::GetFrameSize());
1079     }
1080     ark::compiler::LocationMask regMask(graph->GetLocalAllocator());
1081     regMask.Resize(ark::compiler::GetFrameSize());
1082     regMask.Set(reservedReg);
1083     FixPreassignedRegisters(graph);
1084     return graph->RunPass<ark::compiler::RegAllocGraphColoring>(regMask);
1085 }
1086 
GraphInvalidateAnalyses(ark::compiler::Graph * graph)1087 void GraphInvalidateAnalyses(ark::compiler::Graph *graph)
1088 {
1089     graph->InvalidateAnalysis<ark::compiler::LoopAnalyzer>();
1090     graph->InvalidateAnalysis<ark::compiler::Rpo>();
1091     graph->InvalidateAnalysis<ark::compiler::DominatorsTree>();
1092     graph->InvalidateAnalysis<ark::compiler::LinearOrder>();
1093 }
1094 
GraphMarkBlocksRec(ark::compiler::Graph * graph,ark::compiler::Marker mrk,ark::compiler::BasicBlock * block)1095 static void GraphMarkBlocksRec(ark::compiler::Graph *graph, ark::compiler::Marker mrk, ark::compiler::BasicBlock *block)
1096 {
1097     if (block->SetMarker(mrk)) {
1098         return;
1099     }
1100     for (auto succ : block->GetSuccsBlocks()) {
1101         GraphMarkBlocksRec(graph, mrk, succ);
1102     }
1103 }
1104 
GraphHasUnreachableBlocks(ark::compiler::Graph * graph)1105 bool GraphHasUnreachableBlocks(ark::compiler::Graph *graph)
1106 {
1107     bool ret = false;
1108     ark::compiler::Marker mrk = graph->NewMarker();
1109     GraphMarkBlocksRec(graph, mrk, graph->GetStartBlock());
1110     auto bbs = graph->GetVectorBlocks();
1111     // Remove unreachable blocks
1112     for (auto &bb : bbs) {
1113         if (bb != nullptr && !bb->IsMarked(mrk)) {
1114             LIBABCKIT_LOG(DEBUG) << "BB " << bb->GetId() << " is unreachable\n";
1115             ret = true;
1116             break;
1117         }
1118     }
1119     graph->EraseMarker(mrk);
1120     return ret;
1121 }
1122 
GraphDominatorsTreeAnalysisIsValid(ark::compiler::Graph * graph)1123 bool GraphDominatorsTreeAnalysisIsValid(ark::compiler::Graph *graph)
1124 {
1125     if (!graph->GetAnalysis<ark::compiler::DominatorsTree>().IsValid()) {
1126         if (!graph->RunPass<ark::compiler::DominatorsTree>()) {
1127             LIBABCKIT_LOG(DEBUG) << ": ICDominatorsTree failed!\n";
1128             return false;
1129         }
1130     }
1131     return true;
1132 }
1133 
1134 }  // namespace libabckit
1135