1*0b57cec5SDimitry Andric //===-- PPCMachineFunctionInfo.h - Private data used for PowerPC --*- C++ -*-=// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file declares the PowerPC specific subclass of MachineFunctionInfo. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H 14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 17*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 18*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetCallingConv.h" 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric namespace llvm { 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric /// PPCFunctionInfo - This class is derived from MachineFunction private 23*0b57cec5SDimitry Andric /// PowerPC target-specific information for each MachineFunction. 24*0b57cec5SDimitry Andric class PPCFunctionInfo : public MachineFunctionInfo { 25*0b57cec5SDimitry Andric virtual void anchor(); 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric /// FramePointerSaveIndex - Frame index of where the old frame pointer is 28*0b57cec5SDimitry Andric /// stored. Also used as an anchor for instructions that need to be altered 29*0b57cec5SDimitry Andric /// when using frame pointers (dyna_add, dyna_sub.) 30*0b57cec5SDimitry Andric int FramePointerSaveIndex = 0; 31*0b57cec5SDimitry Andric 32*0b57cec5SDimitry Andric /// ReturnAddrSaveIndex - Frame index of where the return address is stored. 33*0b57cec5SDimitry Andric /// 34*0b57cec5SDimitry Andric int ReturnAddrSaveIndex = 0; 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric /// Frame index where the old base pointer is stored. 37*0b57cec5SDimitry Andric int BasePointerSaveIndex = 0; 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric /// Frame index where the old PIC base pointer is stored. 40*0b57cec5SDimitry Andric int PICBasePointerSaveIndex = 0; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric /// MustSaveLR - Indicates whether LR is defined (or clobbered) in the current 43*0b57cec5SDimitry Andric /// function. This is only valid after the initial scan of the function by 44*0b57cec5SDimitry Andric /// PEI. 45*0b57cec5SDimitry Andric bool MustSaveLR; 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric /// MustSaveTOC - Indicates that the TOC save needs to be performed in the 48*0b57cec5SDimitry Andric /// prologue of the function. This is typically the case when there are 49*0b57cec5SDimitry Andric /// indirect calls in the function and it is more profitable to save the 50*0b57cec5SDimitry Andric /// TOC pointer in the prologue than in the block(s) containing the call(s). 51*0b57cec5SDimitry Andric bool MustSaveTOC = false; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric /// Do we have to disable shrink-wrapping? This has to be set if we emit any 54*0b57cec5SDimitry Andric /// instructions that clobber LR in the entry block because discovering this 55*0b57cec5SDimitry Andric /// in PEI is too late (happens after shrink-wrapping); 56*0b57cec5SDimitry Andric bool ShrinkWrapDisabled = false; 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric /// Does this function have any stack spills. 59*0b57cec5SDimitry Andric bool HasSpills = false; 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric /// Does this function spill using instructions with only r+r (not r+i) 62*0b57cec5SDimitry Andric /// forms. 63*0b57cec5SDimitry Andric bool HasNonRISpills = false; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric /// SpillsCR - Indicates whether CR is spilled in the current function. 66*0b57cec5SDimitry Andric bool SpillsCR = false; 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric /// Indicates whether VRSAVE is spilled in the current function. 69*0b57cec5SDimitry Andric bool SpillsVRSAVE = false; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric /// LRStoreRequired - The bool indicates whether there is some explicit use of 72*0b57cec5SDimitry Andric /// the LR/LR8 stack slot that is not obvious from scanning the code. This 73*0b57cec5SDimitry Andric /// requires that the code generator produce a store of LR to the stack on 74*0b57cec5SDimitry Andric /// entry, even though LR may otherwise apparently not be used. 75*0b57cec5SDimitry Andric bool LRStoreRequired = false; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric /// This function makes use of the PPC64 ELF TOC base pointer (register r2). 78*0b57cec5SDimitry Andric bool UsesTOCBasePtr = false; 79*0b57cec5SDimitry Andric 80*0b57cec5SDimitry Andric /// MinReservedArea - This is the frame size that is at least reserved in a 81*0b57cec5SDimitry Andric /// potential caller (parameter+linkage area). 82*0b57cec5SDimitry Andric unsigned MinReservedArea = 0; 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric /// TailCallSPDelta - Stack pointer delta used when tail calling. Maximum 85*0b57cec5SDimitry Andric /// amount the stack pointer is adjusted to make the frame bigger for tail 86*0b57cec5SDimitry Andric /// calls. Used for creating an area before the register spill area. 87*0b57cec5SDimitry Andric int TailCallSPDelta = 0; 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric /// HasFastCall - Does this function contain a fast call. Used to determine 90*0b57cec5SDimitry Andric /// how the caller's stack pointer should be calculated (epilog/dynamicalloc). 91*0b57cec5SDimitry Andric bool HasFastCall = false; 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric /// VarArgsFrameIndex - FrameIndex for start of varargs area. 94*0b57cec5SDimitry Andric int VarArgsFrameIndex = 0; 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric /// VarArgsStackOffset - StackOffset for start of stack 97*0b57cec5SDimitry Andric /// arguments. 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric int VarArgsStackOffset = 0; 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric /// VarArgsNumGPR - Index of the first unused integer 102*0b57cec5SDimitry Andric /// register for parameter passing. 103*0b57cec5SDimitry Andric unsigned VarArgsNumGPR = 0; 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric /// VarArgsNumFPR - Index of the first unused double 106*0b57cec5SDimitry Andric /// register for parameter passing. 107*0b57cec5SDimitry Andric unsigned VarArgsNumFPR = 0; 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric /// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4. 110*0b57cec5SDimitry Andric int CRSpillFrameIndex = 0; 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric /// If any of CR[2-4] need to be saved in the prologue and restored in the 113*0b57cec5SDimitry Andric /// epilogue then they are added to this array. This is used for the 114*0b57cec5SDimitry Andric /// 64-bit SVR4 ABI. 115*0b57cec5SDimitry Andric SmallVector<unsigned, 3> MustSaveCRs; 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric /// Hold onto our MachineFunction context. 118*0b57cec5SDimitry Andric MachineFunction &MF; 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric /// Whether this uses the PIC Base register or not. 121*0b57cec5SDimitry Andric bool UsesPICBase = false; 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric /// True if this function has a subset of CSRs that is handled explicitly via 124*0b57cec5SDimitry Andric /// copies 125*0b57cec5SDimitry Andric bool IsSplitCSR = false; 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric /// We keep track attributes for each live-in virtual registers 128*0b57cec5SDimitry Andric /// to use SExt/ZExt flags in later optimization. 129*0b57cec5SDimitry Andric std::vector<std::pair<unsigned, ISD::ArgFlagsTy>> LiveInAttrs; 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric public: 132*0b57cec5SDimitry Andric explicit PPCFunctionInfo(MachineFunction &MF) : MF(MF) {} 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric int getFramePointerSaveIndex() const { return FramePointerSaveIndex; } 135*0b57cec5SDimitry Andric void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; } 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; } 138*0b57cec5SDimitry Andric void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; } 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric int getBasePointerSaveIndex() const { return BasePointerSaveIndex; } 141*0b57cec5SDimitry Andric void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; } 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andric int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; } 144*0b57cec5SDimitry Andric void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; } 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric unsigned getMinReservedArea() const { return MinReservedArea; } 147*0b57cec5SDimitry Andric void setMinReservedArea(unsigned size) { MinReservedArea = size; } 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric int getTailCallSPDelta() const { return TailCallSPDelta; } 150*0b57cec5SDimitry Andric void setTailCallSPDelta(int size) { TailCallSPDelta = size; } 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andric /// MustSaveLR - This is set when the prolog/epilog inserter does its initial 153*0b57cec5SDimitry Andric /// scan of the function. It is true if the LR/LR8 register is ever explicitly 154*0b57cec5SDimitry Andric /// defined/clobbered in the machine function (e.g. by calls and movpctolr, 155*0b57cec5SDimitry Andric /// which is used in PIC generation), or if the LR stack slot is explicitly 156*0b57cec5SDimitry Andric /// referenced by builtin_return_address. 157*0b57cec5SDimitry Andric void setMustSaveLR(bool U) { MustSaveLR = U; } 158*0b57cec5SDimitry Andric bool mustSaveLR() const { return MustSaveLR; } 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric void setMustSaveTOC(bool U) { MustSaveTOC = U; } 161*0b57cec5SDimitry Andric bool mustSaveTOC() const { return MustSaveTOC; } 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric /// We certainly don't want to shrink wrap functions if we've emitted a 164*0b57cec5SDimitry Andric /// MovePCtoLR8 as that has to go into the entry, so the prologue definitely 165*0b57cec5SDimitry Andric /// has to go into the entry block. 166*0b57cec5SDimitry Andric void setShrinkWrapDisabled(bool U) { ShrinkWrapDisabled = U; } 167*0b57cec5SDimitry Andric bool shrinkWrapDisabled() const { return ShrinkWrapDisabled; } 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric void setHasSpills() { HasSpills = true; } 170*0b57cec5SDimitry Andric bool hasSpills() const { return HasSpills; } 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric void setHasNonRISpills() { HasNonRISpills = true; } 173*0b57cec5SDimitry Andric bool hasNonRISpills() const { return HasNonRISpills; } 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric void setSpillsCR() { SpillsCR = true; } 176*0b57cec5SDimitry Andric bool isCRSpilled() const { return SpillsCR; } 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric void setSpillsVRSAVE() { SpillsVRSAVE = true; } 179*0b57cec5SDimitry Andric bool isVRSAVESpilled() const { return SpillsVRSAVE; } 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric void setLRStoreRequired() { LRStoreRequired = true; } 182*0b57cec5SDimitry Andric bool isLRStoreRequired() const { return LRStoreRequired; } 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric void setUsesTOCBasePtr() { UsesTOCBasePtr = true; } 185*0b57cec5SDimitry Andric bool usesTOCBasePtr() const { return UsesTOCBasePtr; } 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric void setHasFastCall() { HasFastCall = true; } 188*0b57cec5SDimitry Andric bool hasFastCall() const { return HasFastCall;} 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } 191*0b57cec5SDimitry Andric void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric int getVarArgsStackOffset() const { return VarArgsStackOffset; } 194*0b57cec5SDimitry Andric void setVarArgsStackOffset(int Offset) { VarArgsStackOffset = Offset; } 195*0b57cec5SDimitry Andric 196*0b57cec5SDimitry Andric unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; } 197*0b57cec5SDimitry Andric void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; } 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; } 200*0b57cec5SDimitry Andric void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; } 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andric /// This function associates attributes for each live-in virtual register. 203*0b57cec5SDimitry Andric void addLiveInAttr(unsigned VReg, ISD::ArgFlagsTy Flags) { 204*0b57cec5SDimitry Andric LiveInAttrs.push_back(std::make_pair(VReg, Flags)); 205*0b57cec5SDimitry Andric } 206*0b57cec5SDimitry Andric 207*0b57cec5SDimitry Andric /// This function returns true if the specified vreg is 208*0b57cec5SDimitry Andric /// a live-in register and sign-extended. 209*0b57cec5SDimitry Andric bool isLiveInSExt(unsigned VReg) const; 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric /// This function returns true if the specified vreg is 212*0b57cec5SDimitry Andric /// a live-in register and zero-extended. 213*0b57cec5SDimitry Andric bool isLiveInZExt(unsigned VReg) const; 214*0b57cec5SDimitry Andric 215*0b57cec5SDimitry Andric int getCRSpillFrameIndex() const { return CRSpillFrameIndex; } 216*0b57cec5SDimitry Andric void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; } 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric const SmallVectorImpl<unsigned> & 219*0b57cec5SDimitry Andric getMustSaveCRs() const { return MustSaveCRs; } 220*0b57cec5SDimitry Andric void addMustSaveCR(unsigned Reg) { MustSaveCRs.push_back(Reg); } 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric void setUsesPICBase(bool uses) { UsesPICBase = uses; } 223*0b57cec5SDimitry Andric bool usesPICBase() const { return UsesPICBase; } 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric bool isSplitCSR() const { return IsSplitCSR; } 226*0b57cec5SDimitry Andric void setIsSplitCSR(bool s) { IsSplitCSR = s; } 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric MCSymbol *getPICOffsetSymbol() const; 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric MCSymbol *getGlobalEPSymbol() const; 231*0b57cec5SDimitry Andric MCSymbol *getLocalEPSymbol() const; 232*0b57cec5SDimitry Andric MCSymbol *getTOCOffsetSymbol() const; 233*0b57cec5SDimitry Andric }; 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric } // end namespace llvm 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H 238