• 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     static void Visit##opc##SR(GraphVisitor *visitor, Inst *inst);
137 
138     ENCODE_INST_WITH_SHIFTED_OPERAND(BINARY_SHIFTED_REGISTER_OPERATION_DEF)
139 
140 #undef BINARY_SHIFTED_REGISTER_OPERATION_DEF
141 
142     static void VisitShrI(GraphVisitor *visitor, Inst *inst);
143 
144     static void VisitCast(GraphVisitor *visitor, Inst *inst);
145 
146     static void VisitBitcast(GraphVisitor *visitor, Inst *inst);
147 
148     static void VisitPhi([[maybe_unused]] GraphVisitor *visitor, [[maybe_unused]] Inst *inst);
149 
150     static void VisitConstant(GraphVisitor *visitor, Inst *inst);
151 
152     static void VisitNullPtr(GraphVisitor *visitor, Inst *inst);
153 
154     static void VisitLoadUndefined(GraphVisitor *visitor, Inst *inst);
155 
156     static void VisitIf(GraphVisitor *visitor, Inst *inst);
157 
158     static void VisitIfImm(GraphVisitor *visitor, Inst *inst);
159 
160     static void VisitCompare(GraphVisitor *visitor, Inst *inst);
161 
162     static void VisitCmp(GraphVisitor *visitor, Inst *inst);
163 
164     // All next visitors use execution model for implementation
165     static void VisitReturnVoid(GraphVisitor *visitor, Inst * /* unused */);
166 
167     static void VisitReturn(GraphVisitor *visitor, Inst *inst);
168 
169     static void VisitReturnI(GraphVisitor *visitor, Inst *inst);
170 
171     static void VisitReturnInlined(GraphVisitor *visitor, Inst * /* unused */);
172 
173     static void VisitNewArray(GraphVisitor *visitor, Inst *inst);
174 
175     static void VisitLoadConstArray(GraphVisitor *visitor, Inst *inst);
176 
177     static void VisitFillConstArray(GraphVisitor *visitor, Inst *inst);
178 
179     static void VisitParameter(GraphVisitor *visitor, Inst *inst);
180 
181     static void VisitStoreArray(GraphVisitor *visitor, Inst *inst);
182 
183     static void VisitSpillFill(GraphVisitor *visitor, Inst *inst);
184 
185     static void VisitSaveState(GraphVisitor *visitor, Inst *inst);
186 
187     static void VisitSaveStateDeoptimize(GraphVisitor *visitor, Inst *inst);
188 
189     static void VisitSaveStateOsr(GraphVisitor *visitor, Inst *inst);
190 
191     static void VisitLoadArray(GraphVisitor *visitor, Inst *inst);
192 
193     static void VisitLoadCompressedStringChar(GraphVisitor *visitor, Inst *inst);
194 
195     static void VisitLenArray(GraphVisitor *visitor, Inst *inst);
196 
197     static void VisitNullCheck(GraphVisitor *visitor, Inst *inst);
198 
199     static void VisitBoundsCheck(GraphVisitor *visitor, Inst *inst);
200 
201     static void VisitZeroCheck(GraphVisitor *visitor, Inst *inst);
202 
203     static void VisitRefTypeCheck(GraphVisitor *visitor, Inst *inst);
204 
205     static void VisitNegativeCheck(GraphVisitor *visitor, Inst *inst);
206 
207     static void VisitNotPositiveCheck(GraphVisitor *visitor, Inst *inst);
208 
209     static void VisitLoadString(GraphVisitor *visitor, Inst *inst);
210 
211     static void VisitResolveObjectField(GraphVisitor *visitor, Inst *inst);
212 
213     static void VisitLoadResolvedObjectField(GraphVisitor *visitor, Inst *inst);
214 
215     static void VisitLoadObject(GraphVisitor *visitor, Inst *inst);
216 
217     static void VisitLoad(GraphVisitor *visitor, Inst *inst);
218 
219     static void VisitStoreObject(GraphVisitor *visitor, Inst *inst);
220 
221     static void VisitStoreResolvedObjectField(GraphVisitor *visitor, Inst *inst);
222 
223     static void VisitStore(GraphVisitor *visitor, Inst *inst);
224 
225     static void VisitLoadStatic(GraphVisitor *visitor, Inst *inst);
226 
227     static void VisitResolveObjectFieldStatic(GraphVisitor *visitor, Inst *inst);
228 
229     static void VisitLoadResolvedObjectFieldStatic(GraphVisitor *visitor, Inst *inst);
230 
231     static void VisitStoreStatic(GraphVisitor *visitor, Inst *inst);
232 
233     static void VisitUnresolvedStoreStatic(GraphVisitor *visitor, Inst *inst);
234 
235     static void VisitStoreResolvedObjectFieldStatic(GraphVisitor *visitor, Inst *inst);
236 
237     static void VisitNewObject(GraphVisitor *visitor, Inst *inst);
238 
239     static void VisitLoadRuntimeClass(GraphVisitor *visitor, Inst *inst);
240 
241     static void VisitLoadClass(GraphVisitor *visitor, Inst *inst);
242 
243     static void VisitLoadAndInitClass(GraphVisitor *visitor, Inst *inst);
244 
245     static void VisitGetGlobalVarAddress(GraphVisitor *visitor, Inst *inst);
246 
247     static void VisitUnresolvedLoadAndInitClass(GraphVisitor *visitor, Inst *inst);
248 
249     static void VisitInitClass(GraphVisitor *visitor, Inst *inst);
250 
251     static void VisitUnresolvedInitClass(GraphVisitor *visitor, Inst *inst);
252 
253     static void VisitLoadType(GraphVisitor *visitor, Inst *inst);
254 
255     static void VisitUnresolvedLoadType(GraphVisitor *visitor, Inst *inst);
256 
257     static void VisitCheckCast(GraphVisitor *visitor, Inst *inst);
258 
259     static void VisitIsInstance(GraphVisitor *visitor, Inst *inst);
260 
261     static void VisitMonitor(GraphVisitor *visitor, Inst *inst);
262 
263     static void VisitIntrinsic(GraphVisitor *visitor, Inst *inst);
264 
265     static void VisitBuiltin(GraphVisitor *visitor, Inst *inst);
266 
267     static void VisitBoundsCheckI(GraphVisitor *visitor, Inst *inst);
268 
269     static void VisitStoreArrayI(GraphVisitor *visitor, Inst *inst);
270 
271     static void VisitLoadArrayI(GraphVisitor *visitor, Inst *inst);
272 
273     static void VisitLoadCompressedStringCharI(GraphVisitor *visitor, Inst *inst);
274 
275     static void VisitLoadI(GraphVisitor *visitor, Inst *inst);
276 
277     static void VisitStoreI(GraphVisitor *visitor, Inst *inst);
278 
279     static void VisitMultiArray(GraphVisitor *visitor, Inst *inst);
280     static void VisitInitEmptyString(GraphVisitor *visitor, Inst *inst);
281     static void VisitInitString(GraphVisitor *visitor, Inst *inst);
282 
283     static void VisitCallStatic(GraphVisitor *visitor, Inst *inst);
284 
285     static void VisitResolveStatic(GraphVisitor *visitor, Inst *inst);
286     static void VisitCallResolvedStatic(GraphVisitor *visitor, Inst *inst);
287 
288     static void VisitCallVirtual(GraphVisitor *visitor, Inst *inst);
289 
290     static void VisitResolveVirtual(GraphVisitor *visitor, Inst *inst);
291     static void VisitCallResolvedVirtual(GraphVisitor *visitor, Inst *inst);
292 
293     static void VisitCallLaunchStatic(GraphVisitor *visitor, Inst *inst);
294     static void VisitCallResolvedLaunchStatic(GraphVisitor *visitor, Inst *inst);
295 
296     static void VisitCallLaunchVirtual(GraphVisitor *visitor, Inst *inst);
297     static void VisitCallResolvedLaunchVirtual(GraphVisitor *visitor, Inst *inst);
298 
299     static void VisitCallDynamic(GraphVisitor *visitor, Inst *inst);
300 
301     static void VisitLoadConstantPool(GraphVisitor *visitor, Inst *inst);
302     static void VisitLoadLexicalEnv(GraphVisitor *visitor, Inst *inst);
303 
304     static void VisitLoadFromConstantPool(GraphVisitor *visitor, Inst *inst);
305 
306     static void VisitSafePoint(GraphVisitor *visitor, Inst *inst);
307 
308     static void VisitSelect(GraphVisitor *visitor, Inst *inst);
309 
310     static void VisitSelectImm(GraphVisitor *visitor, Inst *inst);
311 
312     static void VisitLoadArrayPair(GraphVisitor *visitor, Inst *inst);
313 
314     static void VisitLoadArrayPairI(GraphVisitor *visitor, Inst *inst);
315 
316     static void VisitLoadPairPart(GraphVisitor *visitor, Inst *inst);
317 
318     static void VisitLoadObjectPair(GraphVisitor *visitor, Inst *inst);
319 
320     static void VisitStoreArrayPair(GraphVisitor *visitor, Inst *inst);
321 
322     static void VisitStoreArrayPairI(GraphVisitor *visitor, Inst *inst);
323 
324     static void VisitStoreObjectPair(GraphVisitor *visitor, Inst *inst);
325 
326     static void VisitLoadExclusive(GraphVisitor *visitor, Inst *inst);
327 
328     static void VisitStoreExclusive(GraphVisitor *visitor, Inst *inst);
329 
330     static void VisitNOP(GraphVisitor *visitor, Inst *inst);
331 
332     static void VisitThrow(GraphVisitor *visitor, Inst *inst);
333 
334     static void VisitDeoptimizeIf(GraphVisitor *visitor, Inst *inst);
335 
336     static void VisitDeoptimizeCompare(GraphVisitor *visitor, Inst *inst);
337 
338     static void VisitDeoptimizeCompareImm(GraphVisitor *visitor, Inst *inst);
339 
340     static void VisitDeoptimize(GraphVisitor *visitor, Inst *inst);
341 
342     static void VisitIsMustDeoptimize(GraphVisitor *visitor, Inst *inst);
343 
344     static void VisitMAdd(GraphVisitor *visitor, Inst *inst);
345     static void VisitMSub(GraphVisitor *visitor, Inst *inst);
346     static void VisitMNeg(GraphVisitor *visitor, Inst *inst);
347     static void VisitOrNot(GraphVisitor *visitor, Inst *inst);
348     static void VisitAndNot(GraphVisitor *visitor, Inst *inst);
349     static void VisitXorNot(GraphVisitor *visitor, Inst *inst);
350     static void VisitNegSR(GraphVisitor *visitor, Inst *inst);
351 
352     static void VisitGetInstanceClass(GraphVisitor *visitor, Inst *inst);
353     static void VisitGetManagedClassObject(GraphVisitor *visito, Inst *inst);
354     static void VisitLoadImmediate(GraphVisitor *visitor, Inst *inst);
355     static void VisitFunctionImmediate(GraphVisitor *visitor, Inst *inst);
356     static void VisitLoadObjFromConst(GraphVisitor *visitor, Inst *inst);
357     static void VisitRegDef(GraphVisitor *visitor, Inst *inst);
358     static void VisitLiveIn(GraphVisitor *visitor, Inst *inst);
359     static void VisitLiveOut(GraphVisitor *visitor, Inst *inst);
360     static void VisitCallIndirect(GraphVisitor *visitor, Inst *inst);
361     static void VisitCall(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 
413 #include "optimizer/ir/visitor.inc"
414 
415 private:
416     Codegen *cg_;
417     Arch arch_;
418     bool success_ {true};
419 };  // EncodeVisitor
420 
421 }  // namespace ark::compiler
422 
423 #endif  // COMPILER_OPTIMIZER_CODEGEN_ENCODE_VISITOR_H
424