• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef COMPILER_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H
17 #define COMPILER_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H
18 
19 #include "codegen.h"
20 
21 namespace ark::compiler {
22 
23 class Encoder;
24 class CodeBuilder;
25 class OsrEntryStub;
26 
27 class EncodeVisitor : public GraphVisitor {
28     using EntrypointId = RuntimeInterface::EntrypointId;
29 
30 public:
EncodeVisitor(Codegen * cg)31     explicit EncodeVisitor(Codegen *cg) : cg_(cg), arch_(cg->GetArch()) {}
32 
33     EncodeVisitor() = delete;
34 
GetBlocksToVisit()35     const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override
36     {
37         return cg_->GetGraph()->GetBlocksRPO();
38     }
GetCodegen()39     Codegen *GetCodegen() const
40     {
41         return cg_;
42     }
GetEncoder()43     Encoder *GetEncoder()
44     {
45         return cg_->GetEncoder();
46     }
GetArch()47     Arch GetArch() const
48     {
49         return arch_;
50     }
GetCallingConvention()51     CallingConvention *GetCallingConvention()
52     {
53         return cg_->GetCallingConvention();
54     }
55 
GetRegfile()56     RegistersDescription *GetRegfile()
57     {
58         return cg_->GetRegfile();
59     }
60 
GetResult()61     bool GetResult()
62     {
63         return success_ && cg_->GetEncoder()->GetResult();
64     }
65 
66     // For each group of SpillFillData representing spill or fill operations and
67     // sharing the same source and destination types order by stack slot number in descending order.
68     static void SortSpillFillData(ArenaVector<SpillFillData> *spillFills);
69     // Checks if two spill-fill operations could be coalesced into single operation over pair of arguments.
70     static bool CanCombineSpillFills(SpillFillData pred, SpillFillData succ, const CFrameLayout &fl,
71                                      const Graph *graph);
72 
73 protected:
74     // UnaryOperation
75     static void VisitMov(GraphVisitor *visitor, Inst *inst);
76     static void VisitNeg(GraphVisitor *visitor, Inst *inst);
77     static void VisitAbs(GraphVisitor *visitor, Inst *inst);
78     static void VisitNot(GraphVisitor *visitor, Inst *inst);
79     static void VisitSqrt(GraphVisitor *visitor, Inst *inst);
80 
81     // BinaryOperation
82     static void VisitAdd(GraphVisitor *visitor, Inst *inst);
83     static void VisitSub(GraphVisitor *visitor, Inst *inst);
84     static void VisitMul(GraphVisitor *visitor, Inst *inst);
85     static void VisitShl(GraphVisitor *visitor, Inst *inst);
86     static void VisitAShr(GraphVisitor *visitor, Inst *inst);
87     static void VisitAnd(GraphVisitor *visitor, Inst *inst);
88     static void VisitOr(GraphVisitor *visitor, Inst *inst);
89     static void VisitXor(GraphVisitor *visitor, Inst *inst);
90 
91     // Binary Overflow Operation
92     static void VisitAddOverflow(GraphVisitor *visitor, Inst *inst);
93     static void VisitAddOverflowCheck(GraphVisitor *visitor, Inst *inst);
94     static void VisitSubOverflow(GraphVisitor *visitor, Inst *inst);
95     static void VisitSubOverflowCheck(GraphVisitor *visitor, Inst *inst);
96     static void VisitNegOverflowAndZeroCheck(GraphVisitor *visitor, Inst *inst);
97 
98 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
99 #define BINARY_IMM_OPERATION(opc) static void Visit##opc##I(GraphVisitor *visitor, Inst *inst)
100 
101 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
102 #define BINARY_IMM_OPS(DEF) \
103     DEF(Add);               \
104     DEF(Sub);               \
105     DEF(Shl);               \
106     DEF(AShr);              \
107     DEF(And);               \
108     DEF(Or);                \
109     DEF(Xor);               \
110     DEF(Div);               \
111     DEF(Mod)
112 
113     BINARY_IMM_OPS(BINARY_IMM_OPERATION);
114 
115 #undef BINARY_IMM_OPS
116 #undef BINARY_IMM_OPERATION
117 
118 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
119 #define BINARY_SIGN_UNSIGN_OPERATION(opc) static void Visit##opc(GraphVisitor *visitor, Inst *inst)
120 
121 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
122 #define SIGN_UNSIGN_OPS(DEF) \
123     DEF(Div);                \
124     DEF(Mod);                \
125     DEF(Min);                \
126     DEF(Max);                \
127     DEF(Shr)
128 
129     SIGN_UNSIGN_OPS(BINARY_SIGN_UNSIGN_OPERATION);
130 
131 #undef SIGN_UNSIGN_OPS
132 #undef BINARY_SIGN_UNSIGN_OPERATION
133 
134 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
135 #define BINARY_SHIFTED_REGISTER_OPERATION_DEF(opc, ignored) \
136     /* CC-OFFNXT(G.PRE.09) code generation */               \
137     static void Visit##opc##SR(GraphVisitor *visitor, Inst *inst);
138 
139     ENCODE_INST_WITH_SHIFTED_OPERAND(BINARY_SHIFTED_REGISTER_OPERATION_DEF)
140 
141 #undef BINARY_SHIFTED_REGISTER_OPERATION_DEF
142 
143     static void VisitShrI(GraphVisitor *visitor, Inst *inst);
144 
145     static void VisitCast(GraphVisitor *visitor, Inst *inst);
146 
147     static void VisitBitcast(GraphVisitor *visitor, Inst *inst);
148 
149     static void VisitPhi([[maybe_unused]] GraphVisitor *visitor, [[maybe_unused]] Inst *inst);
150 
151     static void VisitConstant(GraphVisitor *visitor, Inst *inst);
152 
153     static void VisitNullPtr(GraphVisitor *visitor, Inst *inst);
154 
155     static void VisitLoadUniqueObject(GraphVisitor *visitor, Inst *inst);
156 
157     static void VisitIf(GraphVisitor *visitor, Inst *inst);
158 
159     static void VisitIfImm(GraphVisitor *visitor, Inst *inst);
160 
161     static void VisitCompare(GraphVisitor *visitor, Inst *inst);
162 
163     static void VisitCmp(GraphVisitor *visitor, Inst *inst);
164 
165     // All next visitors use execution model for implementation
166     static void VisitReturnVoid(GraphVisitor *visitor, Inst * /* unused */);
167 
168     static void VisitReturn(GraphVisitor *visitor, Inst *inst);
169 
170     static void VisitReturnI(GraphVisitor *visitor, Inst *inst);
171 
172     static void VisitReturnInlined(GraphVisitor *visitor, Inst * /* unused */);
173 
174     static void VisitNewArray(GraphVisitor *visitor, Inst *inst);
175 
176     static void VisitLoadConstArray(GraphVisitor *visitor, Inst *inst);
177 
178     static void VisitFillConstArray(GraphVisitor *visitor, Inst *inst);
179 
180     static void VisitParameter(GraphVisitor *visitor, Inst *inst);
181 
182     static void VisitStoreArray(GraphVisitor *visitor, Inst *inst);
183 
184     static void VisitSpillFill(GraphVisitor *visitor, Inst *inst);
185 
186     static void VisitSaveState(GraphVisitor *visitor, Inst *inst);
187 
188     static void VisitSaveStateDeoptimize(GraphVisitor *visitor, Inst *inst);
189 
190     static void VisitSaveStateOsr(GraphVisitor *visitor, Inst *inst);
191 
192     static void VisitLoadArray(GraphVisitor *visitor, Inst *inst);
193 
194     static void VisitLoadCompressedStringChar(GraphVisitor *visitor, Inst *inst);
195 
196     static void VisitLenArray(GraphVisitor *visitor, Inst *inst);
197 
198     static void VisitNullCheck(GraphVisitor *visitor, Inst *inst);
199 
200     static void VisitBoundsCheck(GraphVisitor *visitor, Inst *inst);
201 
202     static void VisitZeroCheck(GraphVisitor *visitor, Inst *inst);
203 
204     static void VisitRefTypeCheck(GraphVisitor *visitor, Inst *inst);
205 
206     static void VisitNegativeCheck(GraphVisitor *visitor, Inst *inst);
207 
208     static void VisitNotPositiveCheck(GraphVisitor *visitor, Inst *inst);
209 
210     static void VisitLoadString(GraphVisitor *visitor, Inst *inst);
211 
212     static void VisitResolveObjectField(GraphVisitor *visitor, Inst *inst);
213 
214     static void VisitLoadResolvedObjectField(GraphVisitor *visitor, Inst *inst);
215 
216     static void VisitLoadObject(GraphVisitor *visitor, Inst *inst);
217 
218     static void VisitLoad(GraphVisitor *visitor, Inst *inst);
219 
220     static void VisitStoreObject(GraphVisitor *visitor, Inst *inst);
221 
222     static void VisitStoreResolvedObjectField(GraphVisitor *visitor, Inst *inst);
223 
224     static void VisitStore(GraphVisitor *visitor, Inst *inst);
225 
226     static void VisitLoadStatic(GraphVisitor *visitor, Inst *inst);
227 
228     static void VisitResolveObjectFieldStatic(GraphVisitor *visitor, Inst *inst);
229 
230     static void VisitLoadResolvedObjectFieldStatic(GraphVisitor *visitor, Inst *inst);
231 
232     static void VisitStoreStatic(GraphVisitor *visitor, Inst *inst);
233 
234     static void VisitUnresolvedStoreStatic(GraphVisitor *visitor, Inst *inst);
235 
236     static void VisitStoreResolvedObjectFieldStatic(GraphVisitor *visitor, Inst *inst);
237 
238     static void VisitNewObject(GraphVisitor *visitor, Inst *inst);
239 
240     static void VisitLoadRuntimeClass(GraphVisitor *visitor, Inst *inst);
241 
242     static void VisitLoadClass(GraphVisitor *visitor, Inst *inst);
243 
244     static void VisitLoadAndInitClass(GraphVisitor *visitor, Inst *inst);
245 
246     static void VisitGetGlobalVarAddress(GraphVisitor *visitor, Inst *inst);
247 
248     static void VisitUnresolvedLoadAndInitClass(GraphVisitor *visitor, Inst *inst);
249 
250     static void VisitInitClass(GraphVisitor *visitor, Inst *inst);
251 
252     static void VisitUnresolvedInitClass(GraphVisitor *visitor, Inst *inst);
253 
254     static void VisitLoadType(GraphVisitor *visitor, Inst *inst);
255 
256     static void VisitUnresolvedLoadType(GraphVisitor *visitor, Inst *inst);
257 
258     static void VisitCheckCast(GraphVisitor *visitor, Inst *inst);
259 
260     static void VisitIsInstance(GraphVisitor *visitor, Inst *inst);
261 
262     static void VisitMonitor(GraphVisitor *visitor, Inst *inst);
263 
264     static void VisitIntrinsic(GraphVisitor *visitor, Inst *inst);
265 
266     static void VisitBuiltin(GraphVisitor *visitor, Inst *inst);
267 
268     static void VisitBoundsCheckI(GraphVisitor *visitor, Inst *inst);
269 
270     static void VisitStoreArrayI(GraphVisitor *visitor, Inst *inst);
271 
272     static void VisitLoadArrayI(GraphVisitor *visitor, Inst *inst);
273 
274     static void VisitLoadCompressedStringCharI(GraphVisitor *visitor, Inst *inst);
275 
276     static void VisitLoadI(GraphVisitor *visitor, Inst *inst);
277 
278     static void VisitStoreI(GraphVisitor *visitor, Inst *inst);
279 
280     static void VisitMultiArray(GraphVisitor *visitor, Inst *inst);
281     static void VisitInitEmptyString(GraphVisitor *visitor, Inst *inst);
282     static void VisitInitString(GraphVisitor *visitor, Inst *inst);
283 
284     static void VisitCallStatic(GraphVisitor *visitor, Inst *inst);
285 
286     static void VisitResolveStatic(GraphVisitor *visitor, Inst *inst);
287     static void VisitCallResolvedStatic(GraphVisitor *visitor, Inst *inst);
288 
289     static void VisitCallVirtual(GraphVisitor *visitor, Inst *inst);
290 
291     static void VisitResolveVirtual(GraphVisitor *visitor, Inst *inst);
292     static void VisitCallResolvedVirtual(GraphVisitor *visitor, Inst *inst);
293 
294     static void VisitCallDynamic(GraphVisitor *visitor, Inst *inst);
295 
296     static void VisitCallNative(GraphVisitor *visitor, Inst *inst);
297     static void VisitWrapObjectNative(GraphVisitor *visitor, Inst *inst);
298 
299     static void VisitLoadConstantPool(GraphVisitor *visitor, Inst *inst);
300     static void VisitLoadLexicalEnv(GraphVisitor *visitor, Inst *inst);
301 
302     static void VisitLoadFromConstantPool(GraphVisitor *visitor, Inst *inst);
303 
304     static void VisitSafePoint(GraphVisitor *visitor, Inst *inst);
305 
306     static void VisitSelect(GraphVisitor *visitor, Inst *inst);
307 
308     static void VisitSelectImm(GraphVisitor *visitor, Inst *inst);
309 
310     static void VisitLoadArrayPair(GraphVisitor *visitor, Inst *inst);
311 
312     static void VisitLoadArrayPairI(GraphVisitor *visitor, Inst *inst);
313 
314     static void VisitLoadPairPart(GraphVisitor *visitor, Inst *inst);
315 
316     static void VisitLoadObjectPair(GraphVisitor *visitor, Inst *inst);
317 
318     static void VisitStoreArrayPair(GraphVisitor *visitor, Inst *inst);
319 
320     static void VisitStoreArrayPairI(GraphVisitor *visitor, Inst *inst);
321 
322     static void VisitStoreObjectPair(GraphVisitor *visitor, Inst *inst);
323 
324     static void VisitLoadExclusive(GraphVisitor *visitor, Inst *inst);
325 
326     static void VisitStoreExclusive(GraphVisitor *visitor, Inst *inst);
327 
328     static void VisitNOP(GraphVisitor *visitor, Inst *inst);
329 
330     static void VisitThrow(GraphVisitor *visitor, Inst *inst);
331 
332     static void VisitDeoptimizeIf(GraphVisitor *visitor, Inst *inst);
333 
334     static void VisitDeoptimizeCompare(GraphVisitor *visitor, Inst *inst);
335 
336     static void VisitDeoptimizeCompareImm(GraphVisitor *visitor, Inst *inst);
337 
338     static void VisitDeoptimize(GraphVisitor *visitor, Inst *inst);
339 
340     static void VisitIsMustDeoptimize(GraphVisitor *visitor, Inst *inst);
341 
342     static void VisitMAdd(GraphVisitor *visitor, Inst *inst);
343     static void VisitMSub(GraphVisitor *visitor, Inst *inst);
344     static void VisitMNeg(GraphVisitor *visitor, Inst *inst);
345     static void VisitOrNot(GraphVisitor *visitor, Inst *inst);
346     static void VisitAndNot(GraphVisitor *visitor, Inst *inst);
347     static void VisitXorNot(GraphVisitor *visitor, Inst *inst);
348     static void VisitNegSR(GraphVisitor *visitor, Inst *inst);
349 
350     static void VisitGetInstanceClass(GraphVisitor *visitor, Inst *inst);
351     static void VisitGetManagedClassObject(GraphVisitor *visito, Inst *inst);
352     static void VisitLoadImmediate(GraphVisitor *visitor, Inst *inst);
353     static void VisitFunctionImmediate(GraphVisitor *visitor, Inst *inst);
354     static void VisitLoadObjFromConst(GraphVisitor *visitor, Inst *inst);
355     static void VisitRegDef(GraphVisitor *visitor, Inst *inst);
356     static void VisitLiveIn(GraphVisitor *visitor, Inst *inst);
357     static void VisitLiveOut(GraphVisitor *visitor, Inst *inst);
358     static void VisitCallIndirect(GraphVisitor *visitor, Inst *inst);
359     static void VisitCall(GraphVisitor *visitor, Inst *inst);
360 
361     static void VisitResolveByName(GraphVisitor *visitor, Inst *inst);
362 
363     // Dyn inst.
364     static void VisitCompareAnyType(GraphVisitor *visitor, Inst *inst);
365     static void VisitGetAnyTypeName(GraphVisitor *visitor, Inst *inst);
366     static void VisitCastAnyTypeValue(GraphVisitor *visitor, Inst *inst);
367     static void VisitCastValueToAnyType(GraphVisitor *visitor, Inst *inst);
368     static void VisitAnyTypeCheck(GraphVisitor *visitor, Inst *inst);
369     static void VisitHclassCheck(GraphVisitor *visitor, Inst *inst);
370     static void VisitObjByIndexCheck(GraphVisitor *visitor, Inst *inst);
371 
372     static void VisitLoadObjectDynamic(GraphVisitor *visitor, Inst *inst);
373     static void VisitStoreObjectDynamic(GraphVisitor *visitor, Inst *inst);
374 
VisitDefault(Inst * inst)375     void VisitDefault([[maybe_unused]] Inst *inst) override
376     {
377 #ifndef NDEBUG
378         COMPILER_LOG(DEBUG, CODEGEN) << "Can't encode instruction " << GetOpcodeString(inst->GetOpcode())
379                                      << " with type " << DataType::ToString(inst->GetType());
380 #endif
381         success_ = false;
382     }
383 
384     // Helper functions
385     static void FillUnresolvedClass(GraphVisitor *visitor, Inst *inst);
386     static void FillObjectClass(GraphVisitor *visitor, Reg tmpReg, LabelHolder::LabelId throwLabel);
387     static void FillOtherClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId throwLabel);
388     static void FillArrayObjectClass(GraphVisitor *visitor, Reg tmpReg, LabelHolder::LabelId throwLabel);
389     static void FillArrayClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId throwLabel);
390     static void FillInterfaceClass(GraphVisitor *visitor, Inst *inst);
391 
392     static void FillLoadClassUnresolved(GraphVisitor *visitor, Inst *inst);
393 
394     static void FillCheckCast(GraphVisitor *visitor, Inst *inst, Reg src, LabelHolder::LabelId endLabel,
395                               compiler::ClassType klassType);
396 
397     static void FillIsInstanceUnresolved(GraphVisitor *visitor, Inst *inst);
398 
399     static void FillIsInstanceCaseObject(GraphVisitor *visitor, Inst *inst, Reg tmpReg);
400 
401     static void FillIsInstanceCaseOther(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId endLabel);
402 
403     static void FillIsInstanceCaseArrayObject(GraphVisitor *visitor, Inst *inst, Reg tmpReg,
404                                               LabelHolder::LabelId endLabel);
405 
406     static void FillIsInstanceCaseArrayClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg,
407                                              LabelHolder::LabelId endLabel);
408 
409     static void FillIsInstanceCaseInterface(GraphVisitor *visitor, Inst *inst);
410 
411     static void FillIsInstance(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId endLabel);
412     static void EncodeLoadAndInitClassInAot(EncodeVisitor *enc, Encoder *encoder, Inst *inst, uint32_t classId,
413                                             Reg dst);
414 
415 #include "optimizer/ir/visitor.inc"
416 
417 private:
418     Codegen *cg_;
419     Arch arch_;
420     bool success_ {true};
421 };  // EncodeVisitor
422 
423 }  // namespace ark::compiler
424 
425 #endif  // COMPILER_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H
426