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