xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- PPCMachineFunctionInfo.h - Private data used for PowerPC --*- C++ -*-=//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares the PowerPC specific subclass of MachineFunctionInfo.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetCallingConv.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace llvm {
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric /// PPCFunctionInfo - This class is derived from MachineFunction private
230b57cec5SDimitry Andric /// PowerPC target-specific information for each MachineFunction.
240b57cec5SDimitry Andric class PPCFunctionInfo : public MachineFunctionInfo {
25e8d8bef9SDimitry Andric public:
26e8d8bef9SDimitry Andric   enum ParamType {
27fe6060f1SDimitry Andric     FixedType,
28fe6060f1SDimitry Andric     ShortFloatingPoint,
29fe6060f1SDimitry Andric     LongFloatingPoint,
30fe6060f1SDimitry Andric     VectorChar,
31fe6060f1SDimitry Andric     VectorShort,
32fe6060f1SDimitry Andric     VectorInt,
33fe6060f1SDimitry Andric     VectorFloat
34e8d8bef9SDimitry Andric   };
35e8d8bef9SDimitry Andric 
36e8d8bef9SDimitry Andric private:
370b57cec5SDimitry Andric   virtual void anchor();
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   /// FramePointerSaveIndex - Frame index of where the old frame pointer is
400b57cec5SDimitry Andric   /// stored.  Also used as an anchor for instructions that need to be altered
410b57cec5SDimitry Andric   /// when using frame pointers (dyna_add, dyna_sub.)
420b57cec5SDimitry Andric   int FramePointerSaveIndex = 0;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   /// ReturnAddrSaveIndex - Frame index of where the return address is stored.
450b57cec5SDimitry Andric   ///
460b57cec5SDimitry Andric   int ReturnAddrSaveIndex = 0;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   /// Frame index where the old base pointer is stored.
490b57cec5SDimitry Andric   int BasePointerSaveIndex = 0;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   /// Frame index where the old PIC base pointer is stored.
520b57cec5SDimitry Andric   int PICBasePointerSaveIndex = 0;
530b57cec5SDimitry Andric 
54fe6060f1SDimitry Andric   /// Frame index where the ROP Protection Hash is stored.
55fe6060f1SDimitry Andric   int ROPProtectionHashSaveIndex = 0;
56fe6060f1SDimitry Andric 
570b57cec5SDimitry Andric   /// MustSaveLR - Indicates whether LR is defined (or clobbered) in the current
580b57cec5SDimitry Andric   /// function.  This is only valid after the initial scan of the function by
590b57cec5SDimitry Andric   /// PEI.
60480093f4SDimitry Andric   bool MustSaveLR = false;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   /// MustSaveTOC - Indicates that the TOC save needs to be performed in the
630b57cec5SDimitry Andric   /// prologue of the function. This is typically the case when there are
640b57cec5SDimitry Andric   /// indirect calls in the function and it is more profitable to save the
650b57cec5SDimitry Andric   /// TOC pointer in the prologue than in the block(s) containing the call(s).
660b57cec5SDimitry Andric   bool MustSaveTOC = false;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   /// Do we have to disable shrink-wrapping? This has to be set if we emit any
690b57cec5SDimitry Andric   /// instructions that clobber LR in the entry block because discovering this
700b57cec5SDimitry Andric   /// in PEI is too late (happens after shrink-wrapping);
710b57cec5SDimitry Andric   bool ShrinkWrapDisabled = false;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   /// Does this function have any stack spills.
740b57cec5SDimitry Andric   bool HasSpills = false;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   /// Does this function spill using instructions with only r+r (not r+i)
770b57cec5SDimitry Andric   /// forms.
780b57cec5SDimitry Andric   bool HasNonRISpills = false;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   /// SpillsCR - Indicates whether CR is spilled in the current function.
810b57cec5SDimitry Andric   bool SpillsCR = false;
820b57cec5SDimitry Andric 
835ffd83dbSDimitry Andric   /// DisableNonVolatileCR - Indicates whether non-volatile CR fields would be
845ffd83dbSDimitry Andric   /// disabled.
855ffd83dbSDimitry Andric   bool DisableNonVolatileCR = false;
865ffd83dbSDimitry Andric 
870b57cec5SDimitry Andric   /// LRStoreRequired - The bool indicates whether there is some explicit use of
880b57cec5SDimitry Andric   /// the LR/LR8 stack slot that is not obvious from scanning the code.  This
890b57cec5SDimitry Andric   /// requires that the code generator produce a store of LR to the stack on
900b57cec5SDimitry Andric   /// entry, even though LR may otherwise apparently not be used.
910b57cec5SDimitry Andric   bool LRStoreRequired = false;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   /// This function makes use of the PPC64 ELF TOC base pointer (register r2).
940b57cec5SDimitry Andric   bool UsesTOCBasePtr = false;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   /// MinReservedArea - This is the frame size that is at least reserved in a
970b57cec5SDimitry Andric   /// potential caller (parameter+linkage area).
980b57cec5SDimitry Andric   unsigned MinReservedArea = 0;
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   /// TailCallSPDelta - Stack pointer delta used when tail calling. Maximum
1010b57cec5SDimitry Andric   /// amount the stack pointer is adjusted to make the frame bigger for tail
1020b57cec5SDimitry Andric   /// calls. Used for creating an area before the register spill area.
1030b57cec5SDimitry Andric   int TailCallSPDelta = 0;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   /// HasFastCall - Does this function contain a fast call. Used to determine
1060b57cec5SDimitry Andric   /// how the caller's stack pointer should be calculated (epilog/dynamicalloc).
1070b57cec5SDimitry Andric   bool HasFastCall = false;
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
1100b57cec5SDimitry Andric   int VarArgsFrameIndex = 0;
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   /// VarArgsStackOffset - StackOffset for start of stack
1130b57cec5SDimitry Andric   /// arguments.
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   int VarArgsStackOffset = 0;
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   /// VarArgsNumGPR - Index of the first unused integer
1180b57cec5SDimitry Andric   /// register for parameter passing.
1190b57cec5SDimitry Andric   unsigned VarArgsNumGPR = 0;
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   /// VarArgsNumFPR - Index of the first unused double
1220b57cec5SDimitry Andric   /// register for parameter passing.
1230b57cec5SDimitry Andric   unsigned VarArgsNumFPR = 0;
1240b57cec5SDimitry Andric 
125fe6060f1SDimitry Andric   /// FixedParmsNum - The number of fixed parameters.
126fe6060f1SDimitry Andric   unsigned FixedParmsNum = 0;
127e8d8bef9SDimitry Andric 
128fe6060f1SDimitry Andric   /// FloatingParmsNum - The number of floating parameters.
129fe6060f1SDimitry Andric   unsigned FloatingParmsNum = 0;
130e8d8bef9SDimitry Andric 
131fe6060f1SDimitry Andric   /// VectorParmsNum - The number of vector parameters.
132fe6060f1SDimitry Andric   unsigned VectorParmsNum = 0;
133fe6060f1SDimitry Andric 
134fe6060f1SDimitry Andric   /// ParamtersType - Store all the parameter's type that are saved on
135fe6060f1SDimitry Andric   /// registers.
136fe6060f1SDimitry Andric   SmallVector<ParamType, 32> ParamtersType;
137e8d8bef9SDimitry Andric 
1380b57cec5SDimitry Andric   /// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
1390b57cec5SDimitry Andric   int CRSpillFrameIndex = 0;
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric   /// If any of CR[2-4] need to be saved in the prologue and restored in the
1420b57cec5SDimitry Andric   /// epilogue then they are added to this array. This is used for the
1430b57cec5SDimitry Andric   /// 64-bit SVR4 ABI.
1445ffd83dbSDimitry Andric   SmallVector<Register, 3> MustSaveCRs;
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   /// Whether this uses the PIC Base register or not.
1470b57cec5SDimitry Andric   bool UsesPICBase = false;
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   /// We keep track attributes for each live-in virtual registers
1500b57cec5SDimitry Andric   /// to use SExt/ZExt flags in later optimization.
1515ffd83dbSDimitry Andric   std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
1520b57cec5SDimitry Andric 
153*0fca6ea1SDimitry Andric   /// Flags for aix-shared-lib-tls-model-opt, will be lazily initialized for
154*0fca6ea1SDimitry Andric   /// each function.
155*0fca6ea1SDimitry Andric   bool AIXFuncUseTLSIEForLD = false;
156*0fca6ea1SDimitry Andric   bool AIXFuncTLSModelOptInitDone = false;
157*0fca6ea1SDimitry Andric 
1580b57cec5SDimitry Andric public:
159bdd1243dSDimitry Andric   explicit PPCFunctionInfo(const Function &F, const TargetSubtargetInfo *STI);
1600b57cec5SDimitry Andric 
16181ad6265SDimitry Andric   MachineFunctionInfo *
16281ad6265SDimitry Andric   clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
16381ad6265SDimitry Andric         const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
16481ad6265SDimitry Andric       const override;
16581ad6265SDimitry Andric 
1660b57cec5SDimitry Andric   int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
1670b57cec5SDimitry Andric   void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; }
1700b57cec5SDimitry Andric   void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; }
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   int getBasePointerSaveIndex() const { return BasePointerSaveIndex; }
1730b57cec5SDimitry Andric   void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; }
1760b57cec5SDimitry Andric   void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; }
1770b57cec5SDimitry Andric 
178fe6060f1SDimitry Andric   int getROPProtectionHashSaveIndex() const {
179fe6060f1SDimitry Andric     return ROPProtectionHashSaveIndex;
180fe6060f1SDimitry Andric   }
181fe6060f1SDimitry Andric   void setROPProtectionHashSaveIndex(int Idx) {
182fe6060f1SDimitry Andric     ROPProtectionHashSaveIndex = Idx;
183fe6060f1SDimitry Andric   }
184fe6060f1SDimitry Andric 
1850b57cec5SDimitry Andric   unsigned getMinReservedArea() const { return MinReservedArea; }
1860b57cec5SDimitry Andric   void setMinReservedArea(unsigned size) { MinReservedArea = size; }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   int getTailCallSPDelta() const { return TailCallSPDelta; }
1890b57cec5SDimitry Andric   void setTailCallSPDelta(int size) { TailCallSPDelta = size; }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   /// MustSaveLR - This is set when the prolog/epilog inserter does its initial
1920b57cec5SDimitry Andric   /// scan of the function. It is true if the LR/LR8 register is ever explicitly
1930b57cec5SDimitry Andric   /// defined/clobbered in the machine function (e.g. by calls and movpctolr,
1940b57cec5SDimitry Andric   /// which is used in PIC generation), or if the LR stack slot is explicitly
1950b57cec5SDimitry Andric   /// referenced by builtin_return_address.
1960b57cec5SDimitry Andric   void setMustSaveLR(bool U) { MustSaveLR = U; }
1970b57cec5SDimitry Andric   bool mustSaveLR() const    { return MustSaveLR; }
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   void setMustSaveTOC(bool U) { MustSaveTOC = U; }
2000b57cec5SDimitry Andric   bool mustSaveTOC() const    { return MustSaveTOC; }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   /// We certainly don't want to shrink wrap functions if we've emitted a
2030b57cec5SDimitry Andric   /// MovePCtoLR8 as that has to go into the entry, so the prologue definitely
2040b57cec5SDimitry Andric   /// has to go into the entry block.
2050b57cec5SDimitry Andric   void setShrinkWrapDisabled(bool U) { ShrinkWrapDisabled = U; }
2060b57cec5SDimitry Andric   bool shrinkWrapDisabled() const { return ShrinkWrapDisabled; }
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   void setHasSpills()      { HasSpills = true; }
2090b57cec5SDimitry Andric   bool hasSpills() const   { return HasSpills; }
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   void setHasNonRISpills()    { HasNonRISpills = true; }
2120b57cec5SDimitry Andric   bool hasNonRISpills() const { return HasNonRISpills; }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   void setSpillsCR()       { SpillsCR = true; }
2150b57cec5SDimitry Andric   bool isCRSpilled() const { return SpillsCR; }
2160b57cec5SDimitry Andric 
2175ffd83dbSDimitry Andric   void setDisableNonVolatileCR() { DisableNonVolatileCR = true; }
2185ffd83dbSDimitry Andric   bool isNonVolatileCRDisabled() const { return DisableNonVolatileCR; }
2195ffd83dbSDimitry Andric 
2200b57cec5SDimitry Andric   void setLRStoreRequired() { LRStoreRequired = true; }
2210b57cec5SDimitry Andric   bool isLRStoreRequired() const { return LRStoreRequired; }
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   void setUsesTOCBasePtr()    { UsesTOCBasePtr = true; }
2240b57cec5SDimitry Andric   bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   void setHasFastCall() { HasFastCall = true; }
2270b57cec5SDimitry Andric   bool hasFastCall() const { return HasFastCall;}
2280b57cec5SDimitry Andric 
229*0fca6ea1SDimitry Andric   void setAIXFuncTLSModelOptInitDone() { AIXFuncTLSModelOptInitDone = true; }
230*0fca6ea1SDimitry Andric   bool isAIXFuncTLSModelOptInitDone() const {
231*0fca6ea1SDimitry Andric     return AIXFuncTLSModelOptInitDone;
232*0fca6ea1SDimitry Andric   }
233*0fca6ea1SDimitry Andric   void setAIXFuncUseTLSIEForLD() { AIXFuncUseTLSIEForLD = true; }
234*0fca6ea1SDimitry Andric   bool isAIXFuncUseTLSIEForLD() const { return AIXFuncUseTLSIEForLD; }
235*0fca6ea1SDimitry Andric 
2360b57cec5SDimitry Andric   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
2370b57cec5SDimitry Andric   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   int getVarArgsStackOffset() const { return VarArgsStackOffset; }
2400b57cec5SDimitry Andric   void setVarArgsStackOffset(int Offset) { VarArgsStackOffset = Offset; }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
2430b57cec5SDimitry Andric   void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
2440b57cec5SDimitry Andric 
245fe6060f1SDimitry Andric   unsigned getFixedParmsNum() const { return FixedParmsNum; }
246fe6060f1SDimitry Andric   unsigned getFloatingPointParmsNum() const { return FloatingParmsNum; }
247fe6060f1SDimitry Andric   unsigned getVectorParmsNum() const { return VectorParmsNum; }
248fe6060f1SDimitry Andric   bool hasVectorParms() const { return VectorParmsNum != 0; }
249e8d8bef9SDimitry Andric 
250fe6060f1SDimitry Andric   uint32_t getParmsType() const;
251e8d8bef9SDimitry Andric 
252fe6060f1SDimitry Andric   uint32_t getVecExtParmsType() const;
253fe6060f1SDimitry Andric 
254e8d8bef9SDimitry Andric   void appendParameterType(ParamType Type);
255e8d8bef9SDimitry Andric 
2560b57cec5SDimitry Andric   unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
2570b57cec5SDimitry Andric   void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; }
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   /// This function associates attributes for each live-in virtual register.
2605ffd83dbSDimitry Andric   void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags) {
2610b57cec5SDimitry Andric     LiveInAttrs.push_back(std::make_pair(VReg, Flags));
2620b57cec5SDimitry Andric   }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2650b57cec5SDimitry Andric   /// a live-in register and sign-extended.
2665ffd83dbSDimitry Andric   bool isLiveInSExt(Register VReg) const;
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2690b57cec5SDimitry Andric   /// a live-in register and zero-extended.
2705ffd83dbSDimitry Andric   bool isLiveInZExt(Register VReg) const;
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   int getCRSpillFrameIndex() const { return CRSpillFrameIndex; }
2730b57cec5SDimitry Andric   void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; }
2740b57cec5SDimitry Andric 
2755ffd83dbSDimitry Andric   const SmallVectorImpl<Register> &
2760b57cec5SDimitry Andric     getMustSaveCRs() const { return MustSaveCRs; }
2775ffd83dbSDimitry Andric   void addMustSaveCR(Register Reg) { MustSaveCRs.push_back(Reg); }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   void setUsesPICBase(bool uses) { UsesPICBase = uses; }
2800b57cec5SDimitry Andric   bool usesPICBase() const { return UsesPICBase; }
2810b57cec5SDimitry Andric 
2825ffd83dbSDimitry Andric   MCSymbol *getPICOffsetSymbol(MachineFunction &MF) const;
2830b57cec5SDimitry Andric 
2845ffd83dbSDimitry Andric   MCSymbol *getGlobalEPSymbol(MachineFunction &MF) const;
2855ffd83dbSDimitry Andric   MCSymbol *getLocalEPSymbol(MachineFunction &MF) const;
2865ffd83dbSDimitry Andric   MCSymbol *getTOCOffsetSymbol(MachineFunction &MF) const;
2870b57cec5SDimitry Andric };
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric } // end namespace llvm
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
292