xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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 {
25*e8d8bef9SDimitry Andric public:
26*e8d8bef9SDimitry Andric   // The value in the ParamType are used to indicate the bitstrings used in the
27*e8d8bef9SDimitry Andric   // encoding format.
28*e8d8bef9SDimitry Andric   enum ParamType {
29*e8d8bef9SDimitry Andric     FixedType = 0x0,
30*e8d8bef9SDimitry Andric     ShortFloatPoint = 0x2,
31*e8d8bef9SDimitry Andric     LongFloatPoint = 0x3
32*e8d8bef9SDimitry Andric   };
33*e8d8bef9SDimitry Andric 
34*e8d8bef9SDimitry Andric private:
350b57cec5SDimitry Andric   virtual void anchor();
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   /// FramePointerSaveIndex - Frame index of where the old frame pointer is
380b57cec5SDimitry Andric   /// stored.  Also used as an anchor for instructions that need to be altered
390b57cec5SDimitry Andric   /// when using frame pointers (dyna_add, dyna_sub.)
400b57cec5SDimitry Andric   int FramePointerSaveIndex = 0;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   /// ReturnAddrSaveIndex - Frame index of where the return address is stored.
430b57cec5SDimitry Andric   ///
440b57cec5SDimitry Andric   int ReturnAddrSaveIndex = 0;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   /// Frame index where the old base pointer is stored.
470b57cec5SDimitry Andric   int BasePointerSaveIndex = 0;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   /// Frame index where the old PIC base pointer is stored.
500b57cec5SDimitry Andric   int PICBasePointerSaveIndex = 0;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   /// MustSaveLR - Indicates whether LR is defined (or clobbered) in the current
530b57cec5SDimitry Andric   /// function.  This is only valid after the initial scan of the function by
540b57cec5SDimitry Andric   /// PEI.
55480093f4SDimitry Andric   bool MustSaveLR = false;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   /// MustSaveTOC - Indicates that the TOC save needs to be performed in the
580b57cec5SDimitry Andric   /// prologue of the function. This is typically the case when there are
590b57cec5SDimitry Andric   /// indirect calls in the function and it is more profitable to save the
600b57cec5SDimitry Andric   /// TOC pointer in the prologue than in the block(s) containing the call(s).
610b57cec5SDimitry Andric   bool MustSaveTOC = false;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   /// Do we have to disable shrink-wrapping? This has to be set if we emit any
640b57cec5SDimitry Andric   /// instructions that clobber LR in the entry block because discovering this
650b57cec5SDimitry Andric   /// in PEI is too late (happens after shrink-wrapping);
660b57cec5SDimitry Andric   bool ShrinkWrapDisabled = false;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   /// Does this function have any stack spills.
690b57cec5SDimitry Andric   bool HasSpills = false;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   /// Does this function spill using instructions with only r+r (not r+i)
720b57cec5SDimitry Andric   /// forms.
730b57cec5SDimitry Andric   bool HasNonRISpills = false;
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   /// SpillsCR - Indicates whether CR is spilled in the current function.
760b57cec5SDimitry Andric   bool SpillsCR = false;
770b57cec5SDimitry Andric 
785ffd83dbSDimitry Andric   /// DisableNonVolatileCR - Indicates whether non-volatile CR fields would be
795ffd83dbSDimitry Andric   /// disabled.
805ffd83dbSDimitry Andric   bool DisableNonVolatileCR = false;
815ffd83dbSDimitry Andric 
820b57cec5SDimitry Andric   /// LRStoreRequired - The bool indicates whether there is some explicit use of
830b57cec5SDimitry Andric   /// the LR/LR8 stack slot that is not obvious from scanning the code.  This
840b57cec5SDimitry Andric   /// requires that the code generator produce a store of LR to the stack on
850b57cec5SDimitry Andric   /// entry, even though LR may otherwise apparently not be used.
860b57cec5SDimitry Andric   bool LRStoreRequired = false;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   /// This function makes use of the PPC64 ELF TOC base pointer (register r2).
890b57cec5SDimitry Andric   bool UsesTOCBasePtr = false;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   /// MinReservedArea - This is the frame size that is at least reserved in a
920b57cec5SDimitry Andric   /// potential caller (parameter+linkage area).
930b57cec5SDimitry Andric   unsigned MinReservedArea = 0;
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   /// TailCallSPDelta - Stack pointer delta used when tail calling. Maximum
960b57cec5SDimitry Andric   /// amount the stack pointer is adjusted to make the frame bigger for tail
970b57cec5SDimitry Andric   /// calls. Used for creating an area before the register spill area.
980b57cec5SDimitry Andric   int TailCallSPDelta = 0;
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   /// HasFastCall - Does this function contain a fast call. Used to determine
1010b57cec5SDimitry Andric   /// how the caller's stack pointer should be calculated (epilog/dynamicalloc).
1020b57cec5SDimitry Andric   bool HasFastCall = false;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
1050b57cec5SDimitry Andric   int VarArgsFrameIndex = 0;
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   /// VarArgsStackOffset - StackOffset for start of stack
1080b57cec5SDimitry Andric   /// arguments.
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   int VarArgsStackOffset = 0;
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   /// VarArgsNumGPR - Index of the first unused integer
1130b57cec5SDimitry Andric   /// register for parameter passing.
1140b57cec5SDimitry Andric   unsigned VarArgsNumGPR = 0;
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   /// VarArgsNumFPR - Index of the first unused double
1170b57cec5SDimitry Andric   /// register for parameter passing.
1180b57cec5SDimitry Andric   unsigned VarArgsNumFPR = 0;
1190b57cec5SDimitry Andric 
120*e8d8bef9SDimitry Andric   /// FixedParamNum - Number of fixed parameter.
121*e8d8bef9SDimitry Andric   unsigned FixedParamNum = 0;
122*e8d8bef9SDimitry Andric 
123*e8d8bef9SDimitry Andric   /// FloatingParamNum - Number of floating point parameter.
124*e8d8bef9SDimitry Andric   unsigned FloatingPointParamNum = 0;
125*e8d8bef9SDimitry Andric 
126*e8d8bef9SDimitry Andric   /// ParamType - Encode type for every parameter
127*e8d8bef9SDimitry Andric   /// in the order of parameters passing in.
128*e8d8bef9SDimitry Andric   /// Bitstring starts from the most significant (leftmost) bit.
129*e8d8bef9SDimitry Andric   /// '0'b => fixed parameter.
130*e8d8bef9SDimitry Andric   /// '10'b => floating point short parameter.
131*e8d8bef9SDimitry Andric   /// '11'b => floating point long parameter.
132*e8d8bef9SDimitry Andric   uint32_t ParameterType = 0;
133*e8d8bef9SDimitry Andric 
1340b57cec5SDimitry Andric   /// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
1350b57cec5SDimitry Andric   int CRSpillFrameIndex = 0;
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   /// If any of CR[2-4] need to be saved in the prologue and restored in the
1380b57cec5SDimitry Andric   /// epilogue then they are added to this array. This is used for the
1390b57cec5SDimitry Andric   /// 64-bit SVR4 ABI.
1405ffd83dbSDimitry Andric   SmallVector<Register, 3> MustSaveCRs;
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   /// Whether this uses the PIC Base register or not.
1430b57cec5SDimitry Andric   bool UsesPICBase = false;
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   /// We keep track attributes for each live-in virtual registers
1460b57cec5SDimitry Andric   /// to use SExt/ZExt flags in later optimization.
1475ffd83dbSDimitry Andric   std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric public:
1505ffd83dbSDimitry Andric   explicit PPCFunctionInfo(const MachineFunction &MF);
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
1530b57cec5SDimitry Andric   void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; }
1560b57cec5SDimitry Andric   void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; }
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   int getBasePointerSaveIndex() const { return BasePointerSaveIndex; }
1590b57cec5SDimitry Andric   void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; }
1620b57cec5SDimitry Andric   void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   unsigned getMinReservedArea() const { return MinReservedArea; }
1650b57cec5SDimitry Andric   void setMinReservedArea(unsigned size) { MinReservedArea = size; }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   int getTailCallSPDelta() const { return TailCallSPDelta; }
1680b57cec5SDimitry Andric   void setTailCallSPDelta(int size) { TailCallSPDelta = size; }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   /// MustSaveLR - This is set when the prolog/epilog inserter does its initial
1710b57cec5SDimitry Andric   /// scan of the function. It is true if the LR/LR8 register is ever explicitly
1720b57cec5SDimitry Andric   /// defined/clobbered in the machine function (e.g. by calls and movpctolr,
1730b57cec5SDimitry Andric   /// which is used in PIC generation), or if the LR stack slot is explicitly
1740b57cec5SDimitry Andric   /// referenced by builtin_return_address.
1750b57cec5SDimitry Andric   void setMustSaveLR(bool U) { MustSaveLR = U; }
1760b57cec5SDimitry Andric   bool mustSaveLR() const    { return MustSaveLR; }
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   void setMustSaveTOC(bool U) { MustSaveTOC = U; }
1790b57cec5SDimitry Andric   bool mustSaveTOC() const    { return MustSaveTOC; }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   /// We certainly don't want to shrink wrap functions if we've emitted a
1820b57cec5SDimitry Andric   /// MovePCtoLR8 as that has to go into the entry, so the prologue definitely
1830b57cec5SDimitry Andric   /// has to go into the entry block.
1840b57cec5SDimitry Andric   void setShrinkWrapDisabled(bool U) { ShrinkWrapDisabled = U; }
1850b57cec5SDimitry Andric   bool shrinkWrapDisabled() const { return ShrinkWrapDisabled; }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   void setHasSpills()      { HasSpills = true; }
1880b57cec5SDimitry Andric   bool hasSpills() const   { return HasSpills; }
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   void setHasNonRISpills()    { HasNonRISpills = true; }
1910b57cec5SDimitry Andric   bool hasNonRISpills() const { return HasNonRISpills; }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   void setSpillsCR()       { SpillsCR = true; }
1940b57cec5SDimitry Andric   bool isCRSpilled() const { return SpillsCR; }
1950b57cec5SDimitry Andric 
1965ffd83dbSDimitry Andric   void setDisableNonVolatileCR() { DisableNonVolatileCR = true; }
1975ffd83dbSDimitry Andric   bool isNonVolatileCRDisabled() const { return DisableNonVolatileCR; }
1985ffd83dbSDimitry Andric 
1990b57cec5SDimitry Andric   void setLRStoreRequired() { LRStoreRequired = true; }
2000b57cec5SDimitry Andric   bool isLRStoreRequired() const { return LRStoreRequired; }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   void setUsesTOCBasePtr()    { UsesTOCBasePtr = true; }
2030b57cec5SDimitry Andric   bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   void setHasFastCall() { HasFastCall = true; }
2060b57cec5SDimitry Andric   bool hasFastCall() const { return HasFastCall;}
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
2090b57cec5SDimitry Andric   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   int getVarArgsStackOffset() const { return VarArgsStackOffset; }
2120b57cec5SDimitry Andric   void setVarArgsStackOffset(int Offset) { VarArgsStackOffset = Offset; }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
2150b57cec5SDimitry Andric   void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
2160b57cec5SDimitry Andric 
217*e8d8bef9SDimitry Andric   unsigned getFixedParamNum() const { return FixedParamNum; }
218*e8d8bef9SDimitry Andric 
219*e8d8bef9SDimitry Andric   unsigned getFloatingPointParamNum() const { return FloatingPointParamNum; }
220*e8d8bef9SDimitry Andric 
221*e8d8bef9SDimitry Andric   uint32_t getParameterType() const { return ParameterType; }
222*e8d8bef9SDimitry Andric   void appendParameterType(ParamType Type);
223*e8d8bef9SDimitry Andric 
2240b57cec5SDimitry Andric   unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
2250b57cec5SDimitry Andric   void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   /// This function associates attributes for each live-in virtual register.
2285ffd83dbSDimitry Andric   void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags) {
2290b57cec5SDimitry Andric     LiveInAttrs.push_back(std::make_pair(VReg, Flags));
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2330b57cec5SDimitry Andric   /// a live-in register and sign-extended.
2345ffd83dbSDimitry Andric   bool isLiveInSExt(Register VReg) const;
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2370b57cec5SDimitry Andric   /// a live-in register and zero-extended.
2385ffd83dbSDimitry Andric   bool isLiveInZExt(Register VReg) const;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   int getCRSpillFrameIndex() const { return CRSpillFrameIndex; }
2410b57cec5SDimitry Andric   void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; }
2420b57cec5SDimitry Andric 
2435ffd83dbSDimitry Andric   const SmallVectorImpl<Register> &
2440b57cec5SDimitry Andric     getMustSaveCRs() const { return MustSaveCRs; }
2455ffd83dbSDimitry Andric   void addMustSaveCR(Register Reg) { MustSaveCRs.push_back(Reg); }
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   void setUsesPICBase(bool uses) { UsesPICBase = uses; }
2480b57cec5SDimitry Andric   bool usesPICBase() const { return UsesPICBase; }
2490b57cec5SDimitry Andric 
2505ffd83dbSDimitry Andric   MCSymbol *getPICOffsetSymbol(MachineFunction &MF) const;
2510b57cec5SDimitry Andric 
2525ffd83dbSDimitry Andric   MCSymbol *getGlobalEPSymbol(MachineFunction &MF) const;
2535ffd83dbSDimitry Andric   MCSymbol *getLocalEPSymbol(MachineFunction &MF) const;
2545ffd83dbSDimitry Andric   MCSymbol *getTOCOffsetSymbol(MachineFunction &MF) const;
2550b57cec5SDimitry Andric };
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric } // end namespace llvm
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
260