xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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 
1530b57cec5SDimitry Andric public:
154*bdd1243dSDimitry Andric   explicit PPCFunctionInfo(const Function &F, const TargetSubtargetInfo *STI);
1550b57cec5SDimitry Andric 
15681ad6265SDimitry Andric   MachineFunctionInfo *
15781ad6265SDimitry Andric   clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
15881ad6265SDimitry Andric         const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
15981ad6265SDimitry Andric       const override;
16081ad6265SDimitry Andric 
1610b57cec5SDimitry Andric   int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
1620b57cec5SDimitry Andric   void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; }
1650b57cec5SDimitry Andric   void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   int getBasePointerSaveIndex() const { return BasePointerSaveIndex; }
1680b57cec5SDimitry Andric   void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; }
1710b57cec5SDimitry Andric   void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; }
1720b57cec5SDimitry Andric 
173fe6060f1SDimitry Andric   int getROPProtectionHashSaveIndex() const {
174fe6060f1SDimitry Andric     return ROPProtectionHashSaveIndex;
175fe6060f1SDimitry Andric   }
176fe6060f1SDimitry Andric   void setROPProtectionHashSaveIndex(int Idx) {
177fe6060f1SDimitry Andric     ROPProtectionHashSaveIndex = Idx;
178fe6060f1SDimitry Andric   }
179fe6060f1SDimitry Andric 
1800b57cec5SDimitry Andric   unsigned getMinReservedArea() const { return MinReservedArea; }
1810b57cec5SDimitry Andric   void setMinReservedArea(unsigned size) { MinReservedArea = size; }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   int getTailCallSPDelta() const { return TailCallSPDelta; }
1840b57cec5SDimitry Andric   void setTailCallSPDelta(int size) { TailCallSPDelta = size; }
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   /// MustSaveLR - This is set when the prolog/epilog inserter does its initial
1870b57cec5SDimitry Andric   /// scan of the function. It is true if the LR/LR8 register is ever explicitly
1880b57cec5SDimitry Andric   /// defined/clobbered in the machine function (e.g. by calls and movpctolr,
1890b57cec5SDimitry Andric   /// which is used in PIC generation), or if the LR stack slot is explicitly
1900b57cec5SDimitry Andric   /// referenced by builtin_return_address.
1910b57cec5SDimitry Andric   void setMustSaveLR(bool U) { MustSaveLR = U; }
1920b57cec5SDimitry Andric   bool mustSaveLR() const    { return MustSaveLR; }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   void setMustSaveTOC(bool U) { MustSaveTOC = U; }
1950b57cec5SDimitry Andric   bool mustSaveTOC() const    { return MustSaveTOC; }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   /// We certainly don't want to shrink wrap functions if we've emitted a
1980b57cec5SDimitry Andric   /// MovePCtoLR8 as that has to go into the entry, so the prologue definitely
1990b57cec5SDimitry Andric   /// has to go into the entry block.
2000b57cec5SDimitry Andric   void setShrinkWrapDisabled(bool U) { ShrinkWrapDisabled = U; }
2010b57cec5SDimitry Andric   bool shrinkWrapDisabled() const { return ShrinkWrapDisabled; }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   void setHasSpills()      { HasSpills = true; }
2040b57cec5SDimitry Andric   bool hasSpills() const   { return HasSpills; }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   void setHasNonRISpills()    { HasNonRISpills = true; }
2070b57cec5SDimitry Andric   bool hasNonRISpills() const { return HasNonRISpills; }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   void setSpillsCR()       { SpillsCR = true; }
2100b57cec5SDimitry Andric   bool isCRSpilled() const { return SpillsCR; }
2110b57cec5SDimitry Andric 
2125ffd83dbSDimitry Andric   void setDisableNonVolatileCR() { DisableNonVolatileCR = true; }
2135ffd83dbSDimitry Andric   bool isNonVolatileCRDisabled() const { return DisableNonVolatileCR; }
2145ffd83dbSDimitry Andric 
2150b57cec5SDimitry Andric   void setLRStoreRequired() { LRStoreRequired = true; }
2160b57cec5SDimitry Andric   bool isLRStoreRequired() const { return LRStoreRequired; }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric   void setUsesTOCBasePtr()    { UsesTOCBasePtr = true; }
2190b57cec5SDimitry Andric   bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   void setHasFastCall() { HasFastCall = true; }
2220b57cec5SDimitry Andric   bool hasFastCall() const { return HasFastCall;}
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
2250b57cec5SDimitry Andric   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   int getVarArgsStackOffset() const { return VarArgsStackOffset; }
2280b57cec5SDimitry Andric   void setVarArgsStackOffset(int Offset) { VarArgsStackOffset = Offset; }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
2310b57cec5SDimitry Andric   void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
2320b57cec5SDimitry Andric 
233fe6060f1SDimitry Andric   unsigned getFixedParmsNum() const { return FixedParmsNum; }
234fe6060f1SDimitry Andric   unsigned getFloatingPointParmsNum() const { return FloatingParmsNum; }
235fe6060f1SDimitry Andric   unsigned getVectorParmsNum() const { return VectorParmsNum; }
236fe6060f1SDimitry Andric   bool hasVectorParms() const { return VectorParmsNum != 0; }
237e8d8bef9SDimitry Andric 
238fe6060f1SDimitry Andric   uint32_t getParmsType() const;
239e8d8bef9SDimitry Andric 
240fe6060f1SDimitry Andric   uint32_t getVecExtParmsType() const;
241fe6060f1SDimitry Andric 
242e8d8bef9SDimitry Andric   void appendParameterType(ParamType Type);
243e8d8bef9SDimitry Andric 
2440b57cec5SDimitry Andric   unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
2450b57cec5SDimitry Andric   void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; }
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   /// This function associates attributes for each live-in virtual register.
2485ffd83dbSDimitry Andric   void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags) {
2490b57cec5SDimitry Andric     LiveInAttrs.push_back(std::make_pair(VReg, Flags));
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2530b57cec5SDimitry Andric   /// a live-in register and sign-extended.
2545ffd83dbSDimitry Andric   bool isLiveInSExt(Register VReg) const;
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2570b57cec5SDimitry Andric   /// a live-in register and zero-extended.
2585ffd83dbSDimitry Andric   bool isLiveInZExt(Register VReg) const;
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   int getCRSpillFrameIndex() const { return CRSpillFrameIndex; }
2610b57cec5SDimitry Andric   void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; }
2620b57cec5SDimitry Andric 
2635ffd83dbSDimitry Andric   const SmallVectorImpl<Register> &
2640b57cec5SDimitry Andric     getMustSaveCRs() const { return MustSaveCRs; }
2655ffd83dbSDimitry Andric   void addMustSaveCR(Register Reg) { MustSaveCRs.push_back(Reg); }
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   void setUsesPICBase(bool uses) { UsesPICBase = uses; }
2680b57cec5SDimitry Andric   bool usesPICBase() const { return UsesPICBase; }
2690b57cec5SDimitry Andric 
2705ffd83dbSDimitry Andric   MCSymbol *getPICOffsetSymbol(MachineFunction &MF) const;
2710b57cec5SDimitry Andric 
2725ffd83dbSDimitry Andric   MCSymbol *getGlobalEPSymbol(MachineFunction &MF) const;
2735ffd83dbSDimitry Andric   MCSymbol *getLocalEPSymbol(MachineFunction &MF) const;
2745ffd83dbSDimitry Andric   MCSymbol *getTOCOffsetSymbol(MachineFunction &MF) const;
2750b57cec5SDimitry Andric };
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric } // end namespace llvm
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
280