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