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/MIRYamlMapping.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/Support/YAMLTraits.h"
26 enum AMXProgModelEnum
{ None
= 0, DirectReg
= 1, ManagedRA
= 2 };
28 class X86MachineFunctionInfo
;
31 template <> struct ScalarEnumerationTraits
<AMXProgModelEnum
> {
32 static void enumeration(IO
&YamlIO
, AMXProgModelEnum
&Value
) {
33 YamlIO
.enumCase(Value
, "None", AMXProgModelEnum::None
);
34 YamlIO
.enumCase(Value
, "DirectReg", AMXProgModelEnum::DirectReg
);
35 YamlIO
.enumCase(Value
, "ManagedRA", AMXProgModelEnum::ManagedRA
);
39 struct X86MachineFunctionInfo final
: public yaml::MachineFunctionInfo
{
40 AMXProgModelEnum AMXProgModel
;
42 X86MachineFunctionInfo() = default;
43 X86MachineFunctionInfo(const llvm::X86MachineFunctionInfo
&MFI
);
45 void mappingImpl(yaml::IO
&YamlIO
) override
;
46 ~X86MachineFunctionInfo() = default;
49 template <> struct MappingTraits
<X86MachineFunctionInfo
> {
50 static void mapping(IO
&YamlIO
, X86MachineFunctionInfo
&MFI
) {
51 YamlIO
.mapOptional("amxProgModel", MFI
.AMXProgModel
);
54 } // end namespace yaml
56 /// X86MachineFunctionInfo - This class is derived from MachineFunction and
57 /// contains private X86 target-specific information for each MachineFunction.
58 class X86MachineFunctionInfo
: public MachineFunctionInfo
{
59 virtual void anchor();
61 /// ForceFramePointer - True if the function is required to use of frame
62 /// pointer for reasons other than it containing dynamic allocation or
63 /// that FP eliminatation is turned off. For example, Cygwin main function
64 /// contains stack pointer re-alignment code which requires FP.
65 bool ForceFramePointer
= false;
67 /// RestoreBasePointerOffset - Non-zero if the function has base pointer
68 /// and makes call to llvm.eh.sjlj.setjmp. When non-zero, the value is a
69 /// displacement from the frame pointer to a slot where the base pointer
71 signed char RestoreBasePointerOffset
= 0;
73 /// WinEHXMMSlotInfo - Slot information of XMM registers in the stack frame
75 DenseMap
<int, unsigned> WinEHXMMSlotInfo
;
77 /// CalleeSavedFrameSize - Size of the callee-saved register portion of the
78 /// stack frame in bytes.
79 unsigned CalleeSavedFrameSize
= 0;
81 /// BytesToPopOnReturn - Number of bytes function pops on return (in addition
82 /// to the space used by the return address).
83 /// Used on windows platform for stdcall & fastcall name decoration
84 unsigned BytesToPopOnReturn
= 0;
86 /// ReturnAddrIndex - FrameIndex for return slot.
87 int ReturnAddrIndex
= 0;
89 /// FrameIndex for return slot.
90 int FrameAddrIndex
= 0;
92 /// TailCallReturnAddrDelta - The number of bytes by which return address
93 /// stack slot is moved as the result of tail call optimization.
94 int TailCallReturnAddrDelta
= 0;
96 /// SRetReturnReg - Some subtargets require that sret lowering includes
97 /// returning the value of the returned struct in a register. This field
98 /// holds the virtual register into which the sret argument is passed.
99 Register SRetReturnReg
;
101 /// GlobalBaseReg - keeps track of the virtual register initialized for
102 /// use as the global base register. This is used for PIC in some PIC
103 /// relocation models.
104 Register GlobalBaseReg
;
106 /// VarArgsFrameIndex - FrameIndex for start of varargs area.
107 int VarArgsFrameIndex
= 0;
108 /// RegSaveFrameIndex - X86-64 vararg func register save area.
109 int RegSaveFrameIndex
= 0;
110 /// VarArgsGPOffset - X86-64 vararg func int reg offset.
111 unsigned VarArgsGPOffset
= 0;
112 /// VarArgsFPOffset - X86-64 vararg func fp reg offset.
113 unsigned VarArgsFPOffset
= 0;
114 /// ArgumentStackSize - The number of bytes on stack consumed by the arguments
115 /// being passed on the stack.
116 unsigned ArgumentStackSize
= 0;
117 /// NumLocalDynamics - Number of local-dynamic TLS accesses.
118 unsigned NumLocalDynamics
= 0;
119 /// HasPushSequences - Keeps track of whether this function uses sequences
120 /// of pushes to pass function parameters.
121 bool HasPushSequences
= false;
123 /// True if the function recovers from an SEH exception, and therefore needs
124 /// to spill and restore the frame pointer.
125 bool HasSEHFramePtrSave
= false;
127 /// The frame index of a stack object containing the original frame pointer
128 /// used to address arguments in a function using a base pointer.
129 int SEHFramePtrSaveIndex
= 0;
131 /// The AMX programing model used in the function.
132 AMXProgModelEnum AMXProgModel
= AMXProgModelEnum::None
;
134 /// True if this function has a subset of CSRs that is handled explicitly via
136 bool IsSplitCSR
= false;
138 /// True if this function uses the red zone.
139 bool UsesRedZone
= false;
141 /// True if this function has DYN_ALLOCA instructions.
142 bool HasDynAlloca
= false;
144 /// True if this function has any preallocated calls.
145 bool HasPreallocatedCall
= false;
147 /// Whether this function has an extended frame record [Ctx, RBP, Return
148 /// addr]. If so, bit 60 of the in-memory frame pointer will be 1 to enable
149 /// other tools to detect the extended record.
150 bool HasSwiftAsyncContext
= false;
152 /// Ajust stack for push2/pop2
153 bool PadForPush2Pop2
= false;
155 /// Candidate registers for push2/pop2
156 std::set
<Register
> CandidatesForPush2Pop2
;
158 /// True if this function has CFI directives that adjust the CFA.
159 /// This is used to determine if we should direct the debugger to use
160 /// the CFA instead of the stack pointer.
161 bool HasCFIAdjustCfa
= false;
163 MachineInstr
*StackPtrSaveMI
= nullptr;
165 std::optional
<int> SwiftAsyncContextFrameIdx
;
167 // Preallocated fields are only used during isel.
168 // FIXME: Can we find somewhere else to store these?
169 DenseMap
<const Value
*, size_t> PreallocatedIds
;
170 SmallVector
<size_t, 0> PreallocatedStackSizes
;
171 SmallVector
<SmallVector
<size_t, 4>, 0> PreallocatedArgOffsets
;
173 // True if a function clobbers FP/BP according to its calling convention.
174 bool FPClobberedByCall
= false;
175 bool BPClobberedByCall
= false;
176 bool FPClobberedByInvoke
= false;
177 bool BPClobberedByInvoke
= false;
180 /// ForwardedMustTailRegParms - A list of virtual and physical registers
181 /// that must be forwarded to every musttail call.
182 SmallVector
<ForwardedRegister
, 1> ForwardedMustTailRegParms
;
185 X86MachineFunctionInfo() = default;
186 X86MachineFunctionInfo(const Function
&F
, const TargetSubtargetInfo
*STI
) {}
188 X86MachineFunctionInfo(const X86MachineFunctionInfo
&) = default;
190 MachineFunctionInfo
*
191 clone(BumpPtrAllocator
&Allocator
, MachineFunction
&DestMF
,
192 const DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> &Src2DstMBB
)
195 void initializeBaseYamlFields(const yaml::X86MachineFunctionInfo
&YamlMFI
);
197 bool getForceFramePointer() const { return ForceFramePointer
;}
198 void setForceFramePointer(bool forceFP
) { ForceFramePointer
= forceFP
; }
200 bool getHasPushSequences() const { return HasPushSequences
; }
201 void setHasPushSequences(bool HasPush
) { HasPushSequences
= HasPush
; }
203 bool getRestoreBasePointer() const { return RestoreBasePointerOffset
!=0; }
204 void setRestoreBasePointer(const MachineFunction
*MF
);
205 void setRestoreBasePointer(unsigned CalleeSavedFrameSize
) {
206 RestoreBasePointerOffset
= -CalleeSavedFrameSize
;
208 int getRestoreBasePointerOffset() const {return RestoreBasePointerOffset
; }
210 DenseMap
<int, unsigned>& getWinEHXMMSlotInfo() { return WinEHXMMSlotInfo
; }
211 const DenseMap
<int, unsigned>& getWinEHXMMSlotInfo() const {
212 return WinEHXMMSlotInfo
; }
214 unsigned getCalleeSavedFrameSize() const {
215 return CalleeSavedFrameSize
+ 8 * padForPush2Pop2();
217 void setCalleeSavedFrameSize(unsigned bytes
) { CalleeSavedFrameSize
= bytes
; }
219 unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn
; }
220 void setBytesToPopOnReturn (unsigned bytes
) { BytesToPopOnReturn
= bytes
;}
222 int getRAIndex() const { return ReturnAddrIndex
; }
223 void setRAIndex(int Index
) { ReturnAddrIndex
= Index
; }
225 int getFAIndex() const { return FrameAddrIndex
; }
226 void setFAIndex(int Index
) { FrameAddrIndex
= Index
; }
228 int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta
; }
229 void setTCReturnAddrDelta(int delta
) {TailCallReturnAddrDelta
= delta
;}
231 Register
getSRetReturnReg() const { return SRetReturnReg
; }
232 void setSRetReturnReg(Register Reg
) { SRetReturnReg
= Reg
; }
234 Register
getGlobalBaseReg() const { return GlobalBaseReg
; }
235 void setGlobalBaseReg(Register Reg
) { GlobalBaseReg
= Reg
; }
237 int getVarArgsFrameIndex() const { return VarArgsFrameIndex
; }
238 void setVarArgsFrameIndex(int Idx
) { VarArgsFrameIndex
= Idx
; }
240 int getRegSaveFrameIndex() const { return RegSaveFrameIndex
; }
241 void setRegSaveFrameIndex(int Idx
) { RegSaveFrameIndex
= Idx
; }
243 unsigned getVarArgsGPOffset() const { return VarArgsGPOffset
; }
244 void setVarArgsGPOffset(unsigned Offset
) { VarArgsGPOffset
= Offset
; }
246 unsigned getVarArgsFPOffset() const { return VarArgsFPOffset
; }
247 void setVarArgsFPOffset(unsigned Offset
) { VarArgsFPOffset
= Offset
; }
249 unsigned getArgumentStackSize() const { return ArgumentStackSize
; }
250 void setArgumentStackSize(unsigned size
) { ArgumentStackSize
= size
; }
252 unsigned getNumLocalDynamicTLSAccesses() const { return NumLocalDynamics
; }
253 void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamics
; }
255 bool getHasSEHFramePtrSave() const { return HasSEHFramePtrSave
; }
256 void setHasSEHFramePtrSave(bool V
) { HasSEHFramePtrSave
= V
; }
258 int getSEHFramePtrSaveIndex() const { return SEHFramePtrSaveIndex
; }
259 void setSEHFramePtrSaveIndex(int Index
) { SEHFramePtrSaveIndex
= Index
; }
261 AMXProgModelEnum
getAMXProgModel() const { return AMXProgModel
; }
262 void setAMXProgModel(AMXProgModelEnum Model
) {
263 assert((AMXProgModel
== AMXProgModelEnum::None
|| AMXProgModel
== Model
) &&
264 "mixed model is not supported");
265 AMXProgModel
= Model
;
268 SmallVectorImpl
<ForwardedRegister
> &getForwardedMustTailRegParms() {
269 return ForwardedMustTailRegParms
;
272 bool isSplitCSR() const { return IsSplitCSR
; }
273 void setIsSplitCSR(bool s
) { IsSplitCSR
= s
; }
275 bool getUsesRedZone() const { return UsesRedZone
; }
276 void setUsesRedZone(bool V
) { UsesRedZone
= V
; }
278 bool hasDynAlloca() const { return HasDynAlloca
; }
279 void setHasDynAlloca(bool v
) { HasDynAlloca
= v
; }
281 bool hasPreallocatedCall() const { return HasPreallocatedCall
; }
282 void setHasPreallocatedCall(bool v
) { HasPreallocatedCall
= v
; }
284 bool hasSwiftAsyncContext() const { return HasSwiftAsyncContext
; }
285 void setHasSwiftAsyncContext(bool v
) { HasSwiftAsyncContext
= v
; }
287 bool padForPush2Pop2() const { return PadForPush2Pop2
; }
288 void setPadForPush2Pop2(bool V
) { PadForPush2Pop2
= V
; }
290 bool isCandidateForPush2Pop2(Register Reg
) const {
291 return CandidatesForPush2Pop2
.find(Reg
) != CandidatesForPush2Pop2
.end();
293 void addCandidateForPush2Pop2(Register Reg
) {
294 CandidatesForPush2Pop2
.insert(Reg
);
296 size_t getNumCandidatesForPush2Pop2() const {
297 return CandidatesForPush2Pop2
.size();
300 bool hasCFIAdjustCfa() const { return HasCFIAdjustCfa
; }
301 void setHasCFIAdjustCfa(bool v
) { HasCFIAdjustCfa
= v
; }
303 void setStackPtrSaveMI(MachineInstr
*MI
) { StackPtrSaveMI
= MI
; }
304 MachineInstr
*getStackPtrSaveMI() const { return StackPtrSaveMI
; }
306 std::optional
<int> getSwiftAsyncContextFrameIdx() const {
307 return SwiftAsyncContextFrameIdx
;
309 void setSwiftAsyncContextFrameIdx(int v
) { SwiftAsyncContextFrameIdx
= v
; }
311 size_t getPreallocatedIdForCallSite(const Value
*CS
) {
312 auto Insert
= PreallocatedIds
.insert({CS
, PreallocatedIds
.size()});
314 PreallocatedStackSizes
.push_back(0);
315 PreallocatedArgOffsets
.emplace_back();
317 return Insert
.first
->second
;
320 void setPreallocatedStackSize(size_t Id
, size_t StackSize
) {
321 PreallocatedStackSizes
[Id
] = StackSize
;
324 size_t getPreallocatedStackSize(const size_t Id
) {
325 assert(PreallocatedStackSizes
[Id
] != 0 && "stack size not set");
326 return PreallocatedStackSizes
[Id
];
329 void setPreallocatedArgOffsets(size_t Id
, ArrayRef
<size_t> AO
) {
330 PreallocatedArgOffsets
[Id
].assign(AO
.begin(), AO
.end());
333 ArrayRef
<size_t> getPreallocatedArgOffsets(const size_t Id
) {
334 assert(!PreallocatedArgOffsets
[Id
].empty() && "arg offsets not set");
335 return PreallocatedArgOffsets
[Id
];
338 bool getFPClobberedByCall() const { return FPClobberedByCall
; }
339 void setFPClobberedByCall(bool C
) { FPClobberedByCall
= C
; }
341 bool getBPClobberedByCall() const { return BPClobberedByCall
; }
342 void setBPClobberedByCall(bool C
) { BPClobberedByCall
= C
; }
344 bool getFPClobberedByInvoke() const { return FPClobberedByInvoke
; }
345 void setFPClobberedByInvoke(bool C
) { FPClobberedByInvoke
= C
; }
347 bool getBPClobberedByInvoke() const { return BPClobberedByInvoke
; }
348 void setBPClobberedByInvoke(bool C
) { BPClobberedByInvoke
= C
; }
351 } // End llvm namespace