1 //===-- X86MachineFunctionInfo.h - X86 machine function info ----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file declares X86-specific per-machine-function information.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_X86_X86MACHINEFUNCTIONINFO_H
14 #define LLVM_LIB_TARGET_X86_X86MACHINEFUNCTIONINFO_H
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/CodeGen/CallingConvLower.h"
19 #include "llvm/CodeGen/MachineFunction.h"
24 /// X86MachineFunctionInfo - This class is derived from MachineFunction and
25 /// contains private X86 target-specific information for each MachineFunction.
26 class X86MachineFunctionInfo
: public MachineFunctionInfo
{
27 virtual void anchor();
29 /// ForceFramePointer - True if the function is required to use of frame
30 /// pointer for reasons other than it containing dynamic allocation or
31 /// that FP eliminatation is turned off. For example, Cygwin main function
32 /// contains stack pointer re-alignment code which requires FP.
33 bool ForceFramePointer
= false;
35 /// RestoreBasePointerOffset - Non-zero if the function has base pointer
36 /// and makes call to llvm.eh.sjlj.setjmp. When non-zero, the value is a
37 /// displacement from the frame pointer to a slot where the base pointer
39 signed char RestoreBasePointerOffset
= 0;
41 /// WinEHXMMSlotInfo - Slot information of XMM registers in the stack frame
43 DenseMap
<int, unsigned> WinEHXMMSlotInfo
;
45 /// CalleeSavedFrameSize - Size of the callee-saved register portion of the
46 /// stack frame in bytes.
47 unsigned CalleeSavedFrameSize
= 0;
49 /// BytesToPopOnReturn - Number of bytes function pops on return (in addition
50 /// to the space used by the return address).
51 /// Used on windows platform for stdcall & fastcall name decoration
52 unsigned BytesToPopOnReturn
= 0;
54 /// ReturnAddrIndex - FrameIndex for return slot.
55 int ReturnAddrIndex
= 0;
57 /// FrameIndex for return slot.
58 int FrameAddrIndex
= 0;
60 /// TailCallReturnAddrDelta - The number of bytes by which return address
61 /// stack slot is moved as the result of tail call optimization.
62 int TailCallReturnAddrDelta
= 0;
64 /// SRetReturnReg - Some subtargets require that sret lowering includes
65 /// returning the value of the returned struct in a register. This field
66 /// holds the virtual register into which the sret argument is passed.
67 Register SRetReturnReg
;
69 /// GlobalBaseReg - keeps track of the virtual register initialized for
70 /// use as the global base register. This is used for PIC in some PIC
71 /// relocation models.
72 Register GlobalBaseReg
;
74 /// VarArgsFrameIndex - FrameIndex for start of varargs area.
75 int VarArgsFrameIndex
= 0;
76 /// RegSaveFrameIndex - X86-64 vararg func register save area.
77 int RegSaveFrameIndex
= 0;
78 /// VarArgsGPOffset - X86-64 vararg func int reg offset.
79 unsigned VarArgsGPOffset
= 0;
80 /// VarArgsFPOffset - X86-64 vararg func fp reg offset.
81 unsigned VarArgsFPOffset
= 0;
82 /// ArgumentStackSize - The number of bytes on stack consumed by the arguments
83 /// being passed on the stack.
84 unsigned ArgumentStackSize
= 0;
85 /// NumLocalDynamics - Number of local-dynamic TLS accesses.
86 unsigned NumLocalDynamics
= 0;
87 /// HasPushSequences - Keeps track of whether this function uses sequences
88 /// of pushes to pass function parameters.
89 bool HasPushSequences
= false;
91 /// True if the function recovers from an SEH exception, and therefore needs
92 /// to spill and restore the frame pointer.
93 bool HasSEHFramePtrSave
= false;
95 /// The frame index of a stack object containing the original frame pointer
96 /// used to address arguments in a function using a base pointer.
97 int SEHFramePtrSaveIndex
= 0;
99 /// True if this function has a subset of CSRs that is handled explicitly via
101 bool IsSplitCSR
= false;
103 /// True if this function uses the red zone.
104 bool UsesRedZone
= false;
106 /// True if this function has DYN_ALLOCA instructions.
107 bool HasDynAlloca
= false;
109 /// True if this function has any preallocated calls.
110 bool HasPreallocatedCall
= false;
112 /// Whether this function has an extended frame record [Ctx, RBP, Return
113 /// addr]. If so, bit 60 of the in-memory frame pointer will be 1 to enable
114 /// other tools to detect the extended record.
115 bool HasSwiftAsyncContext
= false;
117 /// True if this function has tile virtual register. This is used to
118 /// determine if we should insert tilerelease in frame lowering.
119 bool HasVirtualTileReg
= false;
121 /// Ajust stack for push2/pop2
122 bool PadForPush2Pop2
= false;
124 /// Candidate registers for push2/pop2
125 std::set
<Register
> CandidatesForPush2Pop2
;
127 /// True if this function has CFI directives that adjust the CFA.
128 /// This is used to determine if we should direct the debugger to use
129 /// the CFA instead of the stack pointer.
130 bool HasCFIAdjustCfa
= false;
132 MachineInstr
*StackPtrSaveMI
= nullptr;
134 std::optional
<int> SwiftAsyncContextFrameIdx
;
136 // Preallocated fields are only used during isel.
137 // FIXME: Can we find somewhere else to store these?
138 DenseMap
<const Value
*, size_t> PreallocatedIds
;
139 SmallVector
<size_t, 0> PreallocatedStackSizes
;
140 SmallVector
<SmallVector
<size_t, 4>, 0> PreallocatedArgOffsets
;
143 /// ForwardedMustTailRegParms - A list of virtual and physical registers
144 /// that must be forwarded to every musttail call.
145 SmallVector
<ForwardedRegister
, 1> ForwardedMustTailRegParms
;
148 X86MachineFunctionInfo() = default;
149 X86MachineFunctionInfo(const Function
&F
, const TargetSubtargetInfo
*STI
) {}
151 X86MachineFunctionInfo(const X86MachineFunctionInfo
&) = default;
153 MachineFunctionInfo
*
154 clone(BumpPtrAllocator
&Allocator
, MachineFunction
&DestMF
,
155 const DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> &Src2DstMBB
)
158 bool getForceFramePointer() const { return ForceFramePointer
;}
159 void setForceFramePointer(bool forceFP
) { ForceFramePointer
= forceFP
; }
161 bool getHasPushSequences() const { return HasPushSequences
; }
162 void setHasPushSequences(bool HasPush
) { HasPushSequences
= HasPush
; }
164 bool getRestoreBasePointer() const { return RestoreBasePointerOffset
!=0; }
165 void setRestoreBasePointer(const MachineFunction
*MF
);
166 void setRestoreBasePointer(unsigned CalleeSavedFrameSize
) {
167 RestoreBasePointerOffset
= -CalleeSavedFrameSize
;
169 int getRestoreBasePointerOffset() const {return RestoreBasePointerOffset
; }
171 DenseMap
<int, unsigned>& getWinEHXMMSlotInfo() { return WinEHXMMSlotInfo
; }
172 const DenseMap
<int, unsigned>& getWinEHXMMSlotInfo() const {
173 return WinEHXMMSlotInfo
; }
175 unsigned getCalleeSavedFrameSize() const {
176 return CalleeSavedFrameSize
+ 8 * padForPush2Pop2();
178 void setCalleeSavedFrameSize(unsigned bytes
) { CalleeSavedFrameSize
= bytes
; }
180 unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn
; }
181 void setBytesToPopOnReturn (unsigned bytes
) { BytesToPopOnReturn
= bytes
;}
183 int getRAIndex() const { return ReturnAddrIndex
; }
184 void setRAIndex(int Index
) { ReturnAddrIndex
= Index
; }
186 int getFAIndex() const { return FrameAddrIndex
; }
187 void setFAIndex(int Index
) { FrameAddrIndex
= Index
; }
189 int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta
; }
190 void setTCReturnAddrDelta(int delta
) {TailCallReturnAddrDelta
= delta
;}
192 Register
getSRetReturnReg() const { return SRetReturnReg
; }
193 void setSRetReturnReg(Register Reg
) { SRetReturnReg
= Reg
; }
195 Register
getGlobalBaseReg() const { return GlobalBaseReg
; }
196 void setGlobalBaseReg(Register Reg
) { GlobalBaseReg
= Reg
; }
198 int getVarArgsFrameIndex() const { return VarArgsFrameIndex
; }
199 void setVarArgsFrameIndex(int Idx
) { VarArgsFrameIndex
= Idx
; }
201 int getRegSaveFrameIndex() const { return RegSaveFrameIndex
; }
202 void setRegSaveFrameIndex(int Idx
) { RegSaveFrameIndex
= Idx
; }
204 unsigned getVarArgsGPOffset() const { return VarArgsGPOffset
; }
205 void setVarArgsGPOffset(unsigned Offset
) { VarArgsGPOffset
= Offset
; }
207 unsigned getVarArgsFPOffset() const { return VarArgsFPOffset
; }
208 void setVarArgsFPOffset(unsigned Offset
) { VarArgsFPOffset
= Offset
; }
210 unsigned getArgumentStackSize() const { return ArgumentStackSize
; }
211 void setArgumentStackSize(unsigned size
) { ArgumentStackSize
= size
; }
213 unsigned getNumLocalDynamicTLSAccesses() const { return NumLocalDynamics
; }
214 void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamics
; }
216 bool getHasSEHFramePtrSave() const { return HasSEHFramePtrSave
; }
217 void setHasSEHFramePtrSave(bool V
) { HasSEHFramePtrSave
= V
; }
219 int getSEHFramePtrSaveIndex() const { return SEHFramePtrSaveIndex
; }
220 void setSEHFramePtrSaveIndex(int Index
) { SEHFramePtrSaveIndex
= Index
; }
222 SmallVectorImpl
<ForwardedRegister
> &getForwardedMustTailRegParms() {
223 return ForwardedMustTailRegParms
;
226 bool isSplitCSR() const { return IsSplitCSR
; }
227 void setIsSplitCSR(bool s
) { IsSplitCSR
= s
; }
229 bool getUsesRedZone() const { return UsesRedZone
; }
230 void setUsesRedZone(bool V
) { UsesRedZone
= V
; }
232 bool hasDynAlloca() const { return HasDynAlloca
; }
233 void setHasDynAlloca(bool v
) { HasDynAlloca
= v
; }
235 bool hasPreallocatedCall() const { return HasPreallocatedCall
; }
236 void setHasPreallocatedCall(bool v
) { HasPreallocatedCall
= v
; }
238 bool hasSwiftAsyncContext() const { return HasSwiftAsyncContext
; }
239 void setHasSwiftAsyncContext(bool v
) { HasSwiftAsyncContext
= v
; }
241 bool hasVirtualTileReg() const { return HasVirtualTileReg
; }
242 void setHasVirtualTileReg(bool v
) { HasVirtualTileReg
= v
; }
244 bool padForPush2Pop2() const { return PadForPush2Pop2
; }
245 void setPadForPush2Pop2(bool V
) { PadForPush2Pop2
= V
; }
247 bool isCandidateForPush2Pop2(Register Reg
) const {
248 return CandidatesForPush2Pop2
.find(Reg
) != CandidatesForPush2Pop2
.end();
250 void addCandidateForPush2Pop2(Register Reg
) {
251 CandidatesForPush2Pop2
.insert(Reg
);
253 size_t getNumCandidatesForPush2Pop2() const {
254 return CandidatesForPush2Pop2
.size();
257 bool hasCFIAdjustCfa() const { return HasCFIAdjustCfa
; }
258 void setHasCFIAdjustCfa(bool v
) { HasCFIAdjustCfa
= v
; }
260 void setStackPtrSaveMI(MachineInstr
*MI
) { StackPtrSaveMI
= MI
; }
261 MachineInstr
*getStackPtrSaveMI() const { return StackPtrSaveMI
; }
263 std::optional
<int> getSwiftAsyncContextFrameIdx() const {
264 return SwiftAsyncContextFrameIdx
;
266 void setSwiftAsyncContextFrameIdx(int v
) { SwiftAsyncContextFrameIdx
= v
; }
268 size_t getPreallocatedIdForCallSite(const Value
*CS
) {
269 auto Insert
= PreallocatedIds
.insert({CS
, PreallocatedIds
.size()});
271 PreallocatedStackSizes
.push_back(0);
272 PreallocatedArgOffsets
.emplace_back();
274 return Insert
.first
->second
;
277 void setPreallocatedStackSize(size_t Id
, size_t StackSize
) {
278 PreallocatedStackSizes
[Id
] = StackSize
;
281 size_t getPreallocatedStackSize(const size_t Id
) {
282 assert(PreallocatedStackSizes
[Id
] != 0 && "stack size not set");
283 return PreallocatedStackSizes
[Id
];
286 void setPreallocatedArgOffsets(size_t Id
, ArrayRef
<size_t> AO
) {
287 PreallocatedArgOffsets
[Id
].assign(AO
.begin(), AO
.end());
290 ArrayRef
<size_t> getPreallocatedArgOffsets(const size_t Id
) {
291 assert(!PreallocatedArgOffsets
[Id
].empty() && "arg offsets not set");
292 return PreallocatedArgOffsets
[Id
];
296 } // End llvm namespace