xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
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 {
250b57cec5SDimitry Andric   virtual void anchor();
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric   /// FramePointerSaveIndex - Frame index of where the old frame pointer is
280b57cec5SDimitry Andric   /// stored.  Also used as an anchor for instructions that need to be altered
290b57cec5SDimitry Andric   /// when using frame pointers (dyna_add, dyna_sub.)
300b57cec5SDimitry Andric   int FramePointerSaveIndex = 0;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   /// ReturnAddrSaveIndex - Frame index of where the return address is stored.
330b57cec5SDimitry Andric   ///
340b57cec5SDimitry Andric   int ReturnAddrSaveIndex = 0;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric   /// Frame index where the old base pointer is stored.
370b57cec5SDimitry Andric   int BasePointerSaveIndex = 0;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   /// Frame index where the old PIC base pointer is stored.
400b57cec5SDimitry Andric   int PICBasePointerSaveIndex = 0;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   /// MustSaveLR - Indicates whether LR is defined (or clobbered) in the current
430b57cec5SDimitry Andric   /// function.  This is only valid after the initial scan of the function by
440b57cec5SDimitry Andric   /// PEI.
45480093f4SDimitry Andric   bool MustSaveLR = false;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric   /// MustSaveTOC - Indicates that the TOC save needs to be performed in the
480b57cec5SDimitry Andric   /// prologue of the function. This is typically the case when there are
490b57cec5SDimitry Andric   /// indirect calls in the function and it is more profitable to save the
500b57cec5SDimitry Andric   /// TOC pointer in the prologue than in the block(s) containing the call(s).
510b57cec5SDimitry Andric   bool MustSaveTOC = false;
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   /// Do we have to disable shrink-wrapping? This has to be set if we emit any
540b57cec5SDimitry Andric   /// instructions that clobber LR in the entry block because discovering this
550b57cec5SDimitry Andric   /// in PEI is too late (happens after shrink-wrapping);
560b57cec5SDimitry Andric   bool ShrinkWrapDisabled = false;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   /// Does this function have any stack spills.
590b57cec5SDimitry Andric   bool HasSpills = false;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   /// Does this function spill using instructions with only r+r (not r+i)
620b57cec5SDimitry Andric   /// forms.
630b57cec5SDimitry Andric   bool HasNonRISpills = false;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   /// SpillsCR - Indicates whether CR is spilled in the current function.
660b57cec5SDimitry Andric   bool SpillsCR = false;
670b57cec5SDimitry Andric 
68*5ffd83dbSDimitry Andric   /// DisableNonVolatileCR - Indicates whether non-volatile CR fields would be
69*5ffd83dbSDimitry Andric   /// disabled.
70*5ffd83dbSDimitry Andric   bool DisableNonVolatileCR = false;
71*5ffd83dbSDimitry Andric 
720b57cec5SDimitry Andric   /// Indicates whether VRSAVE is spilled in the current function.
730b57cec5SDimitry Andric   bool SpillsVRSAVE = false;
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   /// LRStoreRequired - The bool indicates whether there is some explicit use of
760b57cec5SDimitry Andric   /// the LR/LR8 stack slot that is not obvious from scanning the code.  This
770b57cec5SDimitry Andric   /// requires that the code generator produce a store of LR to the stack on
780b57cec5SDimitry Andric   /// entry, even though LR may otherwise apparently not be used.
790b57cec5SDimitry Andric   bool LRStoreRequired = false;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   /// This function makes use of the PPC64 ELF TOC base pointer (register r2).
820b57cec5SDimitry Andric   bool UsesTOCBasePtr = false;
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   /// MinReservedArea - This is the frame size that is at least reserved in a
850b57cec5SDimitry Andric   /// potential caller (parameter+linkage area).
860b57cec5SDimitry Andric   unsigned MinReservedArea = 0;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   /// TailCallSPDelta - Stack pointer delta used when tail calling. Maximum
890b57cec5SDimitry Andric   /// amount the stack pointer is adjusted to make the frame bigger for tail
900b57cec5SDimitry Andric   /// calls. Used for creating an area before the register spill area.
910b57cec5SDimitry Andric   int TailCallSPDelta = 0;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   /// HasFastCall - Does this function contain a fast call. Used to determine
940b57cec5SDimitry Andric   /// how the caller's stack pointer should be calculated (epilog/dynamicalloc).
950b57cec5SDimitry Andric   bool HasFastCall = false;
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
980b57cec5SDimitry Andric   int VarArgsFrameIndex = 0;
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   /// VarArgsStackOffset - StackOffset for start of stack
1010b57cec5SDimitry Andric   /// arguments.
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   int VarArgsStackOffset = 0;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   /// VarArgsNumGPR - Index of the first unused integer
1060b57cec5SDimitry Andric   /// register for parameter passing.
1070b57cec5SDimitry Andric   unsigned VarArgsNumGPR = 0;
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   /// VarArgsNumFPR - Index of the first unused double
1100b57cec5SDimitry Andric   /// register for parameter passing.
1110b57cec5SDimitry Andric   unsigned VarArgsNumFPR = 0;
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   /// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
1140b57cec5SDimitry Andric   int CRSpillFrameIndex = 0;
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   /// If any of CR[2-4] need to be saved in the prologue and restored in the
1170b57cec5SDimitry Andric   /// epilogue then they are added to this array. This is used for the
1180b57cec5SDimitry Andric   /// 64-bit SVR4 ABI.
119*5ffd83dbSDimitry Andric   SmallVector<Register, 3> MustSaveCRs;
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   /// Whether this uses the PIC Base register or not.
1220b57cec5SDimitry Andric   bool UsesPICBase = false;
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   /// We keep track attributes for each live-in virtual registers
1250b57cec5SDimitry Andric   /// to use SExt/ZExt flags in later optimization.
126*5ffd83dbSDimitry Andric   std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric public:
129*5ffd83dbSDimitry Andric   explicit PPCFunctionInfo(const MachineFunction &MF);
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
1320b57cec5SDimitry Andric   void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; }
1350b57cec5SDimitry Andric   void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   int getBasePointerSaveIndex() const { return BasePointerSaveIndex; }
1380b57cec5SDimitry Andric   void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; }
1410b57cec5SDimitry Andric   void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   unsigned getMinReservedArea() const { return MinReservedArea; }
1440b57cec5SDimitry Andric   void setMinReservedArea(unsigned size) { MinReservedArea = size; }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   int getTailCallSPDelta() const { return TailCallSPDelta; }
1470b57cec5SDimitry Andric   void setTailCallSPDelta(int size) { TailCallSPDelta = size; }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   /// MustSaveLR - This is set when the prolog/epilog inserter does its initial
1500b57cec5SDimitry Andric   /// scan of the function. It is true if the LR/LR8 register is ever explicitly
1510b57cec5SDimitry Andric   /// defined/clobbered in the machine function (e.g. by calls and movpctolr,
1520b57cec5SDimitry Andric   /// which is used in PIC generation), or if the LR stack slot is explicitly
1530b57cec5SDimitry Andric   /// referenced by builtin_return_address.
1540b57cec5SDimitry Andric   void setMustSaveLR(bool U) { MustSaveLR = U; }
1550b57cec5SDimitry Andric   bool mustSaveLR() const    { return MustSaveLR; }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   void setMustSaveTOC(bool U) { MustSaveTOC = U; }
1580b57cec5SDimitry Andric   bool mustSaveTOC() const    { return MustSaveTOC; }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   /// We certainly don't want to shrink wrap functions if we've emitted a
1610b57cec5SDimitry Andric   /// MovePCtoLR8 as that has to go into the entry, so the prologue definitely
1620b57cec5SDimitry Andric   /// has to go into the entry block.
1630b57cec5SDimitry Andric   void setShrinkWrapDisabled(bool U) { ShrinkWrapDisabled = U; }
1640b57cec5SDimitry Andric   bool shrinkWrapDisabled() const { return ShrinkWrapDisabled; }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   void setHasSpills()      { HasSpills = true; }
1670b57cec5SDimitry Andric   bool hasSpills() const   { return HasSpills; }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   void setHasNonRISpills()    { HasNonRISpills = true; }
1700b57cec5SDimitry Andric   bool hasNonRISpills() const { return HasNonRISpills; }
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   void setSpillsCR()       { SpillsCR = true; }
1730b57cec5SDimitry Andric   bool isCRSpilled() const { return SpillsCR; }
1740b57cec5SDimitry Andric 
175*5ffd83dbSDimitry Andric   void setDisableNonVolatileCR() { DisableNonVolatileCR = true; }
176*5ffd83dbSDimitry Andric   bool isNonVolatileCRDisabled() const { return DisableNonVolatileCR; }
177*5ffd83dbSDimitry Andric 
1780b57cec5SDimitry Andric   void setSpillsVRSAVE()       { SpillsVRSAVE = true; }
1790b57cec5SDimitry Andric   bool isVRSAVESpilled() const { return SpillsVRSAVE; }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   void setLRStoreRequired() { LRStoreRequired = true; }
1820b57cec5SDimitry Andric   bool isLRStoreRequired() const { return LRStoreRequired; }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   void setUsesTOCBasePtr()    { UsesTOCBasePtr = true; }
1850b57cec5SDimitry Andric   bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   void setHasFastCall() { HasFastCall = true; }
1880b57cec5SDimitry Andric   bool hasFastCall() const { return HasFastCall;}
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
1910b57cec5SDimitry Andric   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   int getVarArgsStackOffset() const { return VarArgsStackOffset; }
1940b57cec5SDimitry Andric   void setVarArgsStackOffset(int Offset) { VarArgsStackOffset = Offset; }
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
1970b57cec5SDimitry Andric   void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
2000b57cec5SDimitry Andric   void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   /// This function associates attributes for each live-in virtual register.
203*5ffd83dbSDimitry Andric   void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags) {
2040b57cec5SDimitry Andric     LiveInAttrs.push_back(std::make_pair(VReg, Flags));
2050b57cec5SDimitry Andric   }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2080b57cec5SDimitry Andric   /// a live-in register and sign-extended.
209*5ffd83dbSDimitry Andric   bool isLiveInSExt(Register VReg) const;
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
2120b57cec5SDimitry Andric   /// a live-in register and zero-extended.
213*5ffd83dbSDimitry Andric   bool isLiveInZExt(Register VReg) const;
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   int getCRSpillFrameIndex() const { return CRSpillFrameIndex; }
2160b57cec5SDimitry Andric   void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; }
2170b57cec5SDimitry Andric 
218*5ffd83dbSDimitry Andric   const SmallVectorImpl<Register> &
2190b57cec5SDimitry Andric     getMustSaveCRs() const { return MustSaveCRs; }
220*5ffd83dbSDimitry Andric   void addMustSaveCR(Register Reg) { MustSaveCRs.push_back(Reg); }
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   void setUsesPICBase(bool uses) { UsesPICBase = uses; }
2230b57cec5SDimitry Andric   bool usesPICBase() const { return UsesPICBase; }
2240b57cec5SDimitry Andric 
225*5ffd83dbSDimitry Andric   MCSymbol *getPICOffsetSymbol(MachineFunction &MF) const;
2260b57cec5SDimitry Andric 
227*5ffd83dbSDimitry Andric   MCSymbol *getGlobalEPSymbol(MachineFunction &MF) const;
228*5ffd83dbSDimitry Andric   MCSymbol *getLocalEPSymbol(MachineFunction &MF) const;
229*5ffd83dbSDimitry Andric   MCSymbol *getTOCOffsetSymbol(MachineFunction &MF) const;
2300b57cec5SDimitry Andric };
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric } // end namespace llvm
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
235