xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- PPCMachineFunctionInfo.h - Private data used for PowerPC --*- C++ -*-=//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file declares the PowerPC specific subclass of MachineFunctionInfo.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
17*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
18*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetCallingConv.h"
19*0b57cec5SDimitry Andric 
20*0b57cec5SDimitry Andric namespace llvm {
21*0b57cec5SDimitry Andric 
22*0b57cec5SDimitry Andric /// PPCFunctionInfo - This class is derived from MachineFunction private
23*0b57cec5SDimitry Andric /// PowerPC target-specific information for each MachineFunction.
24*0b57cec5SDimitry Andric class PPCFunctionInfo : public MachineFunctionInfo {
25*0b57cec5SDimitry Andric   virtual void anchor();
26*0b57cec5SDimitry Andric 
27*0b57cec5SDimitry Andric   /// FramePointerSaveIndex - Frame index of where the old frame pointer is
28*0b57cec5SDimitry Andric   /// stored.  Also used as an anchor for instructions that need to be altered
29*0b57cec5SDimitry Andric   /// when using frame pointers (dyna_add, dyna_sub.)
30*0b57cec5SDimitry Andric   int FramePointerSaveIndex = 0;
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric   /// ReturnAddrSaveIndex - Frame index of where the return address is stored.
33*0b57cec5SDimitry Andric   ///
34*0b57cec5SDimitry Andric   int ReturnAddrSaveIndex = 0;
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric   /// Frame index where the old base pointer is stored.
37*0b57cec5SDimitry Andric   int BasePointerSaveIndex = 0;
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric   /// Frame index where the old PIC base pointer is stored.
40*0b57cec5SDimitry Andric   int PICBasePointerSaveIndex = 0;
41*0b57cec5SDimitry Andric 
42*0b57cec5SDimitry Andric   /// MustSaveLR - Indicates whether LR is defined (or clobbered) in the current
43*0b57cec5SDimitry Andric   /// function.  This is only valid after the initial scan of the function by
44*0b57cec5SDimitry Andric   /// PEI.
45*0b57cec5SDimitry Andric   bool MustSaveLR;
46*0b57cec5SDimitry Andric 
47*0b57cec5SDimitry Andric   /// MustSaveTOC - Indicates that the TOC save needs to be performed in the
48*0b57cec5SDimitry Andric   /// prologue of the function. This is typically the case when there are
49*0b57cec5SDimitry Andric   /// indirect calls in the function and it is more profitable to save the
50*0b57cec5SDimitry Andric   /// TOC pointer in the prologue than in the block(s) containing the call(s).
51*0b57cec5SDimitry Andric   bool MustSaveTOC = false;
52*0b57cec5SDimitry Andric 
53*0b57cec5SDimitry Andric   /// Do we have to disable shrink-wrapping? This has to be set if we emit any
54*0b57cec5SDimitry Andric   /// instructions that clobber LR in the entry block because discovering this
55*0b57cec5SDimitry Andric   /// in PEI is too late (happens after shrink-wrapping);
56*0b57cec5SDimitry Andric   bool ShrinkWrapDisabled = false;
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric   /// Does this function have any stack spills.
59*0b57cec5SDimitry Andric   bool HasSpills = false;
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric   /// Does this function spill using instructions with only r+r (not r+i)
62*0b57cec5SDimitry Andric   /// forms.
63*0b57cec5SDimitry Andric   bool HasNonRISpills = false;
64*0b57cec5SDimitry Andric 
65*0b57cec5SDimitry Andric   /// SpillsCR - Indicates whether CR is spilled in the current function.
66*0b57cec5SDimitry Andric   bool SpillsCR = false;
67*0b57cec5SDimitry Andric 
68*0b57cec5SDimitry Andric   /// Indicates whether VRSAVE is spilled in the current function.
69*0b57cec5SDimitry Andric   bool SpillsVRSAVE = false;
70*0b57cec5SDimitry Andric 
71*0b57cec5SDimitry Andric   /// LRStoreRequired - The bool indicates whether there is some explicit use of
72*0b57cec5SDimitry Andric   /// the LR/LR8 stack slot that is not obvious from scanning the code.  This
73*0b57cec5SDimitry Andric   /// requires that the code generator produce a store of LR to the stack on
74*0b57cec5SDimitry Andric   /// entry, even though LR may otherwise apparently not be used.
75*0b57cec5SDimitry Andric   bool LRStoreRequired = false;
76*0b57cec5SDimitry Andric 
77*0b57cec5SDimitry Andric   /// This function makes use of the PPC64 ELF TOC base pointer (register r2).
78*0b57cec5SDimitry Andric   bool UsesTOCBasePtr = false;
79*0b57cec5SDimitry Andric 
80*0b57cec5SDimitry Andric   /// MinReservedArea - This is the frame size that is at least reserved in a
81*0b57cec5SDimitry Andric   /// potential caller (parameter+linkage area).
82*0b57cec5SDimitry Andric   unsigned MinReservedArea = 0;
83*0b57cec5SDimitry Andric 
84*0b57cec5SDimitry Andric   /// TailCallSPDelta - Stack pointer delta used when tail calling. Maximum
85*0b57cec5SDimitry Andric   /// amount the stack pointer is adjusted to make the frame bigger for tail
86*0b57cec5SDimitry Andric   /// calls. Used for creating an area before the register spill area.
87*0b57cec5SDimitry Andric   int TailCallSPDelta = 0;
88*0b57cec5SDimitry Andric 
89*0b57cec5SDimitry Andric   /// HasFastCall - Does this function contain a fast call. Used to determine
90*0b57cec5SDimitry Andric   /// how the caller's stack pointer should be calculated (epilog/dynamicalloc).
91*0b57cec5SDimitry Andric   bool HasFastCall = false;
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
94*0b57cec5SDimitry Andric   int VarArgsFrameIndex = 0;
95*0b57cec5SDimitry Andric 
96*0b57cec5SDimitry Andric   /// VarArgsStackOffset - StackOffset for start of stack
97*0b57cec5SDimitry Andric   /// arguments.
98*0b57cec5SDimitry Andric 
99*0b57cec5SDimitry Andric   int VarArgsStackOffset = 0;
100*0b57cec5SDimitry Andric 
101*0b57cec5SDimitry Andric   /// VarArgsNumGPR - Index of the first unused integer
102*0b57cec5SDimitry Andric   /// register for parameter passing.
103*0b57cec5SDimitry Andric   unsigned VarArgsNumGPR = 0;
104*0b57cec5SDimitry Andric 
105*0b57cec5SDimitry Andric   /// VarArgsNumFPR - Index of the first unused double
106*0b57cec5SDimitry Andric   /// register for parameter passing.
107*0b57cec5SDimitry Andric   unsigned VarArgsNumFPR = 0;
108*0b57cec5SDimitry Andric 
109*0b57cec5SDimitry Andric   /// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
110*0b57cec5SDimitry Andric   int CRSpillFrameIndex = 0;
111*0b57cec5SDimitry Andric 
112*0b57cec5SDimitry Andric   /// If any of CR[2-4] need to be saved in the prologue and restored in the
113*0b57cec5SDimitry Andric   /// epilogue then they are added to this array. This is used for the
114*0b57cec5SDimitry Andric   /// 64-bit SVR4 ABI.
115*0b57cec5SDimitry Andric   SmallVector<unsigned, 3> MustSaveCRs;
116*0b57cec5SDimitry Andric 
117*0b57cec5SDimitry Andric   /// Hold onto our MachineFunction context.
118*0b57cec5SDimitry Andric   MachineFunction &MF;
119*0b57cec5SDimitry Andric 
120*0b57cec5SDimitry Andric   /// Whether this uses the PIC Base register or not.
121*0b57cec5SDimitry Andric   bool UsesPICBase = false;
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric   /// True if this function has a subset of CSRs that is handled explicitly via
124*0b57cec5SDimitry Andric   /// copies
125*0b57cec5SDimitry Andric   bool IsSplitCSR = false;
126*0b57cec5SDimitry Andric 
127*0b57cec5SDimitry Andric   /// We keep track attributes for each live-in virtual registers
128*0b57cec5SDimitry Andric   /// to use SExt/ZExt flags in later optimization.
129*0b57cec5SDimitry Andric   std::vector<std::pair<unsigned, ISD::ArgFlagsTy>> LiveInAttrs;
130*0b57cec5SDimitry Andric 
131*0b57cec5SDimitry Andric public:
132*0b57cec5SDimitry Andric   explicit PPCFunctionInfo(MachineFunction &MF) : MF(MF) {}
133*0b57cec5SDimitry Andric 
134*0b57cec5SDimitry Andric   int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
135*0b57cec5SDimitry Andric   void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
136*0b57cec5SDimitry Andric 
137*0b57cec5SDimitry Andric   int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; }
138*0b57cec5SDimitry Andric   void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; }
139*0b57cec5SDimitry Andric 
140*0b57cec5SDimitry Andric   int getBasePointerSaveIndex() const { return BasePointerSaveIndex; }
141*0b57cec5SDimitry Andric   void setBasePointerSaveIndex(int Idx) { BasePointerSaveIndex = Idx; }
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric   int getPICBasePointerSaveIndex() const { return PICBasePointerSaveIndex; }
144*0b57cec5SDimitry Andric   void setPICBasePointerSaveIndex(int Idx) { PICBasePointerSaveIndex = Idx; }
145*0b57cec5SDimitry Andric 
146*0b57cec5SDimitry Andric   unsigned getMinReservedArea() const { return MinReservedArea; }
147*0b57cec5SDimitry Andric   void setMinReservedArea(unsigned size) { MinReservedArea = size; }
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric   int getTailCallSPDelta() const { return TailCallSPDelta; }
150*0b57cec5SDimitry Andric   void setTailCallSPDelta(int size) { TailCallSPDelta = size; }
151*0b57cec5SDimitry Andric 
152*0b57cec5SDimitry Andric   /// MustSaveLR - This is set when the prolog/epilog inserter does its initial
153*0b57cec5SDimitry Andric   /// scan of the function. It is true if the LR/LR8 register is ever explicitly
154*0b57cec5SDimitry Andric   /// defined/clobbered in the machine function (e.g. by calls and movpctolr,
155*0b57cec5SDimitry Andric   /// which is used in PIC generation), or if the LR stack slot is explicitly
156*0b57cec5SDimitry Andric   /// referenced by builtin_return_address.
157*0b57cec5SDimitry Andric   void setMustSaveLR(bool U) { MustSaveLR = U; }
158*0b57cec5SDimitry Andric   bool mustSaveLR() const    { return MustSaveLR; }
159*0b57cec5SDimitry Andric 
160*0b57cec5SDimitry Andric   void setMustSaveTOC(bool U) { MustSaveTOC = U; }
161*0b57cec5SDimitry Andric   bool mustSaveTOC() const    { return MustSaveTOC; }
162*0b57cec5SDimitry Andric 
163*0b57cec5SDimitry Andric   /// We certainly don't want to shrink wrap functions if we've emitted a
164*0b57cec5SDimitry Andric   /// MovePCtoLR8 as that has to go into the entry, so the prologue definitely
165*0b57cec5SDimitry Andric   /// has to go into the entry block.
166*0b57cec5SDimitry Andric   void setShrinkWrapDisabled(bool U) { ShrinkWrapDisabled = U; }
167*0b57cec5SDimitry Andric   bool shrinkWrapDisabled() const { return ShrinkWrapDisabled; }
168*0b57cec5SDimitry Andric 
169*0b57cec5SDimitry Andric   void setHasSpills()      { HasSpills = true; }
170*0b57cec5SDimitry Andric   bool hasSpills() const   { return HasSpills; }
171*0b57cec5SDimitry Andric 
172*0b57cec5SDimitry Andric   void setHasNonRISpills()    { HasNonRISpills = true; }
173*0b57cec5SDimitry Andric   bool hasNonRISpills() const { return HasNonRISpills; }
174*0b57cec5SDimitry Andric 
175*0b57cec5SDimitry Andric   void setSpillsCR()       { SpillsCR = true; }
176*0b57cec5SDimitry Andric   bool isCRSpilled() const { return SpillsCR; }
177*0b57cec5SDimitry Andric 
178*0b57cec5SDimitry Andric   void setSpillsVRSAVE()       { SpillsVRSAVE = true; }
179*0b57cec5SDimitry Andric   bool isVRSAVESpilled() const { return SpillsVRSAVE; }
180*0b57cec5SDimitry Andric 
181*0b57cec5SDimitry Andric   void setLRStoreRequired() { LRStoreRequired = true; }
182*0b57cec5SDimitry Andric   bool isLRStoreRequired() const { return LRStoreRequired; }
183*0b57cec5SDimitry Andric 
184*0b57cec5SDimitry Andric   void setUsesTOCBasePtr()    { UsesTOCBasePtr = true; }
185*0b57cec5SDimitry Andric   bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
186*0b57cec5SDimitry Andric 
187*0b57cec5SDimitry Andric   void setHasFastCall() { HasFastCall = true; }
188*0b57cec5SDimitry Andric   bool hasFastCall() const { return HasFastCall;}
189*0b57cec5SDimitry Andric 
190*0b57cec5SDimitry Andric   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
191*0b57cec5SDimitry Andric   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
192*0b57cec5SDimitry Andric 
193*0b57cec5SDimitry Andric   int getVarArgsStackOffset() const { return VarArgsStackOffset; }
194*0b57cec5SDimitry Andric   void setVarArgsStackOffset(int Offset) { VarArgsStackOffset = Offset; }
195*0b57cec5SDimitry Andric 
196*0b57cec5SDimitry Andric   unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
197*0b57cec5SDimitry Andric   void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
198*0b57cec5SDimitry Andric 
199*0b57cec5SDimitry Andric   unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
200*0b57cec5SDimitry Andric   void setVarArgsNumFPR(unsigned Num) { VarArgsNumFPR = Num; }
201*0b57cec5SDimitry Andric 
202*0b57cec5SDimitry Andric   /// This function associates attributes for each live-in virtual register.
203*0b57cec5SDimitry Andric   void addLiveInAttr(unsigned VReg, ISD::ArgFlagsTy Flags) {
204*0b57cec5SDimitry Andric     LiveInAttrs.push_back(std::make_pair(VReg, Flags));
205*0b57cec5SDimitry Andric   }
206*0b57cec5SDimitry Andric 
207*0b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
208*0b57cec5SDimitry Andric   /// a live-in register and sign-extended.
209*0b57cec5SDimitry Andric   bool isLiveInSExt(unsigned VReg) const;
210*0b57cec5SDimitry Andric 
211*0b57cec5SDimitry Andric   /// This function returns true if the specified vreg is
212*0b57cec5SDimitry Andric   /// a live-in register and zero-extended.
213*0b57cec5SDimitry Andric   bool isLiveInZExt(unsigned VReg) const;
214*0b57cec5SDimitry Andric 
215*0b57cec5SDimitry Andric   int getCRSpillFrameIndex() const { return CRSpillFrameIndex; }
216*0b57cec5SDimitry Andric   void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; }
217*0b57cec5SDimitry Andric 
218*0b57cec5SDimitry Andric   const SmallVectorImpl<unsigned> &
219*0b57cec5SDimitry Andric     getMustSaveCRs() const { return MustSaveCRs; }
220*0b57cec5SDimitry Andric   void addMustSaveCR(unsigned Reg) { MustSaveCRs.push_back(Reg); }
221*0b57cec5SDimitry Andric 
222*0b57cec5SDimitry Andric   void setUsesPICBase(bool uses) { UsesPICBase = uses; }
223*0b57cec5SDimitry Andric   bool usesPICBase() const { return UsesPICBase; }
224*0b57cec5SDimitry Andric 
225*0b57cec5SDimitry Andric   bool isSplitCSR() const { return IsSplitCSR; }
226*0b57cec5SDimitry Andric   void setIsSplitCSR(bool s) { IsSplitCSR = s; }
227*0b57cec5SDimitry Andric 
228*0b57cec5SDimitry Andric   MCSymbol *getPICOffsetSymbol() const;
229*0b57cec5SDimitry Andric 
230*0b57cec5SDimitry Andric   MCSymbol *getGlobalEPSymbol() const;
231*0b57cec5SDimitry Andric   MCSymbol *getLocalEPSymbol() const;
232*0b57cec5SDimitry Andric   MCSymbol *getTOCOffsetSymbol() const;
233*0b57cec5SDimitry Andric };
234*0b57cec5SDimitry Andric 
235*0b57cec5SDimitry Andric } // end namespace llvm
236*0b57cec5SDimitry Andric 
237*0b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
238