• 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 #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 VisitLoadUndefined(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 VisitCallLaunchStatic(GraphVisitor *visitor, Inst *inst);
295     static void VisitCallResolvedLaunchStatic(GraphVisitor *visitor, Inst *inst);
296 
297     static void VisitCallLaunchVirtual(GraphVisitor *visitor, Inst *inst);
298     static void VisitCallResolvedLaunchVirtual(GraphVisitor *visitor, Inst *inst);
299 
300     static void VisitCallDynamic(GraphVisitor *visitor, Inst *inst);
301 
302     static void VisitLoadConstantPool(GraphVisitor *visitor, Inst *inst);
303     static void VisitLoadLexicalEnv(GraphVisitor *visitor, Inst *inst);
304 
305     static void VisitLoadFromConstantPool(GraphVisitor *visitor, Inst *inst);
306 
307     static void VisitSafePoint(GraphVisitor *visitor, Inst *inst);
308 
309     static void VisitSelect(GraphVisitor *visitor, Inst *inst);
310 
311     static void VisitSelectImm(GraphVisitor *visitor, Inst *inst);
312 
313     static void VisitLoadArrayPair(GraphVisitor *visitor, Inst *inst);
314 
315     static void VisitLoadArrayPairI(GraphVisitor *visitor, Inst *inst);
316 
317     static void VisitLoadPairPart(GraphVisitor *visitor, Inst *inst);
318 
319     static void VisitLoadObjectPair(GraphVisitor *visitor, Inst *inst);
320 
321     static void VisitStoreArrayPair(GraphVisitor *visitor, Inst *inst);
322 
323     static void VisitStoreArrayPairI(GraphVisitor *visitor, Inst *inst);
324 
325     static void VisitStoreObjectPair(GraphVisitor *visitor, Inst *inst);
326 
327     static void VisitLoadExclusive(GraphVisitor *visitor, Inst *inst);
328 
329     static void VisitStoreExclusive(GraphVisitor *visitor, Inst *inst);
330 
331     static void VisitNOP(GraphVisitor *visitor, Inst *inst);
332 
333     static void VisitThrow(GraphVisitor *visitor, Inst *inst);
334 
335     static void VisitDeoptimizeIf(GraphVisitor *visitor, Inst *inst);
336 
337     static void VisitDeoptimizeCompare(GraphVisitor *visitor, Inst *inst);
338 
339     static void VisitDeoptimizeCompareImm(GraphVisitor *visitor, Inst *inst);
340 
341     static void VisitDeoptimize(GraphVisitor *visitor, Inst *inst);
342 
343     static void VisitIsMustDeoptimize(GraphVisitor *visitor, Inst *inst);
344 
345     static void VisitMAdd(GraphVisitor *visitor, Inst *inst);
346     static void VisitMSub(GraphVisitor *visitor, Inst *inst);
347     static void VisitMNeg(GraphVisitor *visitor, Inst *inst);
348     static void VisitOrNot(GraphVisitor *visitor, Inst *inst);
349     static void VisitAndNot(GraphVisitor *visitor, Inst *inst);
350     static void VisitXorNot(GraphVisitor *visitor, Inst *inst);
351     static void VisitNegSR(GraphVisitor *visitor, Inst *inst);
352 
353     static void VisitGetInstanceClass(GraphVisitor *visitor, Inst *inst);
354     static void VisitGetManagedClassObject(GraphVisitor *visito, Inst *inst);
355     static void VisitLoadImmediate(GraphVisitor *visitor, Inst *inst);
356     static void VisitFunctionImmediate(GraphVisitor *visitor, Inst *inst);
357     static void VisitLoadObjFromConst(GraphVisitor *visitor, Inst *inst);
358     static void VisitRegDef(GraphVisitor *visitor, Inst *inst);
359     static void VisitLiveIn(GraphVisitor *visitor, Inst *inst);
360     static void VisitLiveOut(GraphVisitor *visitor, Inst *inst);
361     static void VisitCallIndirect(GraphVisitor *visitor, Inst *inst);
362     static void VisitCall(GraphVisitor *visitor, Inst *inst);
363 
364     // Dyn inst.
365     static void VisitCompareAnyType(GraphVisitor *visitor, Inst *inst);
366     static void VisitGetAnyTypeName(GraphVisitor *visitor, Inst *inst);
367     static void VisitCastAnyTypeValue(GraphVisitor *visitor, Inst *inst);
368     static void VisitCastValueToAnyType(GraphVisitor *visitor, Inst *inst);
369     static void VisitAnyTypeCheck(GraphVisitor *visitor, Inst *inst);
370     static void VisitHclassCheck(GraphVisitor *visitor, Inst *inst);
371     static void VisitObjByIndexCheck(GraphVisitor *visitor, Inst *inst);
372 
373     static void VisitLoadObjectDynamic(GraphVisitor *visitor, Inst *inst);
374     static void VisitStoreObjectDynamic(GraphVisitor *visitor, Inst *inst);
375 
VisitDefault(Inst * inst)376     void VisitDefault([[maybe_unused]] Inst *inst) override
377     {
378 #ifndef NDEBUG
379         COMPILER_LOG(DEBUG, CODEGEN) << "Can't encode instruction " << GetOpcodeString(inst->GetOpcode())
380                                      << " with type " << DataType::ToString(inst->GetType());
381 #endif
382         success_ = false;
383     }
384 
385     // Helper functions
386     static void FillUnresolvedClass(GraphVisitor *visitor, Inst *inst);
387     static void FillObjectClass(GraphVisitor *visitor, Reg tmpReg, LabelHolder::LabelId throwLabel);
388     static void FillOtherClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId throwLabel);
389     static void FillArrayObjectClass(GraphVisitor *visitor, Reg tmpReg, LabelHolder::LabelId throwLabel);
390     static void FillArrayClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId throwLabel);
391     static void FillInterfaceClass(GraphVisitor *visitor, Inst *inst);
392 
393     static void FillLoadClassUnresolved(GraphVisitor *visitor, Inst *inst);
394 
395     static void FillCheckCast(GraphVisitor *visitor, Inst *inst, Reg src, LabelHolder::LabelId endLabel,
396                               compiler::ClassType klassType);
397 
398     static void FillIsInstanceUnresolved(GraphVisitor *visitor, Inst *inst);
399 
400     static void FillIsInstanceCaseObject(GraphVisitor *visitor, Inst *inst, Reg tmpReg);
401 
402     static void FillIsInstanceCaseOther(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId endLabel);
403 
404     static void FillIsInstanceCaseArrayObject(GraphVisitor *visitor, Inst *inst, Reg tmpReg,
405                                               LabelHolder::LabelId endLabel);
406 
407     static void FillIsInstanceCaseArrayClass(GraphVisitor *visitor, Inst *inst, Reg tmpReg,
408                                              LabelHolder::LabelId endLabel);
409 
410     static void FillIsInstanceCaseInterface(GraphVisitor *visitor, Inst *inst);
411 
412     static void FillIsInstance(GraphVisitor *visitor, Inst *inst, Reg tmpReg, LabelHolder::LabelId endLabel);
413     static void EncodeLoadAndInitClassInAot(EncodeVisitor *enc, Encoder *encoder, Inst *inst, uint32_t classId,
414                                             Reg dst);
415 
416 #include "optimizer/ir/visitor.inc"
417 
418 private:
419     Codegen *cg_;
420     Arch arch_;
421     bool success_ {true};
422 };  // EncodeVisitor
423 
424 }  // namespace ark::compiler
425 
426 #endif  // COMPILER_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H
427