• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 MAPLEBE_INCLUDE_CG_CGFUNC_H
17 #define MAPLEBE_INCLUDE_CG_CGFUNC_H
18 
19 #include "becommon.h"
20 #include "operand.h"
21 #include "eh_func.h"
22 #include "memlayout.h"
23 #include "reg_info.h"
24 #include "cgbb.h"
25 #include "call_conv.h"
26 #include "cfi.h"
27 #include "dbg.h"
28 #include "reaching.h"
29 #include "cg_cfg.h"
30 #include "cg_irbuilder.h"
31 #include "call_conv.h"
32 /* MapleIR headers. */
33 #include "mir_parser.h"
34 #include "mir_function.h"
35 #include "debug_info.h"
36 
37 /* Maple MP header */
38 #include "mempool_allocator.h"
39 #include "triple.h"
40 
41 namespace maplebe {
42 constexpr int32 kBBLimit = 100000;
43 constexpr int32 kFreqBase = 100000;
44 struct MemOpndCmp {
operatorMemOpndCmp45     bool operator()(const MemOperand *lhs, const MemOperand *rhs) const
46     {
47         CHECK_FATAL(lhs != nullptr, "null ptr check");
48         CHECK_FATAL(rhs != nullptr, "null ptr check");
49         if (lhs == rhs) {
50             return false;
51         }
52         return (lhs->Less(*rhs));
53     }
54 };
55 
56 class SpillMemOperandSet {
57 public:
SpillMemOperandSet(MapleAllocator & mallocator)58     explicit SpillMemOperandSet(MapleAllocator &mallocator) : reuseSpillLocMem(mallocator.Adapter()) {}
59 
60     virtual ~SpillMemOperandSet() = default;
61 
Add(MemOperand & op)62     void Add(MemOperand &op)
63     {
64         (void)reuseSpillLocMem.insert(&op);
65     }
66 
Remove(MemOperand & op)67     void Remove(MemOperand &op)
68     {
69         reuseSpillLocMem.erase(&op);
70     }
71 
GetOne()72     MemOperand *GetOne()
73     {
74         if (!reuseSpillLocMem.empty()) {
75             MemOperand *res = *reuseSpillLocMem.begin();
76             reuseSpillLocMem.erase(res);
77             return res;
78         }
79         return nullptr;
80     }
81 
82 private:
83     MapleSet<MemOperand *, MemOpndCmp> reuseSpillLocMem;
84 };
85 
86 // Memory read/write node helper - such as: iread, dread, iassign, dassign
87 class MemRWNodeHelper {
88 public:
MemRWNodeHelper(const BaseNode & node,MIRFunction & mirFunc,const BECommon & beCommon)89     MemRWNodeHelper(const BaseNode &node, MIRFunction &mirFunc, const BECommon &beCommon)
90     {
91         GetMemRWNodeBaseInfo(node, mirFunc);
92         GetTrueMirInfo(beCommon);
93     }
94     ~MemRWNodeHelper() = default;
95 
GetFieldID()96     FieldID GetFieldID() const
97     {
98         return fieldId;
99     }
100 
GetMIRType()101     const MIRType *GetMIRType() const
102     {
103         return mirType;
104     }
105 
GetMIRType()106     MIRType *GetMIRType()
107     {
108         return mirType;
109     }
110 
GetByteOffset()111     int32 GetByteOffset() const
112     {
113         return byteOffset;
114     }
115 
GetMemSize()116     uint32 GetMemSize() const
117     {
118         return memSize;
119     }
120 
GetPrimType()121     PrimType GetPrimType() const
122     {
123         return primType;
124     }
125 
IsRefField()126     bool IsRefField() const
127     {
128         return isRefField;
129     }
130 
GetSymbol()131     const MIRSymbol *GetSymbol() const
132     {
133         return symbol;
134     }
135 
GetSymbol()136     MIRSymbol *GetSymbol()
137     {
138         return symbol;
139     }
140 
141 private:
142     FieldID fieldId = FieldID(0);  // fieldId from node
143     MIRType *mirType = nullptr;    // true mirType
144     MIRSymbol *symbol = nullptr;   // date sym, for dread/dassign
145     int32 byteOffset = 0;
146     uint32 memSize = 0;
147     PrimType primType = PTY_unknown;
148     bool isRefField = false;
149 
150     void GetMemRWNodeBaseInfo(const BaseNode &node, MIRFunction &mirFunc);
151     void GetTrueMirInfo(const BECommon &beCommon);
152 };
153 
154 #if TARGARM32
155 class LiveRange;
156 #endif /* TARGARM32 */
157 constexpr uint32 kVRegisterNumber = 80;
158 class CGFunc {
159 public:
160     enum ShiftDirection : uint8 { kShiftLeft, kShiftAright, kShiftLright };
161 
162     CGFunc(MIRModule &mod, CG &cg, MIRFunction &mirFunc, BECommon &beCommon, MemPool &memPool, StackMemPool &stackMp,
163            MapleAllocator &allocator, uint32 funcId);
164     virtual ~CGFunc();
165 
GetName()166     const std::string &GetName() const
167     {
168         return func.GetName();
169     }
170 
GetLabelAndValueMap()171     const MapleMap<LabelIdx, uint64> &GetLabelAndValueMap() const
172     {
173         return labelMap;
174     }
175 
InsertLabelMap(LabelIdx idx,uint64 value)176     void InsertLabelMap(LabelIdx idx, uint64 value)
177     {
178         DEBUG_ASSERT(labelMap.find(idx) == labelMap.end(), "idx already exist");
179         labelMap[idx] = value;
180     }
181 
LayoutStackFrame()182     void LayoutStackFrame()
183     {
184         CHECK_FATAL(memLayout != nullptr, "memLayout should has been initialized in constructor");
185         memLayout->LayoutStackFrame(structCopySize, maxParamStackSize);
186     }
187 
HasCall()188     bool HasCall() const
189     {
190         return func.HasCall();
191     }
192 
HasVLAOrAlloca()193     bool HasVLAOrAlloca() const
194     {
195         return hasVLAOrAlloca;
196     }
197 
SetHasVLAOrAlloca(bool val)198     void SetHasVLAOrAlloca(bool val)
199     {
200         hasVLAOrAlloca = val;
201     }
202 
HasAlloca()203     bool HasAlloca() const
204     {
205         return hasAlloca;
206     }
207 
SetHasAlloca(bool val)208     void SetHasAlloca(bool val)
209     {
210         hasAlloca = val;
211     }
212 
SetRD(ReachingDefinition * paramRd)213     void SetRD(ReachingDefinition *paramRd)
214     {
215         reachingDef = paramRd;
216     }
217 
GetInsnBuilder()218     InsnBuilder *GetInsnBuilder()
219     {
220         return insnBuilder;
221     }
GetOpndBuilder()222     OperandBuilder *GetOpndBuilder()
223     {
224         return opndBuilder;
225     }
226 
GetRDStatus()227     bool GetRDStatus() const
228     {
229         return (reachingDef != nullptr);
230     }
231 
GetRD()232     ReachingDefinition *GetRD()
233     {
234         return reachingDef;
235     }
236 
237     EHFunc *BuildEHFunc();
238     virtual void GenSaveMethodInfoCode(BB &bb) = 0;
239     virtual void GenerateCleanupCode(BB &bb) = 0;
240     virtual bool NeedCleanup() = 0;
241     virtual void GenerateCleanupCodeForExtEpilog(BB &bb) = 0;
242 
243     void CreateLmbcFormalParamInfo();
244     virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0;
245     virtual void AssignLmbcFormalParams() = 0;
246     LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset);
247     virtual void LmbcGenSaveSpForAlloca() = 0;
248     void RemoveUnreachableBB();
249     Insn &BuildLocInsn(int64 fileNum, int64 lineNum, int64 columnNum);
250     void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc);
251     int32 GetFreqFromStmt(uint32 stmtId);
252     void GenerateInstruction();
253     bool MemBarOpt(const StmtNode &membar);
254     void UpdateCallBBFrequency();
255     void HandleFunction();
256     void ProcessExitBBVec();
257     void AddCommonExitBB();
258     virtual void MergeReturn() = 0;
259     void TraverseAndClearCatchMark(BB &bb);
260     void MarkCatchBBs();
GetMaxRegNum()261     uint32 GetMaxRegNum() const
262     {
263         return vReg.GetMaxRegCount();
264     };
SetMaxRegNum(uint32 num)265     void SetMaxRegNum(uint32 num)
266     {
267         vReg.SetMaxRegCount(num);
268     }
IncMaxRegNum(uint32 num)269     void IncMaxRegNum(uint32 num) const
270     {
271         vReg.IncMaxRegCount(num);
272     }
273     // Attention! Do not invoke this interface in other processes except unit-test
SetMaxVReg(uint32 num)274     void SetMaxVReg(uint32 num) const
275     {
276         vReg.SetCount(num);
277     }
278     void DumpCFG() const;
279     void DumpBBInfo(const BB *bb) const;
280     void DumpCGIR() const;
281     Operand *HandleExpr(const BaseNode &parent, BaseNode &expr);
282     /* handle rc reset */
283     virtual void HandleRCCall(bool begin, const MIRSymbol *retRef = nullptr) = 0;
284     virtual void HandleRetCleanup(NaryStmtNode &retNode) = 0;
285     /* select stmt */
286     virtual void SelectDassign(DassignNode &stmt, Operand &opnd0) = 0;
287     virtual void SelectDassignoff(DassignoffNode &stmt, Operand &opnd0) = 0;
288     virtual void SelectRegassign(RegassignNode &stmt, Operand &opnd0) = 0;
289     virtual void SelectAbort() = 0;
290     virtual void SelectAssertNull(UnaryStmtNode &stmt) = 0;
291     virtual void SelectAsm(AsmNode &node) = 0;
292     virtual void SelectAggDassign(DassignNode &stmt) = 0;
293     virtual void SelectIassign(IassignNode &stmt) = 0;
294     virtual void SelectIassignoff(IassignoffNode &stmt) = 0;
295     virtual void SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) = 0;
296     virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0;
297     virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0;
298     virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0;
299     virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0;
300     virtual void SelectReturn(Operand *opnd) = 0;
301     virtual void SelectIgoto(Operand *opnd0) = 0;
302     virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0;
303     virtual void SelectCondSpecialCase1(CondGotoNode &stmt, BaseNode &opnd0) = 0;
304     virtual void SelectCondSpecialCase2(const CondGotoNode &stmt, BaseNode &opnd0) = 0;
305     virtual void SelectGoto(GotoNode &stmt) = 0;
306     virtual void SelectCall(CallNode &callNode) = 0;
307     virtual void SelectIcall(IcallNode &icallNode) = 0;
308     virtual void SelectIntrinsicCall(IntrinsiccallNode &intrinsiccallNode) = 0;
309     virtual Operand *SelectIntrinsicOpWithOneParam(IntrinsicopNode &intrinsicopNode, std::string name) = 0;
310     virtual Operand *SelectIntrinsicOpWithNParams(IntrinsicopNode &intrinsicopNode, PrimType retType,
311                                                   const std::string &name) = 0;
312     virtual Operand *SelectCclz(IntrinsicopNode &intrinsicopNode) = 0;
313     virtual Operand *SelectCctz(IntrinsicopNode &intrinsicopNode) = 0;
314     virtual Operand *SelectCpopcount(IntrinsicopNode &intrinsicopNode) = 0;
315     virtual Operand *SelectCparity(IntrinsicopNode &intrinsicopNode) = 0;
316     virtual Operand *SelectCclrsb(IntrinsicopNode &intrinsicopNode) = 0;
317     virtual Operand *SelectCisaligned(IntrinsicopNode &intrinsicopNode) = 0;
318     virtual Operand *SelectCalignup(IntrinsicopNode &intrinsicopNode) = 0;
319     virtual Operand *SelectCaligndown(IntrinsicopNode &intrinsicopNode) = 0;
320     virtual Operand *SelectCSyncFetch(IntrinsicopNode &intrinsicopNode, Opcode op, bool fetchBefore) = 0;
321     virtual Operand *SelectCSyncBoolCmpSwap(IntrinsicopNode &intrinsicopNode) = 0;
322     virtual Operand *SelectCSyncValCmpSwap(IntrinsicopNode &intrinsicopNode) = 0;
323     virtual Operand *SelectCSyncLockTestSet(IntrinsicopNode &intrinsicopNode, PrimType pty) = 0;
324     virtual Operand *SelectCSyncSynchronize(IntrinsicopNode &intrinsicopNode) = 0;
325     virtual Operand *SelectCAtomicLoadN(IntrinsicopNode &intrinsicopNode) = 0;
326     virtual Operand *SelectCAtomicExchangeN(const IntrinsiccallNode &intrinsiccallNode) = 0;
327     virtual Operand *SelectCReturnAddress(IntrinsicopNode &intrinsicopNode) = 0;
328     virtual void SelectMembar(StmtNode &membar) = 0;
329     virtual void SelectComment(CommentNode &comment) = 0;
330     virtual void HandleCatch() = 0;
331 
332     /* select expr */
333     virtual Operand *SelectDread(const BaseNode &parent, AddrofNode &expr) = 0;
334     virtual RegOperand *SelectRegread(RegreadNode &expr) = 0;
335     virtual Operand *SelectAddrof(AddrofNode &expr, const BaseNode &parent, bool isAddrofoff) = 0;
336     virtual Operand *SelectAddrofoff(AddrofoffNode &expr, const BaseNode &parent) = 0;
337     virtual Operand &SelectAddrofFunc(AddroffuncNode &expr, const BaseNode &parent) = 0;
338     virtual Operand &SelectAddrofLabel(AddroflabelNode &expr, const BaseNode &parent) = 0;
339     virtual Operand *SelectIread(const BaseNode &parent, IreadNode &expr, int extraOffset = 0,
340                                  PrimType finalBitFieldDestType = kPtyInvalid) = 0;
341     virtual Operand *SelectIreadoff(const BaseNode &parent, IreadoffNode &ireadoff) = 0;
342     virtual Operand *SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) = 0;
343     virtual Operand *SelectIntConst(const MIRIntConst &intConst, const BaseNode &parent) = 0;
344     virtual Operand *SelectFloatConst(MIRFloatConst &floatConst, const BaseNode &parent) = 0;
345     virtual Operand *SelectDoubleConst(MIRDoubleConst &doubleConst, const BaseNode &parent) = 0;
346     virtual Operand *SelectStrConst(MIRStrConst &strConst) = 0;
347     virtual Operand *SelectStr16Const(MIRStr16Const &strConst) = 0;
348     virtual void SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
349     virtual Operand *SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
350     virtual void SelectMadd(Operand &resOpnd, Operand &opndM0, Operand &opndM1, Operand &opnd1, PrimType primType) = 0;
351     virtual Operand *SelectMadd(BinaryNode &node, Operand &opndM0, Operand &opndM1, Operand &opnd1,
352                                 const BaseNode &parent) = 0;
353     virtual Operand *SelectRor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
354     virtual Operand &SelectCGArrayElemAdd(BinaryNode &node, const BaseNode &parent) = 0;
355     virtual Operand *SelectShift(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
356     virtual void SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
357     virtual Operand *SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
358     virtual Operand *SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
359     virtual void SelectDiv(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
360     virtual Operand *SelectDiv(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
361     virtual Operand *SelectSub(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
362     virtual void SelectSub(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
363     virtual Operand *SelectBand(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
364     virtual void SelectBand(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
365     virtual Operand *SelectLand(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
366     virtual Operand *SelectLor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent,
367                                bool parentIsBr = false) = 0;
368     virtual void SelectMin(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
369     virtual Operand *SelectMin(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
370     virtual void SelectMax(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
371     virtual Operand *SelectMax(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
372     virtual Operand *SelectCmpOp(CompareNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
373     virtual Operand *SelectBior(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
374     virtual void SelectBior(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
375     virtual Operand *SelectBxor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0;
376     virtual void SelectBxor(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0;
377     virtual Operand *SelectAbs(UnaryNode &node, Operand &opnd0) = 0;
378     virtual Operand *SelectBnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0;
379     virtual Operand *SelectBswap(IntrinsicopNode &node, Operand &opnd0, const BaseNode &parent) = 0;
380     virtual Operand *SelectExtractbits(ExtractbitsNode &node, Operand &opnd0, const BaseNode &parent) = 0;
381     virtual Operand *SelectDepositBits(DepositbitsNode &node, Operand &opnd0, Operand &opnd1,
382                                        const BaseNode &parent) = 0;
383     virtual Operand *SelectRegularBitFieldLoad(ExtractbitsNode &node, const BaseNode &parent) = 0;
384     virtual Operand *SelectLnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0;
385     virtual Operand *SelectNeg(UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0;
386     virtual Operand *SelectRecip(UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0;
387     virtual Operand *SelectSqrt(UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0;
388     virtual Operand *SelectCeil(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) = 0;
389     virtual Operand *SelectFloor(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) = 0;
390     virtual Operand *SelectRetype(TypeCvtNode &node, Operand &opnd0) = 0;
391     virtual Operand *SelectRound(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) = 0;
392     virtual Operand *SelectCvt(const BaseNode &parent, TypeCvtNode &node, Operand &opnd0) = 0;
393     virtual Operand *SelectTrunc(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent) = 0;
394     virtual Operand *SelectSelect(TernaryNode &node, Operand &cond, Operand &opnd0, Operand &opnd1,
395                                   const BaseNode &parent, bool hasCompare = false) = 0;
396     virtual Operand *SelectMalloc(UnaryNode &call, Operand &opnd0) = 0;
397     virtual RegOperand &SelectCopy(Operand &src, PrimType srcType, PrimType dstType) = 0;
398     virtual Operand *SelectAlloca(UnaryNode &call, Operand &opnd0) = 0;
399     virtual Operand *SelectGCMalloc(GCMallocNode &call) = 0;
400     virtual Operand *SelectJarrayMalloc(JarrayMallocNode &call, Operand &opnd0) = 0;
401     virtual void SelectRangeGoto(RangeGotoNode &rangeGotoNode, Operand &opnd0) = 0;
402     virtual Operand *SelectLazyLoad(Operand &opnd0, PrimType primType) = 0;
403     virtual Operand *SelectLazyLoadStatic(MIRSymbol &st, int64 offset, PrimType primType) = 0;
404     virtual Operand *SelectLoadArrayClassCache(MIRSymbol &st, int64 offset, PrimType primType) = 0;
405     virtual void GenerateYieldpoint(BB &bb) = 0;
406 
407     virtual Operand &GetOrCreateRflag() = 0;
408     virtual const Operand *GetRflag() const = 0;
409     virtual const Operand *GetFloatRflag() const = 0;
410     virtual const LabelOperand *GetLabelOperand(LabelIdx labIdx) const = 0;
411     virtual LabelOperand &GetOrCreateLabelOperand(LabelIdx labIdx) = 0;
412     virtual LabelOperand &GetOrCreateLabelOperand(BB &bb) = 0;
413     virtual RegOperand &CreateVirtualRegisterOperand(regno_t vRegNO) = 0;
414     virtual RegOperand &GetOrCreateVirtualRegisterOperand(regno_t vRegNO) = 0;
415     virtual RegOperand &GetOrCreateVirtualRegisterOperand(RegOperand &regOpnd) = 0;
416     virtual RegOperand &GetOrCreateFramePointerRegOperand() = 0;
417     virtual RegOperand &GetOrCreateStackBaseRegOperand() = 0;
418     virtual RegOperand *GetBaseReg(const SymbolAlloc &symAlloc) = 0;
419     virtual int32 GetBaseOffset(const SymbolAlloc &symbolAlloc) = 0;
420     virtual RegOperand &GetZeroOpnd(uint32 size) = 0;
421     virtual Operand &CreateCfiRegOperand(uint32 reg, uint32 size) = 0;
422     virtual Operand &GetTargetRetOperand(PrimType primType, int32 sReg) = 0;
423     virtual Operand &CreateImmOperand(PrimType primType, int64 val) = 0;
424     virtual void ReplaceOpndInInsn(RegOperand &regDest, RegOperand &regSrc, Insn &insn, regno_t destNO) = 0;
425     virtual void CleanupDeadMov(bool dump = false) = 0;
426     virtual void GetRealCallerSaveRegs(const Insn &insn, std::set<regno_t> &realCallerSave) = 0;
427     virtual MemOperand *GetOrCreatSpillMem(regno_t vrNum, uint32 bitSize) = 0;
428 
429     /* ra */
430     virtual void AddtoCalleeSaved(regno_t reg) = 0;
431 
432     virtual bool IsFrameReg(const RegOperand &opnd) const = 0;
IsSPOrFP(const RegOperand & opnd)433     virtual bool IsSPOrFP(const RegOperand &opnd) const
434     {
435         return false;
436     };
IsReturnReg(const RegOperand & opnd)437     virtual bool IsReturnReg(const RegOperand &opnd) const
438     {
439         return false;
440     };
IsSaveReg(const RegOperand & reg,MIRType & mirType,BECommon & cgBeCommon)441     virtual bool IsSaveReg(const RegOperand &reg, MIRType &mirType, BECommon &cgBeCommon)
442     {
443         return false;
444     }
445 
446     /* For Neon intrinsics */
447     virtual RegOperand *SelectVectorAddLong(PrimType rTy, Operand *o1, Operand *o2, PrimType oty, bool isLow) = 0;
448     virtual RegOperand *SelectVectorAddWiden(Operand *o1, PrimType oty1, Operand *o2, PrimType oty2, bool isLow) = 0;
449     virtual RegOperand *SelectVectorAbs(PrimType rType, Operand *o1) = 0;
450     virtual RegOperand *SelectVectorBinOp(PrimType rType, Operand *o1, PrimType oTyp1, Operand *o2, PrimType oTyp2,
451                                           Opcode opc) = 0;
452     virtual RegOperand *SelectVectorBitwiseOp(PrimType rType, Operand *o1, PrimType oty1, Operand *o2, PrimType oty2,
453                                               Opcode opc) = 0;
454     ;
455     virtual RegOperand *SelectVectorCompareZero(Operand *o1, PrimType oty1, Operand *o2, Opcode opc) = 0;
456     virtual RegOperand *SelectVectorCompare(Operand *o1, PrimType oty1, Operand *o2, PrimType oty2, Opcode opc) = 0;
457     virtual RegOperand *SelectVectorFromScalar(PrimType pType, Operand *opnd, PrimType sType) = 0;
458     virtual RegOperand *SelectVectorDup(PrimType rType, Operand *src, bool getLow) = 0;
459     virtual RegOperand *SelectVectorGetElement(PrimType rType, Operand *src, PrimType sType, int32 lane) = 0;
460     virtual RegOperand *SelectVectorAbsSubL(PrimType rType, Operand *o1, Operand *o2, PrimType oTy, bool isLow) = 0;
461     virtual RegOperand *SelectVectorMadd(Operand *o1, PrimType oTyp1, Operand *o2, PrimType oTyp2, Operand *o3,
462                                          PrimType oTyp3) = 0;
463     virtual RegOperand *SelectVectorMerge(PrimType rTyp, Operand *o1, Operand *o2, int32 iNum) = 0;
464     virtual RegOperand *SelectVectorMull(PrimType rType, Operand *o1, PrimType oTyp1, Operand *o2, PrimType oTyp2,
465                                          bool isLow) = 0;
466     virtual RegOperand *SelectVectorNarrow(PrimType rType, Operand *o1, PrimType otyp) = 0;
467     virtual RegOperand *SelectVectorNarrow2(PrimType rType, Operand *o1, PrimType oty1, Operand *o2, PrimType oty2) = 0;
468     virtual RegOperand *SelectVectorNeg(PrimType rType, Operand *o1) = 0;
469     virtual RegOperand *SelectVectorNot(PrimType rType, Operand *o1) = 0;
470 
471     virtual RegOperand *SelectVectorPairwiseAdalp(Operand *src1, PrimType sty1, Operand *src2, PrimType sty2) = 0;
472     virtual RegOperand *SelectVectorPairwiseAdd(PrimType rType, Operand *src, PrimType sType) = 0;
473     virtual RegOperand *SelectVectorReverse(PrimType rtype, Operand *src, PrimType stype, uint32 size) = 0;
474     virtual RegOperand *SelectVectorSetElement(Operand *eOp, PrimType eTyp, Operand *vOpd, PrimType vTyp,
475                                                int32 lane) = 0;
476     virtual RegOperand *SelectVectorShift(PrimType rType, Operand *o1, PrimType oty1, Operand *o2, PrimType oty2,
477                                           Opcode opc) = 0;
478     virtual RegOperand *SelectVectorShiftImm(PrimType rType, Operand *o1, Operand *imm, int32 sVal, Opcode opc) = 0;
479     virtual RegOperand *SelectVectorShiftRNarrow(PrimType rType, Operand *o1, PrimType oType, Operand *o2,
480                                                  bool isLow) = 0;
481     virtual RegOperand *SelectVectorSubWiden(PrimType resType, Operand *o1, PrimType otyp1, Operand *o2, PrimType otyp2,
482                                              bool isLow, bool isWide) = 0;
483     virtual RegOperand *SelectVectorSum(PrimType rtype, Operand *o1, PrimType oType) = 0;
484     virtual RegOperand *SelectVectorTableLookup(PrimType rType, Operand *o1, Operand *o2) = 0;
485     virtual RegOperand *SelectVectorWiden(PrimType rType, Operand *o1, PrimType otyp, bool isLow) = 0;
486 
HandleFuncCfg(CGCFG * cfg)487     virtual void HandleFuncCfg(CGCFG *cfg)
488     {
489         AddCommonExitBB();
490     }
491 
492     /* For ebo issue. */
GetTrueOpnd()493     virtual Operand *GetTrueOpnd()
494     {
495         return nullptr;
496     }
ClearUnreachableGotInfos(BB & bb)497     virtual void ClearUnreachableGotInfos(BB &bb)
498     {
499         (void)bb;
500     };
ClearUnreachableConstInfos(BB & bb)501     virtual void ClearUnreachableConstInfos(BB &bb)
502     {
503         (void)bb;
504     };
505     LabelIdx CreateLabel();
506 
GetVirtualRegisterOperand(regno_t vRegNO)507     RegOperand *GetVirtualRegisterOperand(regno_t vRegNO) const
508     {
509         std::unordered_map<regno_t, RegOperand *> &vRegOperandTable = VregInfo::vRegOperandTable;
510         auto it = vRegOperandTable.find(vRegNO);
511         return it == vRegOperandTable.end() ? nullptr : it->second;
512     }
513 
AddReferenceReg(regno_t regNO)514     void AddReferenceReg(regno_t regNO)
515     {
516         referenceVirtualRegs.insert(regNO);
517     }
518 
IsRegReference(regno_t regNO)519     bool IsRegReference(regno_t regNO) const
520     {
521         return referenceVirtualRegs.count(regNO) != 0;
522     }
523 
GetReferenceRegs()524     const MapleUnorderedSet<regno_t> &GetReferenceRegs() const
525     {
526         return referenceVirtualRegs;
527     }
528 
ReplaceRegReference(regno_t oldReg,regno_t newReg)529     void ReplaceRegReference(regno_t oldReg, regno_t newReg)
530     {
531         auto iter = referenceVirtualRegs.find(oldReg);
532         if (iter != referenceVirtualRegs.end()) {
533             referenceVirtualRegs.erase(iter);
534             referenceVirtualRegs.insert(newReg);
535         }
536     }
537 
AddReferenceStackSlot(int64 offset)538     void AddReferenceStackSlot(int64 offset)
539     {
540         referenceStackSlots.insert(offset);
541     }
542 
IsStackSlotReference(int64 offset)543     bool IsStackSlotReference(int64 offset) const
544     {
545         return referenceStackSlots.count(offset) != 0;
546     }
547 
GetReferenceStackSlots()548     const MapleSet<int64> &GetReferenceStackSlots() const
549     {
550         return referenceStackSlots;
551     }
552 
SetPregIdx2Opnd(size_t pregIdx,Operand & opnd)553     void SetPregIdx2Opnd(size_t pregIdx, Operand &opnd)
554     {
555         pregIdx2Opnd[pregIdx] = &opnd;
556     }
557 
GetOpndFromPregIdx(size_t pregIdx)558     Operand *GetOpndFromPregIdx(size_t pregIdx)
559     {
560         Operand *opnd = pregIdx2Opnd[pregIdx];
561         return opnd;
562     }
563 
CreateCfiImmOperand(int64 val,uint32 size)564     Operand &CreateCfiImmOperand(int64 val, uint32 size) const
565     {
566         return *memPool->New<cfi::ImmOperand>(val, size);
567     }
568 
CreateCfiStrOperand(const std::string & str)569     Operand &CreateCfiStrOperand(const std::string &str)
570     {
571         return *memPool->New<cfi::StrOperand>(str, *memPool);
572     }
573 
IsSpecialPseudoRegister(PregIdx spr)574     bool IsSpecialPseudoRegister(PregIdx spr) const
575     {
576         return spr < 0;
577     }
578 
NewVReg(RegType regType,uint32 size)579     regno_t NewVReg(RegType regType, uint32 size)
580     {
581         if (CGOptions::UseGeneralRegOnly()) {
582             CHECK_FATAL(regType != kRegTyFloat, "cannot use float | SIMD register with --general-reg-only");
583         }
584         return vReg.GetNextVregNO(regType, size);
585     }
586 
NewVRflag()587     virtual regno_t NewVRflag()
588     {
589         return 0;
590     }
591 
GetRegTyFromPrimTy(PrimType primType)592     RegType GetRegTyFromPrimTy(PrimType primType) const
593     {
594         switch (primType) {
595             case PTY_u1:
596             case PTY_i8:
597             case PTY_u8:
598             case PTY_i16:
599             case PTY_u16:
600             case PTY_i32:
601             case PTY_u32:
602             case PTY_i64:
603             case PTY_u64:
604             case PTY_a32:
605             case PTY_a64:
606             case PTY_ptr:
607             case PTY_ref:
608             case PTY_i128:
609             case PTY_u128:
610             case PTY_agg:
611                 return kRegTyInt;
612             case PTY_f32:
613             case PTY_f64:
614             case PTY_v2i32:
615             case PTY_v2u32:
616             case PTY_v2i64:
617             case PTY_v2u64:
618             case PTY_v2f32:
619             case PTY_v2f64:
620             case PTY_v4i16:
621             case PTY_v4u16:
622             case PTY_v4i32:
623             case PTY_v4u32:
624             case PTY_v4f32:
625             case PTY_v8i8:
626             case PTY_v8u8:
627             case PTY_v8i16:
628             case PTY_v8u16:
629             case PTY_v16i8:
630             case PTY_v16u8:
631                 return kRegTyFloat;
632             default:
633                 DEBUG_ASSERT(false, "Unexpected pty");
634                 return kRegTyUndef;
635         }
636     }
637 
638     /* return Register Type */
GetRegisterType(regno_t rNum)639     virtual RegType GetRegisterType(regno_t rNum) const
640     {
641         CHECK(rNum < vReg.VRegTableSize(), "index out of range in GetVRegSize");
642         return vReg.VRegTableGetType(rNum);
643     }
644 
645 #if defined(TARGX86_64) && TARGX86_64
GetMaxVReg()646     uint32 GetMaxVReg() const
647     {
648         return vReg.GetCount() + opndBuilder->GetCurrentVRegNum();
649     }
650 #else
GetMaxVReg()651     uint32 GetMaxVReg() const
652     {
653         return vReg.GetCount();
654     }
655 #endif
656 
GetSSAvRegCount()657     uint32 GetSSAvRegCount() const
658     {
659         return ssaVRegCount;
660     }
661 
SetSSAvRegCount(uint32 count)662     void SetSSAvRegCount(uint32 count)
663     {
664         ssaVRegCount = count;
665     }
666 
GetVRegSize(regno_t vregNum)667     uint32 GetVRegSize(regno_t vregNum)
668     {
669         CHECK(vregNum < vReg.VRegTableSize(), "index out of range in GetVRegSize");
670         return GetOrCreateVirtualRegisterOperand(vregNum).GetSize() / kBitsPerByte;
671     }
672 
673     MIRSymbol *GetRetRefSymbol(BaseNode &expr);
674 
675     void VerifyAllInsn();
676 
677     void GenerateCfiPrologEpilog();
678 
679     void PatchLongBranch();
680 
MaxCondBranchDistance()681     virtual uint32 MaxCondBranchDistance()
682     {
683         return INT_MAX;
684     }
685 
InsertJumpPad(Insn *)686     virtual void InsertJumpPad(Insn *)
687     {
688         return;
689     }
690 
GetLabelInInsn(Insn & insn)691     virtual LabelIdx GetLabelInInsn(Insn &insn)
692     {
693         return 0;
694     }
695 
CreateDbgImmOperand(int64 val)696     Operand *CreateDbgImmOperand(int64 val) const
697     {
698         return memPool->New<mpldbg::ImmOperand>(val);
699     }
700 
NumBBs()701     uint32 NumBBs() const
702     {
703         return bbCnt;
704     }
705 
706 #if DEBUG
GetLocalVarReplacedByPreg(PregIdx reg)707     StIdx GetLocalVarReplacedByPreg(PregIdx reg)
708     {
709         auto it = pregsToVarsMap->find(reg);
710         return it != pregsToVarsMap->end() ? it->second : StIdx();
711     }
712 #endif
713 
IncTotalNumberOfInstructions()714     void IncTotalNumberOfInstructions()
715     {
716         totalInsns++;
717     }
718 
GetTotalNumberOfInstructions()719     uint32 GetTotalNumberOfInstructions() const
720     {
721         return totalInsns + insnBuilder->GetCreatedInsnNum();
722     }
723 
GetStructCopySize()724     int32 GetStructCopySize() const
725     {
726         return structCopySize;
727     }
728 
GetMaxParamStackSize()729     int32 GetMaxParamStackSize() const
730     {
731         return maxParamStackSize;
732     }
733 
734     virtual void ProcessLazyBinding() = 0;
735 
736     /* Debugging support */
SetDebugInfo(DebugInfo * dbgInfo)737     void SetDebugInfo(DebugInfo *dbgInfo)
738     {
739         debugInfo = dbgInfo;
740     }
741 
742     void AddDIESymbolLocation(const MIRSymbol *sym, SymbolAlloc *loc, bool isParam);
743 
DBGFixCallFrameLocationOffsets()744     virtual void DBGFixCallFrameLocationOffsets() {};
745 
746     /* Get And Set private members */
GetCG()747     CG *GetCG()
748     {
749         return cg;
750     }
751 
GetCG()752     const CG *GetCG() const
753     {
754         return cg;
755     }
756 
GetMirModule()757     MIRModule &GetMirModule()
758     {
759         return mirModule;
760     }
761 
GetMirModule()762     const MIRModule &GetMirModule() const
763     {
764         return mirModule;
765     }
766 
767     template <typename T>
NewMirConst(T & mirConst)768     MIRConst *NewMirConst(T &mirConst)
769     {
770         MIRConst *newConst = mirModule.GetMemPool()->New<T>(mirConst.GetValue(), mirConst.GetType());
771         return newConst;
772     }
773 
GetMIRSrcFileEndLineNum()774     uint32 GetMIRSrcFileEndLineNum() const
775     {
776         auto &srcFileInfo = mirModule.GetSrcFileInfo();
777         if (!srcFileInfo.empty()) {
778             return srcFileInfo.back().second;
779         } else {
780             return 0;
781         }
782     }
783 
GetFunction()784     MIRFunction &GetFunction()
785     {
786         return func;
787     }
788 
GetFunction()789     const MIRFunction &GetFunction() const
790     {
791         return func;
792     }
793 
GetEHFunc()794     EHFunc *GetEHFunc()
795     {
796         return ehFunc;
797     }
798 
GetEHFunc()799     const EHFunc *GetEHFunc() const
800     {
801         return ehFunc;
802     }
803 
SetEHFunc(EHFunc & ehFunction)804     void SetEHFunc(EHFunc &ehFunction)
805     {
806         ehFunc = &ehFunction;
807     }
808 
GetLabelIdx()809     uint32 GetLabelIdx() const
810     {
811         return labelIdx;
812     }
813 
SetLabelIdx(uint32 idx)814     void SetLabelIdx(uint32 idx)
815     {
816         labelIdx = idx;
817     }
818 
GetStartLabel()819     LabelNode *GetStartLabel()
820     {
821         return startLabel;
822     }
823 
GetStartLabel()824     const LabelNode *GetStartLabel() const
825     {
826         return startLabel;
827     }
828 
SetStartLabel(LabelNode & label)829     void SetStartLabel(LabelNode &label)
830     {
831         startLabel = &label;
832     }
833 
GetEndLabel()834     LabelNode *GetEndLabel()
835     {
836         return endLabel;
837     }
838 
GetEndLabel()839     const LabelNode *GetEndLabel() const
840     {
841         return endLabel;
842     }
843 
SetEndLabel(LabelNode & label)844     void SetEndLabel(LabelNode &label)
845     {
846         endLabel = &label;
847     }
848 
GetCleanupLabel()849     LabelNode *GetCleanupLabel()
850     {
851         return cleanupLabel;
852     }
853 
GetCleanupLabel()854     const LabelNode *GetCleanupLabel() const
855     {
856         return cleanupLabel;
857     }
858 
SetCleanupLabel(LabelNode & node)859     void SetCleanupLabel(LabelNode &node)
860     {
861         cleanupLabel = &node;
862     }
863 
GetReturnLabel()864     const LabelNode *GetReturnLabel() const
865     {
866         return returnLabel;
867     }
868 
SetReturnLabel(LabelNode & label)869     void SetReturnLabel(LabelNode &label)
870     {
871         returnLabel = &label;
872     }
873 
GetFirstBB()874     BB *GetFirstBB()
875     {
876         return firstBB;
877     }
878 
GetFirstBB()879     const BB *GetFirstBB() const
880     {
881         return firstBB;
882     }
883 
SetFirstBB(BB & bb)884     void SetFirstBB(BB &bb)
885     {
886         firstBB = &bb;
887     }
888 
GetCleanupBB()889     BB *GetCleanupBB()
890     {
891         return cleanupBB;
892     }
893 
GetCleanupBB()894     const BB *GetCleanupBB() const
895     {
896         return cleanupBB;
897     }
898 
SetCleanupBB(BB & bb)899     void SetCleanupBB(BB &bb)
900     {
901         cleanupBB = &bb;
902     }
903 
GetCleanupEntryBB()904     const BB *GetCleanupEntryBB() const
905     {
906         return cleanupEntryBB;
907     }
908 
SetCleanupEntryBB(BB & bb)909     void SetCleanupEntryBB(BB &bb)
910     {
911         cleanupEntryBB = &bb;
912     }
913 
GetLastBB()914     BB *GetLastBB()
915     {
916         return lastBB;
917     }
918 
GetLastBB()919     const BB *GetLastBB() const
920     {
921         return lastBB;
922     }
923 
SetLastBB(BB & bb)924     void SetLastBB(BB &bb)
925     {
926         lastBB = &bb;
927     }
928 
GetCurBB()929     BB *GetCurBB()
930     {
931         return curBB;
932     }
933 
GetCurBB()934     const BB *GetCurBB() const
935     {
936         return curBB;
937     }
938 
SetCurBB(BB & bb)939     void SetCurBB(BB &bb)
940     {
941         curBB = &bb;
942     }
943 
GetDummyBB()944     BB *GetDummyBB()
945     {
946         return dummyBB;
947     }
948 
GetDummyBB()949     const BB *GetDummyBB() const
950     {
951         return dummyBB;
952     }
953 
GetCommonExitBB()954     BB *GetCommonExitBB()
955     {
956         return commonExitBB;
957     }
958 
GetCommonEntryBB()959     BB *GetCommonEntryBB()
960     {
961         DEBUG_ASSERT(bbVec[0]->GetId() == 0 && bbVec[0] != firstBB, "there is no commonEntryBB");
962         return bbVec[0];
963     }
964 
GetFirstCGGenLabelIdx()965     LabelIdx GetFirstCGGenLabelIdx() const
966     {
967         return firstCGGenLabelIdx;
968     }
969 
GetExitBBsVec()970     MapleVector<BB *> &GetExitBBsVec()
971     {
972         return exitBBVec;
973     }
974 
GetExitBBsVec()975     const MapleVector<BB *> GetExitBBsVec() const
976     {
977         return exitBBVec;
978     }
979 
ExitBBsVecSize()980     size_t ExitBBsVecSize() const
981     {
982         return exitBBVec.size();
983     }
984 
IsExitBBsVecEmpty()985     bool IsExitBBsVecEmpty() const
986     {
987         return exitBBVec.empty();
988     }
989 
EraseExitBBsVec(MapleVector<BB * >::iterator it)990     void EraseExitBBsVec(MapleVector<BB *>::iterator it)
991     {
992         exitBBVec.erase(it);
993     }
994 
PushBackExitBBsVec(BB & bb)995     void PushBackExitBBsVec(BB &bb)
996     {
997         exitBBVec.emplace_back(&bb);
998     }
999 
ClearExitBBsVec()1000     void ClearExitBBsVec()
1001     {
1002         exitBBVec.clear();
1003     }
1004 
IsExtendReg(regno_t vregNum)1005     bool IsExtendReg(regno_t vregNum)
1006     {
1007         return extendSet.find(vregNum) != extendSet.end();
1008     }
1009 
InsertExtendSet(regno_t vregNum)1010     void InsertExtendSet(regno_t vregNum)
1011     {
1012         (void)extendSet.insert(vregNum);
1013     }
1014 
RemoveFromExtendSet(regno_t vregNum)1015     void RemoveFromExtendSet(regno_t vregNum)
1016     {
1017         (void)extendSet.erase(vregNum);
1018     }
1019 
IsExitBB(const BB & currentBB)1020     bool IsExitBB(const BB &currentBB)
1021     {
1022         for (BB *exitBB : exitBBVec) {
1023             if (exitBB == &currentBB) {
1024                 return true;
1025             }
1026         }
1027         return false;
1028     }
1029 
GetExitBB(int32 index)1030     BB *GetExitBB(int32 index)
1031     {
1032         return exitBBVec.at(index);
1033     }
1034 
GetExitBB(int32 index)1035     const BB *GetExitBB(int32 index) const
1036     {
1037         return exitBBVec.at(index);
1038     }
1039 
EraseNoReturnCallBB(MapleVector<BB * >::iterator it)1040     MapleVector<BB *>::iterator EraseNoReturnCallBB(MapleVector<BB *>::iterator it)
1041     {
1042         return noReturnCallBBVec.erase(it);
1043     }
1044 
PushBackNoReturnCallBBsVec(BB & bb)1045     void PushBackNoReturnCallBBsVec(BB &bb)
1046     {
1047         noReturnCallBBVec.emplace_back(&bb);
1048     }
1049 
GetNoRetCallBBVec()1050     MapleVector<BB *> &GetNoRetCallBBVec()
1051     {
1052         return noReturnCallBBVec;
1053     }
1054 
SetLab2BBMap(int32 index,BB & bb)1055     void SetLab2BBMap(int32 index, BB &bb)
1056     {
1057         lab2BBMap[index] = &bb;
1058     }
1059 
GetBBFromLab2BBMap(uint32 index)1060     BB *GetBBFromLab2BBMap(uint32 index)
1061     {
1062         return lab2BBMap[index];
1063     }
1064 
GetLab2BBMap()1065     MapleUnorderedMap<LabelIdx, BB *> &GetLab2BBMap()
1066     {
1067         return lab2BBMap;
1068     }
1069 
1070     void DumpCFGToDot(const std::string &fileNamePrefix);
1071 
GetBecommon()1072     BECommon &GetBecommon()
1073     {
1074         return beCommon;
1075     }
1076 
GetBecommon()1077     const BECommon GetBecommon() const
1078     {
1079         return beCommon;
1080     }
1081 
GetMemlayout()1082     MemLayout *GetMemlayout()
1083     {
1084         return memLayout;
1085     }
1086 
GetMemlayout()1087     const MemLayout *GetMemlayout() const
1088     {
1089         return memLayout;
1090     }
1091 
SetMemlayout(MemLayout & layout)1092     void SetMemlayout(MemLayout &layout)
1093     {
1094         memLayout = &layout;
1095     }
1096 
GetTargetRegInfo()1097     RegisterInfo *GetTargetRegInfo()
1098     {
1099         return targetRegInfo;
1100     }
1101 
SetTargetRegInfo(RegisterInfo & regInfo)1102     void SetTargetRegInfo(RegisterInfo &regInfo)
1103     {
1104         targetRegInfo = &regInfo;
1105     }
1106 
GetMemoryPool()1107     MemPool *GetMemoryPool()
1108     {
1109         return memPool;
1110     }
1111 
GetMemoryPool()1112     const MemPool *GetMemoryPool() const
1113     {
1114         return memPool;
1115     }
1116 
GetStackMemPool()1117     StackMemPool &GetStackMemPool()
1118     {
1119         return stackMp;
1120     }
1121 
GetFuncScopeAllocator()1122     MapleAllocator *GetFuncScopeAllocator()
1123     {
1124         return funcScopeAllocator;
1125     }
1126 
GetFuncScopeAllocator()1127     const MapleAllocator *GetFuncScopeAllocator() const
1128     {
1129         return funcScopeAllocator;
1130     }
1131 
GetEmitStVec()1132     const MapleMap<uint32, MIRSymbol *> GetEmitStVec() const
1133     {
1134         return emitStVec;
1135     }
1136 
GetEmitSt(uint32 id)1137     MIRSymbol *GetEmitSt(uint32 id)
1138     {
1139         return emitStVec[id];
1140     }
1141 
AddEmitSt(uint32 id,MIRSymbol & symbol)1142     void AddEmitSt(uint32 id, MIRSymbol &symbol)
1143     {
1144         CHECK_FATAL(symbol.GetKonst()->GetKind() == kConstAggConst, "not a kConstAggConst");
1145         MIRAggConst *arrayConst = safe_cast<MIRAggConst>(symbol.GetKonst());
1146         for (size_t i = 0; i < arrayConst->GetConstVec().size(); ++i) {
1147             CHECK_FATAL(arrayConst->GetConstVecItem(i)->GetKind() == kConstLblConst, "not a kConstLblConst");
1148             MIRLblConst *lblConst = safe_cast<MIRLblConst>(arrayConst->GetConstVecItem(i));
1149             ++switchLabelCnt[lblConst->GetValue()];
1150         }
1151         emitStVec[id] = &symbol;
1152     }
1153 
UpdateEmitSt(BB & bb,LabelIdx oldLabelIdx,LabelIdx newLabelIdx)1154     void UpdateEmitSt(BB &bb, LabelIdx oldLabelIdx, LabelIdx newLabelIdx)
1155     {
1156         MIRSymbol *st = GetEmitSt(bb.GetId());
1157         MIRAggConst *arrayConst = safe_cast<MIRAggConst>(st->GetKonst());
1158         MIRType *etype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_a64));
1159         MIRConst *mirConst = GetMemoryPool()->New<MIRLblConst>(newLabelIdx, GetFunction().GetPuidx(), *etype);
1160         DEBUG_ASSERT(arrayConst != nullptr, "nullptr check");
1161         for (size_t i = 0; i < arrayConst->GetConstVec().size(); ++i) {
1162             CHECK_FATAL(arrayConst->GetConstVecItem(i)->GetKind() == kConstLblConst, "not a kConstLblConst");
1163             MIRLblConst *lblConst = safe_cast<MIRLblConst>(arrayConst->GetConstVecItem(i));
1164             DEBUG_ASSERT(lblConst != nullptr, "nullptr check");
1165             if (oldLabelIdx == lblConst->GetValue()) {
1166                 arrayConst->SetConstVecItem(i, *mirConst);
1167                 ++switchLabelCnt[newLabelIdx];
1168 
1169                 CHECK_FATAL(switchLabelCnt[oldLabelIdx] > 0, "error labelIdx");
1170                 --switchLabelCnt[oldLabelIdx];
1171                 if (switchLabelCnt[oldLabelIdx] == 0) {
1172                     switchLabelCnt.erase(oldLabelIdx);
1173                 }
1174             }
1175         }
1176     }
1177 
DeleteEmitSt(uint32 id)1178     void DeleteEmitSt(uint32 id)
1179     {
1180         MIRSymbol &symbol = *emitStVec[id];
1181         CHECK_FATAL(symbol.GetKonst()->GetKind() == kConstAggConst, "not a kConstAggConst");
1182         MIRAggConst *arrayConst = safe_cast<MIRAggConst>(symbol.GetKonst());
1183         for (size_t i = 0; i < arrayConst->GetConstVec().size(); ++i) {
1184             CHECK_FATAL(arrayConst->GetConstVecItem(i)->GetKind() == kConstLblConst, "not a kConstLblConst");
1185             MIRLblConst *lblConst = safe_cast<MIRLblConst>(arrayConst->GetConstVecItem(i));
1186 
1187             LabelIdx labelIdx = lblConst->GetValue();
1188             CHECK_FATAL(switchLabelCnt[labelIdx] > 0, "error labelIdx");
1189             --switchLabelCnt[labelIdx];
1190             if (switchLabelCnt[labelIdx] == 0) {
1191                 switchLabelCnt.erase(labelIdx);
1192             }
1193         }
1194         (void)emitStVec.erase(id);
1195     }
1196 
InSwitchTable(LabelIdx label)1197     bool InSwitchTable(LabelIdx label) const
1198     {
1199         if (switchLabelCnt.empty()) {
1200             return false;
1201         }
1202         return (switchLabelCnt.find(label) != switchLabelCnt.end());
1203     }
1204 
GetLocalSymLabelIndex(const MIRSymbol & symbol)1205     LabelIdx GetLocalSymLabelIndex(const MIRSymbol &symbol) const
1206     {
1207         auto itr = funcLocalSym2Label.find(&symbol);
1208         CHECK_FATAL(itr != funcLocalSym2Label.end(), "not assign labelIndex to sym");
1209         return itr->second;
1210     }
1211 
SetLocalSymLabelIndex(const MIRSymbol & mirSymbol,LabelIdx labelIndex)1212     void SetLocalSymLabelIndex(const MIRSymbol &mirSymbol, LabelIdx labelIndex)
1213     {
1214         funcLocalSym2Label[&mirSymbol] = labelIndex;
1215     }
1216 
GetLmbcParamVec()1217     MapleVector<LmbcFormalParamInfo *> &GetLmbcParamVec()
1218     {
1219         return lmbcParamVec;
1220     }
1221 
IncLmbcArgsInRegs(RegType ty)1222     void IncLmbcArgsInRegs(RegType ty)
1223     {
1224         if (ty == kRegTyInt) {
1225             lmbcIntArgs++;
1226         } else {
1227             lmbcFpArgs++;
1228         }
1229     }
1230 
GetLmbcArgsInRegs(RegType ty)1231     int16 GetLmbcArgsInRegs(RegType ty) const
1232     {
1233         return ty == kRegTyInt ? lmbcIntArgs : lmbcFpArgs;
1234     }
1235 
ResetLmbcArgsInRegs()1236     void ResetLmbcArgsInRegs()
1237     {
1238         lmbcIntArgs = 0;
1239         lmbcFpArgs = 0;
1240     }
1241 
IncLmbcTotalArgs()1242     void IncLmbcTotalArgs()
1243     {
1244         lmbcTotalArgs++;
1245     }
1246 
GetLmbcTotalArgs()1247     uint32 GetLmbcTotalArgs() const
1248     {
1249         return lmbcTotalArgs;
1250     }
1251 
ResetLmbcTotalArgs()1252     void ResetLmbcTotalArgs()
1253     {
1254         lmbcTotalArgs = 0;
1255     }
1256 
SetSpSaveReg(regno_t reg)1257     void SetSpSaveReg(regno_t reg)
1258     {
1259         spSaveReg = reg;
1260     }
1261 
GetSpSaveReg()1262     regno_t GetSpSaveReg() const
1263     {
1264         return spSaveReg;
1265     }
1266 
GetAllBBs()1267     MapleVector<BB *> &GetAllBBs()
1268     {
1269         return bbVec;
1270     }
1271 
GetAllBBSize()1272     std::size_t GetAllBBSize() const
1273     {
1274         return bbVec.size();
1275     }
1276 
GetBBFromID(uint32 id)1277     BB *GetBBFromID(uint32 id)
1278     {
1279         return bbVec[id];
1280     }
ClearBBInVec(uint32 id)1281     void ClearBBInVec(uint32 id)
1282     {
1283         bbVec[id] = nullptr;
1284     }
1285 
1286 #if TARGARM32
GetSortedBBs()1287     MapleVector<BB *> &GetSortedBBs()
1288     {
1289         return sortedBBs;
1290     }
1291 
GetSortedBBs()1292     const MapleVector<BB *> &GetSortedBBs() const
1293     {
1294         return sortedBBs;
1295     }
1296 
SetSortedBBs(const MapleVector<BB * > & bbVec)1297     void SetSortedBBs(const MapleVector<BB *> &bbVec)
1298     {
1299         sortedBBs = bbVec;
1300     }
1301 
GetLrVec()1302     MapleVector<LiveRange *> &GetLrVec()
1303     {
1304         return lrVec;
1305     }
1306 
GetLrVec()1307     const MapleVector<LiveRange *> &GetLrVec() const
1308     {
1309         return lrVec;
1310     }
1311 
SetLrVec(const MapleVector<LiveRange * > & newLrVec)1312     void SetLrVec(const MapleVector<LiveRange *> &newLrVec)
1313     {
1314         lrVec = newLrVec;
1315     }
1316 #endif /* TARGARM32 */
1317 
GetTheCFG()1318     CGCFG *GetTheCFG()
1319     {
1320         return theCFG;
1321     }
1322 
SetTheCFG(CGCFG * cfg)1323     void SetTheCFG(CGCFG *cfg)
1324     {
1325         theCFG = cfg;
1326     }
1327 
GetTheCFG()1328     const CGCFG *GetTheCFG() const
1329     {
1330         return theCFG;
1331     }
1332 
GetVirtualRegNOFromPseudoRegIdx(PregIdx idx)1333     regno_t GetVirtualRegNOFromPseudoRegIdx(PregIdx idx) const
1334     {
1335         return regno_t(idx + firstMapleIrVRegNO);
1336     }
1337 
GetHasProEpilogue()1338     bool GetHasProEpilogue() const
1339     {
1340         return hasProEpilogue;
1341     }
1342 
SetHasProEpilogue(bool state)1343     void SetHasProEpilogue(bool state)
1344     {
1345         hasProEpilogue = state;
1346     }
1347 
GetDbgCallFrameOffset()1348     int32 GetDbgCallFrameOffset() const
1349     {
1350         return dbgCallFrameOffset;
1351     }
1352 
SetDbgCallFrameOffset(int32 val)1353     void SetDbgCallFrameOffset(int32 val)
1354     {
1355         dbgCallFrameOffset = val;
1356     }
1357 
CreateNewBB()1358     BB *CreateNewBB()
1359     {
1360         BB *bb = memPool->New<BB>(bbCnt++, *funcScopeAllocator);
1361         bbVec.emplace_back(bb);
1362         return bb;
1363     }
1364 
CreateNewBB(bool unreachable,BB::BBKind kind,uint32 frequency)1365     BB *CreateNewBB(bool unreachable, BB::BBKind kind, uint32 frequency)
1366     {
1367         BB *newBB = CreateNewBB();
1368         newBB->SetKind(kind);
1369         newBB->SetUnreachable(unreachable);
1370         newBB->SetFrequency(frequency);
1371         return newBB;
1372     }
1373 
CreateNewBB(LabelIdx label,bool unreachable,BB::BBKind kind,uint32 frequency)1374     BB *CreateNewBB(LabelIdx label, bool unreachable, BB::BBKind kind, uint32 frequency)
1375     {
1376         BB *newBB = CreateNewBB(unreachable, kind, frequency);
1377         newBB->AddLabel(label);
1378         SetLab2BBMap(label, *newBB);
1379         return newBB;
1380     }
1381 
UpdateFrequency(const StmtNode & stmt)1382     void UpdateFrequency(const StmtNode &stmt)
1383     {
1384         bool withFreqInfo = func.HasFreqMap() && !func.GetLastFreqMap().empty();
1385         if (!withFreqInfo) {
1386             return;
1387         }
1388         auto it = func.GetLastFreqMap().find(stmt.GetStmtID());
1389         if (it != func.GetLastFreqMap().end()) {
1390             frequency = it->second;
1391         }
1392     }
1393 
StartNewBBImpl(bool stmtIsCurBBLastStmt,StmtNode & stmt)1394     BB *StartNewBBImpl(bool stmtIsCurBBLastStmt, StmtNode &stmt)
1395     {
1396         BB *newBB = CreateNewBB();
1397         DEBUG_ASSERT(newBB != nullptr, "newBB should not be nullptr");
1398         if (stmtIsCurBBLastStmt) {
1399             DEBUG_ASSERT(curBB != nullptr, "curBB should not be nullptr");
1400             curBB->SetLastStmt(stmt);
1401             curBB->AppendBB(*newBB);
1402             newBB->SetFirstStmt(*stmt.GetNext());
1403         } else {
1404             newBB->SetFirstStmt(stmt);
1405             if (curBB != nullptr) {
1406                 if (stmt.GetPrev() != nullptr) {
1407                     DEBUG_ASSERT(stmt.GetPrev()->GetNext() == &stmt, " the next of stmt's prev should be stmt self");
1408                 }
1409                 curBB->SetLastStmt(*stmt.GetPrev());
1410                 curBB->AppendBB(*newBB);
1411             }
1412         }
1413         return newBB;
1414     }
1415 
StartNewBB(StmtNode & stmt)1416     BB *StartNewBB(StmtNode &stmt)
1417     {
1418         BB *bb = curBB;
1419         if (stmt.GetNext() != nullptr && stmt.GetNext()->GetOpCode() != OP_label) {
1420             bb = StartNewBBImpl(true, stmt);
1421         }
1422         return bb;
1423     }
1424 
SetCurBBKind(BB::BBKind bbKind)1425     void SetCurBBKind(BB::BBKind bbKind) const
1426     {
1427         curBB->SetKind(bbKind);
1428     }
1429 
SetVolStore(bool val)1430     void SetVolStore(bool val)
1431     {
1432         isVolStore = val;
1433     }
1434 
SetVolReleaseInsn(Insn * insn)1435     void SetVolReleaseInsn(Insn *insn)
1436     {
1437         volReleaseInsn = insn;
1438     }
1439 
IsAfterRegAlloc()1440     bool IsAfterRegAlloc() const
1441     {
1442         return isAfterRegAlloc;
1443     }
1444 
SetIsAfterRegAlloc()1445     void SetIsAfterRegAlloc()
1446     {
1447         isAfterRegAlloc = true;
1448     }
1449 
GetShortFuncName()1450     const MapleString &GetShortFuncName() const
1451     {
1452         return shortFuncName;
1453     }
1454 
GetLSymSize()1455     size_t GetLSymSize() const
1456     {
1457         return lSymSize;
1458     }
1459 
HasTakenLabel()1460     bool HasTakenLabel() const
1461     {
1462         return hasTakenLabel;
1463     }
1464 
SetHasTakenLabel()1465     void SetHasTakenLabel()
1466     {
1467         hasTakenLabel = true;
1468     }
1469 
HasLaidOutByPgoUse()1470     bool HasLaidOutByPgoUse() const
1471     {
1472         return hasLaidOutByPgoUse;
1473     }
1474 
SetHasLaidOutByPgoUse()1475     void SetHasLaidOutByPgoUse()
1476     {
1477         hasLaidOutByPgoUse = true;
1478     }
1479 
1480     virtual InsnVisitor *NewInsnModifier() = 0;
1481 
GenCfi()1482     bool GenCfi() const
1483     {
1484         return (mirModule.GetSrcLang() != kSrcLangC) || mirModule.IsWithDbgInfo();
1485     }
1486 
GetDbgCallFrameLocations(bool isParam)1487     MapleVector<DBGExprLoc *> &GetDbgCallFrameLocations(bool isParam)
1488     {
1489         return isParam ? dbgParamCallFrameLocations : dbgLocalCallFrameLocations;
1490     }
1491 
HasAsm()1492     bool HasAsm() const
1493     {
1494         return hasAsm;
1495     }
1496 
GetUniqueID()1497     uint32 GetUniqueID() const
1498     {
1499         return func.GetPuidx();
1500     }
SetUseFP(bool canUseFP)1501     void SetUseFP(bool canUseFP)
1502     {
1503         useFP = canUseFP;
1504     }
1505 
UseFP()1506     bool UseFP() const
1507     {
1508         return useFP;
1509     }
1510 
UnsetSeenFP()1511     void UnsetSeenFP()
1512     {
1513         seenFP = false;
1514     }
1515 
SeenFP()1516     bool SeenFP() const
1517     {
1518         return seenFP;
1519     }
1520 
1521     void UpdateAllRegisterVregMapping(MapleMap<regno_t, PregIdx> &newMap);
1522 
RegisterVregMapping(regno_t vRegNum,PregIdx pidx)1523     void RegisterVregMapping(regno_t vRegNum, PregIdx pidx)
1524     {
1525         vregsToPregsMap[vRegNum] = pidx;
1526     }
1527 
GetStackMapInsns()1528     const MapleList<Insn *> &GetStackMapInsns() const
1529     {
1530         return stackMapInsns;
1531     }
1532 
AppendStackMapInsn(Insn & insn)1533     void AppendStackMapInsn(Insn &insn)
1534     {
1535         insn.InitStackMapInfo();
1536         stackMapInsns.emplace_back(&insn);
1537     }
1538 
IsStackMapComputed()1539     bool IsStackMapComputed()
1540     {
1541         return isStackMapComputed;
1542     }
1543 
SetStackMapComputed()1544     void SetStackMapComputed()
1545     {
1546         isStackMapComputed = true;
1547     }
1548 
EraseUnreachableStackMapInsns()1549     void EraseUnreachableStackMapInsns()
1550     {
1551         for (auto it = stackMapInsns.begin(); it != stackMapInsns.end();) {
1552             if ((*it)->GetBB()->IsUnreachable()) {
1553                 it = stackMapInsns.erase(it);
1554             } else {
1555                 ++it;
1556             }
1557         }
1558     }
1559 
GetFirstMapleIrVRegNO()1560     uint32 GetFirstMapleIrVRegNO() const
1561     {
1562         return firstMapleIrVRegNO;
1563     }
1564 
SetHasAsm()1565     void SetHasAsm()
1566     {
1567         hasAsm = true;
1568     }
1569 
SetStackProtectInfo(StackProtectKind kind)1570     void SetStackProtectInfo(StackProtectKind kind)
1571     {
1572         stackProtectInfo |= kind;
1573     }
1574 
GetStackProtectInfo()1575     uint8 GetStackProtectInfo() const
1576     {
1577         return stackProtectInfo;
1578     }
1579 
SetNeedStackProtect(bool val)1580     void SetNeedStackProtect(bool val)
1581     {
1582         needStackProtect = val;
1583     }
1584 
GetNeedStackProtect()1585     bool GetNeedStackProtect() const
1586     {
1587         return needStackProtect;
1588     }
1589 
GetCurCallConvKind()1590     CallConvKind GetCurCallConvKind() const
1591     {
1592         return callingConventionKind;
1593     }
1594 
SetFuncEmitInfo(FuncEmitInfo * fnInfo)1595     void SetFuncEmitInfo(FuncEmitInfo *fnInfo)
1596     {
1597         funcEmitInfo = fnInfo;
1598     }
1599 
GetFuncEmitInfo()1600     FuncEmitInfo *GetFuncEmitInfo()
1601     {
1602         return funcEmitInfo;
1603     }
1604 
SetExitBBLost(bool val)1605     void SetExitBBLost(bool val)
1606     {
1607         exitBBLost = val;
1608     }
GetExitBBLost()1609     bool GetExitBBLost()
1610     {
1611         return exitBBLost;
1612     }
1613 
SetHasBuiltCfg(bool hasBuilt)1614     void SetHasBuiltCfg(bool hasBuilt)
1615     {
1616         hasBuiltCfg = hasBuilt;
1617     }
1618 
HasBuiltCfg()1619     bool HasBuiltCfg() const
1620     {
1621         return hasBuiltCfg;
1622     }
1623 
GetWithSrc()1624     bool GetWithSrc() const
1625     {
1626         return withSrc;
1627     }
1628 protected:
1629     uint32 firstMapleIrVRegNO = 200; /* positioned after physical regs */
1630     uint32 firstNonPregVRegNO;
1631     VregInfo vReg;           /* for assigning a number for each CG virtual register */
1632     uint32 ssaVRegCount = 0; /* vreg  count in ssa */
1633     size_t lSymSize;         /* size of local symbol table imported */
1634     MapleVector<BB *> bbVec;
1635     MapleUnorderedSet<regno_t> referenceVirtualRegs;
1636     MapleSet<int64> referenceStackSlots;
1637     MapleVector<Operand *> pregIdx2Opnd;
1638     MapleUnorderedMap<PregIdx, MemOperand *> pRegSpillMemOperands;
1639     MapleUnorderedMap<regno_t, MemOperand *> spillRegMemOperands;
1640     MapleUnorderedMap<uint32, SpillMemOperandSet *> reuseSpillLocMem;
1641     LabelIdx firstCGGenLabelIdx;
1642     MapleMap<LabelIdx, uint64> labelMap;
1643 #if DEBUG
1644     MapleMap<PregIdx, StIdx> *pregsToVarsMap = nullptr;
1645 #endif
1646     MapleMap<regno_t, PregIdx> vregsToPregsMap;
1647     MapleList<Insn *> stackMapInsns;
1648     uint32 totalInsns = 0;
1649     int32 structCopySize;
1650     int32 maxParamStackSize;
1651     static constexpr int kRegIncrStepLen = 80; /* reg number increate step length */
1652 
1653     bool hasVLAOrAlloca = false;
1654     bool hasAlloca = false;
1655     bool hasProEpilogue = false;
1656     bool isVolLoad = false;
1657     bool isVolStore = false;
1658     bool isAfterRegAlloc = false;
1659     bool isAggParamInReg = false;
1660     bool hasTakenLabel = false;
1661     bool hasLaidOutByPgoUse = false;
1662     bool withSrc = true;
1663     uint32 frequency = 0;
1664     DebugInfo *debugInfo = nullptr; /* debugging info */
1665     MapleVector<DBGExprLoc *> dbgParamCallFrameLocations;
1666     MapleVector<DBGExprLoc *> dbgLocalCallFrameLocations;
1667     RegOperand *aggParamReg = nullptr;
1668     ReachingDefinition *reachingDef = nullptr;
1669 
1670     int32 dbgCallFrameOffset = 0;
1671     CG *cg;
1672     MIRModule &mirModule;
1673     MemPool *memPool;
1674     StackMemPool &stackMp;
1675 
GetPseudoRegIdxFromVirtualRegNO(const regno_t vRegNO)1676     PregIdx GetPseudoRegIdxFromVirtualRegNO(const regno_t vRegNO) const
1677     {
1678         if (IsVRegNOForPseudoRegister(vRegNO)) {
1679             return PregIdx(vRegNO - firstMapleIrVRegNO);
1680         }
1681         return VRegNOToPRegIdx(vRegNO);
1682     }
1683 
IsVRegNOForPseudoRegister(regno_t vRegNum)1684     bool IsVRegNOForPseudoRegister(regno_t vRegNum) const
1685     {
1686         /* 0 is not allowed for preg index */
1687         uint32 n = static_cast<uint32>(vRegNum);
1688         return (firstMapleIrVRegNO < n && n < firstNonPregVRegNO);
1689     }
1690 
VRegNOToPRegIdx(regno_t vRegNum)1691     PregIdx VRegNOToPRegIdx(regno_t vRegNum) const
1692     {
1693         auto it = vregsToPregsMap.find(vRegNum);
1694         if (it == vregsToPregsMap.end()) {
1695             return PregIdx(-1);
1696         }
1697         return it->second;
1698     }
1699 
GetVirtualRegNodeFromPseudoRegIdx(PregIdx idx)1700     VirtualRegNode &GetVirtualRegNodeFromPseudoRegIdx(PregIdx idx)
1701     {
1702         return vReg.VRegTableElementGet(GetVirtualRegNOFromPseudoRegIdx(idx));
1703     }
1704 
GetTypeFromPseudoRegIdx(PregIdx idx)1705     PrimType GetTypeFromPseudoRegIdx(PregIdx idx)
1706     {
1707         VirtualRegNode &vRegNode = GetVirtualRegNodeFromPseudoRegIdx(idx);
1708         RegType regType = vRegNode.GetType();
1709         DEBUG_ASSERT(regType == kRegTyInt || regType == kRegTyFloat, "");
1710         uint32 size = vRegNode.GetSize(); /* in bytes */
1711         return (regType == kRegTyInt ? (size <= sizeof(int32) ? PTY_i32 : PTY_i64)
1712                                      : (size <= sizeof(float) ? PTY_f32 : PTY_f64));
1713     }
1714 
GetPseudoRegisterSpillLocation(PregIdx idx)1715     int64 GetPseudoRegisterSpillLocation(PregIdx idx)
1716     {
1717         const SymbolAlloc *symLoc = memLayout->GetSpillLocOfPseduoRegister(idx);
1718         return static_cast<int64>(GetBaseOffset(*symLoc));
1719     }
1720 
GetOrCreatSpillRegLocation(regno_t vrNum,uint32 memByteSize)1721     int64 GetOrCreatSpillRegLocation(regno_t vrNum, uint32 memByteSize)
1722     {
1723         auto *symLoc = GetMemlayout()->GetLocOfSpillRegister(vrNum, memByteSize);
1724         return static_cast<int64>(GetBaseOffset(*symLoc));
1725     }
1726 
1727     virtual MemOperand *GetPseudoRegisterSpillMemoryOperand(PregIdx idx) = 0;
1728 
GetSpillLocation(uint32 size)1729     uint32 GetSpillLocation(uint32 size)
1730     {
1731         uint32 offset = RoundUp(nextSpillLocation, static_cast<uint64>(size));
1732         nextSpillLocation = offset + size;
1733         return offset;
1734     }
1735 
1736     /* See if the symbol is a structure parameter that requires a copy. */
IsParamStructCopy(const MIRSymbol & symbol)1737     bool IsParamStructCopy(const MIRSymbol &symbol) const
1738     {
1739         auto *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(symbol.GetTyIdx());
1740         if (symbol.GetStorageClass() == kScFormal && IsParamStructCopyToMemory(*mirType)) {
1741             return true;
1742         }
1743         return false;
1744     }
1745 
GetPrimTypeFromSize(uint32 byteSize,PrimType defaultType)1746     PrimType GetPrimTypeFromSize(uint32 byteSize, PrimType defaultType) const
1747     {
1748         constexpr uint32 oneByte = 1;
1749         constexpr uint32 twoByte = 2;
1750         constexpr uint32 fourByte = 4;
1751         switch (byteSize) {
1752             case oneByte:
1753                 return PTY_i8;
1754             case twoByte:
1755                 return PTY_i16;
1756             case fourByte:
1757                 return PTY_i32;
1758             default:
1759                 return defaultType;
1760         }
1761     }
1762 
CreateAtomicBuiltinBB()1763     BB *CreateAtomicBuiltinBB()
1764     {
1765         LabelIdx atomicBBLabIdx = CreateLabel();
1766         BB *atomicBB = CreateNewBB();
1767         atomicBB->SetKind(BB::kBBIf);
1768         atomicBB->SetAtomicBuiltIn();
1769         atomicBB->AddLabel(atomicBBLabIdx);
1770         SetLab2BBMap(atomicBBLabIdx, *atomicBB);
1771         GetCurBB()->AppendBB(*atomicBB);
1772         return atomicBB;
1773     }
1774 
1775     // clone old mem and add offset
1776     // oldMem: [base, imm:12] -> newMem: [base, imm:(12 + offset)]
GetMemOperandAddOffset(const MemOperand & oldMem,uint32 offset,uint32 newSize)1777     MemOperand &GetMemOperandAddOffset(const MemOperand &oldMem, uint32 offset, uint32 newSize)
1778     {
1779         auto &newMem = static_cast<MemOperand &>(*oldMem.Clone(*GetMemoryPool()));
1780         auto &oldOffset = *oldMem.GetOffsetOperand();
1781         auto &newOffst = static_cast<ImmOperand &>(*oldOffset.Clone(*GetMemoryPool()));
1782         newOffst.SetValue(oldOffset.GetValue() + offset);
1783         newMem.SetOffsetOperand(newOffst);
1784         newMem.SetSize(newSize);
1785         return newMem;
1786     }
1787 
1788 private:
1789     CGFunc &operator=(const CGFunc &cgFunc);
1790     CGFunc(const CGFunc &);
1791     StmtNode *HandleFirstStmt();
1792     bool CheckSkipMembarOp(const StmtNode &stmt);
1793     MIRFunction &func;
1794     EHFunc *ehFunc = nullptr;
1795 
1796     InsnBuilder *insnBuilder = nullptr;
1797     OperandBuilder *opndBuilder = nullptr;
1798 
1799     uint32 bbCnt = 0;
1800     uint32 labelIdx = 0;               /* local label index number */
1801     LabelNode *startLabel = nullptr;   /* start label of the function */
1802     LabelNode *returnLabel = nullptr;  /* return label of the function */
1803     LabelNode *cleanupLabel = nullptr; /* label to indicate the entry of cleanup code. */
1804     LabelNode *endLabel = nullptr;     /* end label of the function */
1805 
1806     BB *firstBB = nullptr;
1807     BB *cleanupBB = nullptr;
1808     BB *cleanupEntryBB = nullptr;
1809     BB *lastBB = nullptr;
1810     BB *curBB = nullptr;
1811     BB *dummyBB;                    /* use this bb for add some instructions to bb that is no curBB. */
1812     BB *commonExitBB = nullptr;     /* this post-dominate all BBs */
1813     Insn *volReleaseInsn = nullptr; /* use to record the release insn for volatile strore */
1814     MapleVector<BB *> exitBBVec;
1815     MapleVector<BB *> noReturnCallBBVec;
1816     MapleSet<regno_t> extendSet; /* use to mark regs which spilled 32 bits but loaded 64 bits. */
1817     MapleUnorderedMap<LabelIdx, BB *> lab2BBMap;
1818     BECommon &beCommon;
1819     CCImpl *callConv = nullptr;
1820     MemLayout *memLayout = nullptr;
1821     RegisterInfo *targetRegInfo = nullptr;
1822     MapleAllocator *funcScopeAllocator;
1823     MapleMap<uint32, MIRSymbol *> emitStVec; /* symbol that needs to be emit as a local symbol. i.e, switch table */
1824     MapleUnorderedMap<LabelIdx, int32> switchLabelCnt; /* label in switch table */
1825     std::map<const MIRSymbol *, LabelIdx> funcLocalSym2Label;
1826     CallConvKind callingConventionKind;
1827 #if TARGARM32
1828     MapleVector<BB *> sortedBBs;
1829     MapleVector<LiveRange *> lrVec;
1830 #endif /* TARGARM32 */
1831     MapleVector<LmbcFormalParamInfo *> lmbcParamVec;
1832     int32 lmbcIntArgs = 0;
1833     int32 lmbcFpArgs = 0;
1834     uint32 lmbcTotalArgs = 0;
1835     CGCFG *theCFG = nullptr;
1836     FuncEmitInfo *funcEmitInfo = nullptr;
1837     uint32 nextSpillLocation = 0;
1838     regno_t spSaveReg = 0;
1839 
1840     const MapleString shortFuncName;
1841     bool hasAsm = false;
1842     bool useFP = true;
1843     bool seenFP = true;
1844     bool hasBuiltCfg = false;
1845     bool isStackMapComputed = false;
1846 
1847     /* save stack protect kinds which can trigger stack protect */
1848     uint8 stackProtectInfo = 0;
1849     bool needStackProtect = false;
1850 
1851     // mark exitBB is unreachable
1852     bool exitBBLost = false;
1853 }; /* class CGFunc */
1854 
1855 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgLayoutFrame, maplebe::CGFunc)
1856 MAPLE_FUNC_PHASE_DECLARE_END
1857 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgHandleFunction, maplebe::CGFunc)
1858 MAPLE_FUNC_PHASE_DECLARE_END
1859 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgFixCFLocOsft, maplebe::CGFunc)
1860 MAPLE_FUNC_PHASE_DECLARE_END
1861 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgVerify, maplebe::CGFunc)
1862 MAPLE_FUNC_PHASE_DECLARE_END
1863 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgGenCfi, maplebe::CGFunc)
1864 MAPLE_FUNC_PHASE_DECLARE_END
1865 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgEmission, maplebe::CGFunc)
1866 MAPLE_FUNC_PHASE_DECLARE_END
1867 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgGenProEpiLog, maplebe::CGFunc)
1868 MAPLE_FUNC_PHASE_DECLARE_END
1869 } /* namespace maplebe */
1870 #endif /* MAPLEBE_INCLUDE_CG_CGFUNC_H */
1871