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