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 ®Opnd) = 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 ®Dest, RegOperand ®Src, 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 ®, 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 ¤tBB) 943 { 944 for (BB *exitBB : exitBBVec) { 945 if (exitBB == ¤tBB) { 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 ®Info) 1010 { 1011 targetRegInfo = ®Info; 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