xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h (revision fe6060f10f634930ff71b7c50291ddc610da2475)
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 {
27*fe6060f1SDimitry Andric     FixedType,
28*fe6060f1SDimitry Andric     ShortFloatingPoint,
29*fe6060f1SDimitry Andric     LongFloatingPoint,
30*fe6060f1SDimitry Andric     VectorChar,
31*fe6060f1SDimitry Andric     VectorShort,
32*fe6060f1SDimitry Andric     VectorInt,
33*fe6060f1SDimitry 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 
54*fe6060f1SDimitry Andric   /// Frame index where the ROP Protection Hash is stored.
55*fe6060f1SDimitry Andric   int ROPProtectionHashSaveIndex = 0;
56*fe6060f1SDimitry 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 
125*fe6060f1SDimitry Andric   /// FixedParmsNum - The number of fixed parameters.
126*fe6060f1SDimitry Andric   unsigned FixedParmsNum = 0;
127e8d8bef9SDimitry Andric 
128*fe6060f1SDimitry Andric   /// FloatingParmsNum - The number of floating parameters.
129*fe6060f1SDimitry Andric   unsigned FloatingParmsNum = 0;
130e8d8bef9SDimitry Andric 
131*fe6060f1SDimitry Andric   /// VectorParmsNum - The number of vector parameters.
132*fe6060f1SDimitry Andric   unsigned VectorParmsNum = 0;
133*fe6060f1SDimitry Andric 
134*fe6060f1SDimitry Andric   /// ParamtersType - Store all the parameter's type that are saved on
135*fe6060f1SDimitry Andric   /// registers.
136*fe6060f1SDimitry 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:
1545ffd83dbSDimitry Andric   explicit PPCFunctionInfo(const MachineFunction &MF);
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
1570b57cec5SDimitry Andric   void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric   int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; }
1600b57cec5SDimitry Andric   void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   int getBasePointerSaveIndex() const { return BasePointerSaveIndex; }
1630b57cec5SDimitry Andric   void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; }
1660b57cec5SDimitry Andric   void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; }
1670b57cec5SDimitry Andric 
168*fe6060f1SDimitry Andric   int getROPProtectionHashSaveIndex() const {
169*fe6060f1SDimitry Andric     return ROPProtectionHashSaveIndex;
170*fe6060f1SDimitry Andric   }
171*fe6060f1SDimitry Andric   void setROPProtectionHashSaveIndex(int Idx) {
172*fe6060f1SDimitry Andric     ROPProtectionHashSaveIndex = Idx;
173*fe6060f1SDimitry Andric   }
174*fe6060f1SDimitry Andric 
1750b57cec5SDimitry Andric   unsigned getMinReservedArea() const { return MinReservedArea; }
1760b57cec5SDimitry Andric   void setMinReservedArea(unsigned size) { MinReservedArea = size; }
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   int getTailCallSPDelta() const { return TailCallSPDelta; }
1790b57cec5SDimitry Andric   void setTailCallSPDelta(int size) { TailCallSPDelta = size; }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   /// MustSaveLR - This is set when the prolog/epilog inserter does its initial
1820b57cec5SDimitry Andric   /// scan of the function. It is true if the LR/LR8 register is ever explicitly
1830b57cec5SDimitry Andric   /// defined/clobbered in the machine function (e.g. by calls and movpctolr,
1840b57cec5SDimitry Andric   /// which is used in PIC generation), or if the LR stack slot is explicitly
1850b57cec5SDimitry Andric   /// referenced by builtin_return_address.
1860b57cec5SDimitry Andric   void setMustSaveLR(bool U) { MustSaveLR = U; }
1870b57cec5SDimitry Andric   bool mustSaveLR() const    { return MustSaveLR; }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   void setMustSaveTOC(bool U) { MustSaveTOC = U; }
1900b57cec5SDimitry Andric   bool mustSaveTOC() const    { return MustSaveTOC; }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   /// We certainly don't want to shrink wrap functions if we've emitted a
1930b57cec5SDimitry Andric   /// MovePCtoLR8 as that has to go into the entry, so the prologue definitely
1940b57cec5SDimitry Andric   /// has to go into the entry block.
1950b57cec5SDimitry Andric   void setShrinkWrapDisabled(bool U) { ShrinkWrapDisabled = U; }
1960b57cec5SDimitry Andric   bool shrinkWrapDisabled() const { return ShrinkWrapDisabled; }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   void setHasSpills()      { HasSpills = true; }
1990b57cec5SDimitry Andric   bool hasSpills() const   { return HasSpills; }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   void setHasNonRISpills()    { HasNonRISpills = true; }
2020b57cec5SDimitry Andric   bool hasNonRISpills() const { return HasNonRISpills; }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric   void setSpillsCR()       { SpillsCR = true; }
2050b57cec5SDimitry Andric   bool isCRSpilled() const { return SpillsCR; }
2060b57cec5SDimitry Andric 
2075ffd83dbSDimitry Andric   void setDisableNonVolatileCR() { DisableNonVolatileCR = true; }
2085ffd83dbSDimitry Andric   bool isNonVolatileCRDisabled() const { return DisableNonVolatileCR; }
2095ffd83dbSDimitry Andric 
2100b57cec5SDimitry Andric   void setLRStoreRequired() { LRStoreRequired = true; }
2110b57cec5SDimitry Andric   bool isLRStoreRequired() const { return LRStoreRequired; }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   void setUsesTOCBasePtr()    { UsesTOCBasePtr = true; }
2140b57cec5SDimitry Andric   bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   void setHasFastCall() { HasFastCall = true; }
2170b57cec5SDimitry Andric   bool hasFastCall() const { return HasFastCall;}
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
2200b57cec5SDimitry Andric   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   int getVarArgsStackOffset() const { return VarArgsStackOffset; }
2230b57cec5SDimitry Andric   void setVarArgsStackOffset(int Offset) { VarArgsStackOffset = Offset; }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
2260b57cec5SDimitry Andric   void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
2270b57cec5SDimitry Andric 
228*fe6060f1SDimitry Andric   unsigned getFixedParmsNum() const { return FixedParmsNum; }
229*fe6060f1SDimitry Andric   unsigned getFloatingPointParmsNum() const { return FloatingParmsNum; }
230*fe6060f1SDimitry Andric   unsigned getVectorParmsNum() const { return VectorParmsNum; }
231*fe6060f1SDimitry Andric   bool hasVectorParms() const { return VectorParmsNum != 0; }
232e8d8bef9SDimitry Andric 
233*fe6060f1SDimitry Andric   uint32_t getParmsType() const;
234e8d8bef9SDimitry Andric 
235*fe6060f1SDimitry Andric   uint32_t getVecExtParmsType() const;
236*fe6060f1SDimitry Andric 
237e8d8bef9SDimitry Andric   void appendParameterType(ParamType Type);
238e8d8bef9SDimitry Andric 
2390b57cec5SDimitry Andric   unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
2400b57cec5SDimitry Andric   void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   /// This function associates attributes for each live-in virtual register.
2435ffd83dbSDimitry Andric   void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags) {
2440b57cec5SDimitry Andric     LiveInAttrs.push_back(std::make_pair(VReg, Flags));
2450b57cec5SDimitry Andric   }
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2480b57cec5SDimitry Andric   /// a live-in register and sign-extended.
2495ffd83dbSDimitry Andric   bool isLiveInSExt(Register VReg) const;
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2520b57cec5SDimitry Andric   /// a live-in register and zero-extended.
2535ffd83dbSDimitry Andric   bool isLiveInZExt(Register VReg) const;
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   int getCRSpillFrameIndex() const { return CRSpillFrameIndex; }
2560b57cec5SDimitry Andric   void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; }
2570b57cec5SDimitry Andric 
2585ffd83dbSDimitry Andric   const SmallVectorImpl<Register> &
2590b57cec5SDimitry Andric     getMustSaveCRs() const { return MustSaveCRs; }
2605ffd83dbSDimitry Andric   void addMustSaveCR(Register Reg) { MustSaveCRs.push_back(Reg); }
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   void setUsesPICBase(bool uses) { UsesPICBase = uses; }
2630b57cec5SDimitry Andric   bool usesPICBase() const { return UsesPICBase; }
2640b57cec5SDimitry Andric 
2655ffd83dbSDimitry Andric   MCSymbol *getPICOffsetSymbol(MachineFunction &MF) const;
2660b57cec5SDimitry Andric 
2675ffd83dbSDimitry Andric   MCSymbol *getGlobalEPSymbol(MachineFunction &MF) const;
2685ffd83dbSDimitry Andric   MCSymbol *getLocalEPSymbol(MachineFunction &MF) const;
2695ffd83dbSDimitry Andric   MCSymbol *getTOCOffsetSymbol(MachineFunction &MF) const;
2700b57cec5SDimitry Andric };
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric } // end namespace llvm
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
275