• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "libabckit/src/adapter_static/metadata_modify_static.h"
17 #include "inst.h"
18 #include "libabckit/src/metadata_inspect_impl.h"
19 #include "libabckit/src/ir_impl.h"
20 #include "libabckit/src/logger.h"
21 #include "libabckit/src/statuses_impl.h"
22 
23 #include "libabckit/src/codegen/codegen_static.h"
24 
25 #include "optimizer/analysis/liveness_analyzer.h"
26 #include "optimizer/analysis/rpo.h"
27 #include "src/adapter_static/metadata_inspect_static.h"
28 #include "src/adapter_static/abckit_static.h"
29 #include "src/adapter_static/helpers_static.h"
30 #include "static_core/assembler/assembly-program.h"
31 
32 #include "static_core/compiler/optimizer/ir/graph_checker.h"
33 #include "static_core/compiler/optimizer/ir/graph_cloner.h"
34 #include "static_core/compiler/optimizer/analysis/loop_analyzer.h"
35 #include "static_core/compiler/optimizer/optimizations/cleanup.h"
36 #include "static_core/compiler/optimizer/optimizations/move_constants.h"
37 #include "static_core/compiler/optimizer/optimizations/lowering.h"
38 #include "static_core/bytecode_optimizer/reg_encoder.h"
39 
40 #include <cstdint>
41 #include <string>
42 
43 // CC-OFFNXT(WordsTool.95) sensitive word conflict
44 // NOLINTNEXTLINE(google-build-using-namespace)
45 using namespace ark;
46 
47 namespace libabckit {
48 
49 // ========================================
50 // Create / Update
51 // ========================================
CreateStringStatic(AbckitFile * file,const char * value,size_t len)52 AbckitString *CreateStringStatic(AbckitFile *file, const char *value, size_t len)
53 {
54     LIBABCKIT_LOG_FUNC;
55     LIBABCKIT_LOG(DEBUG) << "\"" << value << "\"" << '\n';
56     auto *prog = file->GetStaticProgram();
57     const auto &[progValueIter, _] = prog->strings.insert(std::string(value, len));
58     const auto &progValue = *progValueIter;
59     auto &strings = file->strings;
60 
61     if (strings.find(progValue) != strings.end()) {
62         return strings.at(progValue).get();
63     }
64 
65     auto s = std::make_unique<AbckitString>();
66     s->impl = progValue;
67     strings.insert({progValue, std::move(s)});
68     return strings[progValue].get();
69 }
70 
FunctionSetGraphStatic(AbckitCoreFunction * function,AbckitGraph * graph)71 void FunctionSetGraphStatic(AbckitCoreFunction *function, AbckitGraph *graph)
72 {
73     LIBABCKIT_LOG_FUNC;
74     LIBABCKIT_LOG_FUNC;
75 
76     auto *func = function->GetArkTSImpl()->GetStaticImpl();
77 
78     auto graphImpl =
79         compiler::GraphCloner(graph->impl, graph->impl->GetAllocator(), graph->impl->GetLocalAllocator()).CloneGraph();
80 
81     graphImpl->RemoveUnreachableBlocks();
82     GraphInvalidateAnalyses(graphImpl);
83     CheckInvalidOpcodes(graphImpl, false);
84 
85     LIBABCKIT_LOG(DEBUG) << "======================== BEFORE CODEGEN ========================\n";
86     LIBABCKIT_LOG_DUMP(func->DebugDump(), DEBUG);
87     LIBABCKIT_LOG(DEBUG) << "============================================\n";
88 
89     LIBABCKIT_LOG_DUMP(graphImpl->Dump(&std::cerr), DEBUG);
90 
91     LIBABCKIT_LOG(DEBUG) << "============================================\n";
92 
93     if (!ark::compiler::GraphChecker(graphImpl).Check()) {
94         LIBABCKIT_LOG(DEBUG) << func->name << ": Graph Verifier failed!\n";
95         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
96         return;
97     }
98 
99     graphImpl->RunPass<compiler::Lowering>();
100 
101     graphImpl->RunPass<compiler::Cleanup>(false);
102 
103     graphImpl->RunPass<compiler::MoveConstants>();
104 
105     if (!AllocateRegisters(graphImpl, CodeGenStatic::RESERVED_REG)) {
106         LIBABCKIT_LOG(DEBUG) << func->name << ": RegAllocGraphColoring failed!\n";
107         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_INTERNAL_ERROR);
108         return;
109     }
110 
111     if (!graphImpl->RunPass<bytecodeopt::RegEncoder>()) {
112         LIBABCKIT_LOG(DEBUG) << func->name << ": RegEncoder failed!\n";
113         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_INTERNAL_ERROR);
114         return;
115     }
116 
117     if (!graphImpl->RunPass<CodeGenStatic>(func, graph->irInterface)) {
118         LIBABCKIT_LOG(DEBUG) << func->name << ": Code generation failed!\n";
119         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_INTERNAL_ERROR);
120         return;
121     }
122 
123     func->valueOfFirstParam = static_cast<int64_t>(graphImpl->GetStackSlotsCount()) - 1L;
124     func->regsNum = static_cast<size_t>(func->valueOfFirstParam + 1U);
125 
126     LIBABCKIT_LOG(DEBUG) << "======================== AFTER CODEGEN ========================\n";
127     LIBABCKIT_LOG_DUMP(func->DebugDump(), DEBUG);
128     LIBABCKIT_LOG(DEBUG) << "============================================\n";
129 }
130 
FindOrCreateLiteralBoolStatic(AbckitFile * file,bool value)131 AbckitLiteral *FindOrCreateLiteralBoolStatic(AbckitFile *file, bool value)
132 {
133     LIBABCKIT_LOG_FUNC;
134     return FindOrCreateLiteralBoolStaticImpl(file, value);
135 }
136 
FindOrCreateLiteralU8Static(AbckitFile * file,uint8_t value)137 AbckitLiteral *FindOrCreateLiteralU8Static(AbckitFile *file, uint8_t value)
138 {
139     LIBABCKIT_LOG_FUNC;
140     return FindOrCreateLiteralU8StaticImpl(file, value);
141 }
142 
FindOrCreateLiteralU16Static(AbckitFile * file,uint16_t value)143 AbckitLiteral *FindOrCreateLiteralU16Static(AbckitFile *file, uint16_t value)
144 {
145     LIBABCKIT_LOG_FUNC;
146     return FindOrCreateLiteralU16StaticImpl(file, value);
147 }
148 
FindOrCreateLiteralMethodAffiliateStatic(AbckitFile * file,uint16_t value)149 AbckitLiteral *FindOrCreateLiteralMethodAffiliateStatic(AbckitFile *file, uint16_t value)
150 {
151     LIBABCKIT_LOG_FUNC;
152     return FindOrCreateLiteralMethodAffiliateStaticImpl(file, value);
153 }
154 
FindOrCreateLiteralU32Static(AbckitFile * file,uint32_t value)155 AbckitLiteral *FindOrCreateLiteralU32Static(AbckitFile *file, uint32_t value)
156 {
157     LIBABCKIT_LOG_FUNC;
158     return FindOrCreateLiteralU32StaticImpl(file, value);
159 }
160 
FindOrCreateLiteralU64Static(AbckitFile * file,uint64_t value)161 AbckitLiteral *FindOrCreateLiteralU64Static(AbckitFile *file, uint64_t value)
162 {
163     LIBABCKIT_LOG_FUNC;
164     return FindOrCreateLiteralU64StaticImpl(file, value);
165 }
166 
FindOrCreateLiteralFloatStatic(AbckitFile * file,float value)167 AbckitLiteral *FindOrCreateLiteralFloatStatic(AbckitFile *file, float value)
168 {
169     LIBABCKIT_LOG_FUNC;
170     return FindOrCreateLiteralFloatStaticImpl(file, value);
171 }
172 
FindOrCreateLiteralDoubleStatic(AbckitFile * file,double value)173 AbckitLiteral *FindOrCreateLiteralDoubleStatic(AbckitFile *file, double value)
174 {
175     LIBABCKIT_LOG_FUNC;
176     return FindOrCreateLiteralDoubleStaticImpl(file, value);
177 }
178 
FindOrCreateLiteralStringStatic(AbckitFile * file,const char * value,size_t len)179 AbckitLiteral *FindOrCreateLiteralStringStatic(AbckitFile *file, const char *value, size_t len)
180 {
181     LIBABCKIT_LOG_FUNC;
182     return FindOrCreateLiteralStringStaticImpl(file, std::string(value, len));
183 }
184 
FindOrCreateLiteralMethodStatic(AbckitFile * file,AbckitCoreFunction * function)185 AbckitLiteral *FindOrCreateLiteralMethodStatic(AbckitFile *file, AbckitCoreFunction *function)
186 {
187     LIBABCKIT_LOG_FUNC;
188     return FindOrCreateLiteralMethodStaticImpl(file, GetMangleFuncName(function));
189 }
190 
EmplaceType(ark::pandasm::Program * prog,AbckitLiteral * value)191 static void EmplaceType(ark::pandasm::Program *prog, AbckitLiteral *value)
192 {
193     switch (LiteralGetTagStatic(value)) {
194         case ABCKIT_LITERAL_TAG_BOOL:
195             prog->arrayTypes.emplace(pandasm::Type("u1", 1));
196             break;
197         case ABCKIT_LITERAL_TAG_BYTE:
198             prog->arrayTypes.emplace(pandasm::Type("u8", 1));
199             break;
200         case ABCKIT_LITERAL_TAG_SHORT:
201             prog->arrayTypes.emplace(pandasm::Type("u16", 1));
202             break;
203         case ABCKIT_LITERAL_TAG_INTEGER:
204             prog->arrayTypes.emplace(pandasm::Type("u32", 1));
205             break;
206         case ABCKIT_LITERAL_TAG_LONG:
207             prog->arrayTypes.emplace(pandasm::Type("u64", 1));
208             break;
209         case ABCKIT_LITERAL_TAG_FLOAT:
210             prog->arrayTypes.emplace(pandasm::Type("f32", 1));
211             break;
212         case ABCKIT_LITERAL_TAG_DOUBLE:
213             prog->arrayTypes.emplace(pandasm::Type("f64", 1));
214             break;
215         case ABCKIT_LITERAL_TAG_STRING:
216             prog->arrayTypes.emplace(pandasm::Type("reference", 1));
217             break;
218         default:
219             UNREACHABLE();
220     }
221 }
222 
CreateLiteralArrayStatic(AbckitFile * file,AbckitLiteral ** value,size_t size)223 AbckitLiteralArray *CreateLiteralArrayStatic(AbckitFile *file, AbckitLiteral **value, size_t size)
224 {
225     LIBABCKIT_LOG_FUNC;
226     auto *prog = file->GetStaticProgram();
227     EmplaceType(prog, *value);
228     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
229     auto lit = *reinterpret_cast<pandasm::LiteralArray::Literal *>(value[0]->val.get());
230     pandasm::LiteralArray::Literal tagLit;
231     tagLit.tag = panda_file::LiteralTag::TAGVALUE;
232     tagLit.value = static_cast<uint8_t>(lit.tag);
233     std::vector<pandasm::LiteralArray::Literal> stdLitArr;
234     stdLitArr.emplace_back(tagLit);
235 
236     pandasm::LiteralArray::Literal len;
237     len.tag = panda_file::LiteralTag::INTEGER;
238     len.value = static_cast<uint32_t>(size);
239     stdLitArr.emplace_back(len);
240 
241     prog->arrayTypes.emplace(pandasm::Type("u32", 1));
242     for (size_t i = 0; i < size; i++) {
243         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
244         auto lit = *reinterpret_cast<pandasm::LiteralArray::Literal *>(value[i]->val.get());
245         stdLitArr.emplace_back(lit);
246     }
247 
248     // NOLINTNEXTLINE(cert-msc51-cpp)
249     uint32_t arrayOffset = 0;
250     while (prog->literalarrayTable.find(std::to_string(arrayOffset)) != prog->literalarrayTable.end()) {
251         arrayOffset++;
252     }
253     auto arrayName = std::to_string(arrayOffset);
254 
255     prog->literalarrayTable.emplace(arrayName, pandasm::LiteralArray());
256     pandasm::LiteralArray &arrImpl = prog->literalarrayTable[arrayName];
257     arrImpl.literals = std::move(stdLitArr);
258 
259     auto litarr = std::make_unique<AbckitLiteralArray>(file, &arrImpl);
260     return file->litarrs.emplace_back(std::move(litarr)).get();
261 }
262 
FindOrCreateValueU1Static(AbckitFile * file,bool value)263 AbckitValue *FindOrCreateValueU1Static(AbckitFile *file, bool value)
264 {
265     LIBABCKIT_LOG_FUNC;
266     return FindOrCreateValueU1StaticImpl(file, value);
267 }
268 
FindOrCreateValueDoubleStatic(AbckitFile * file,double value)269 AbckitValue *FindOrCreateValueDoubleStatic(AbckitFile *file, double value)
270 {
271     LIBABCKIT_LOG_FUNC;
272     return FindOrCreateValueDoubleStaticImpl(file, value);
273 }
274 
FindOrCreateValueStringStatic(AbckitFile * file,const char * value,size_t len)275 AbckitValue *FindOrCreateValueStringStatic(AbckitFile *file, const char *value, size_t len)
276 {
277     LIBABCKIT_LOG_FUNC;
278     return FindOrCreateValueStringStaticImpl(file, std::string(value, len));
279 }
280 
281 }  // namespace libabckit
282