1 //===-- X86MachineFunctionInfo.h - X86 machine function info ----*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares X86-specific per-machine-function information. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_X86_X86MACHINEFUNCTIONINFO_H 14 #define LLVM_LIB_TARGET_X86_X86MACHINEFUNCTIONINFO_H 15 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/CodeGen/CallingConvLower.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include <set> 21 22 namespace llvm { 23 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(); 28 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; 34 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 38 /// is stashed. 39 signed char RestoreBasePointerOffset = 0; 40 41 /// WinEHXMMSlotInfo - Slot information of XMM registers in the stack frame 42 /// in bytes. 43 DenseMap<int, unsigned> WinEHXMMSlotInfo; 44 45 /// CalleeSavedFrameSize - Size of the callee-saved register portion of the 46 /// stack frame in bytes. 47 unsigned CalleeSavedFrameSize = 0; 48 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; 53 54 /// ReturnAddrIndex - FrameIndex for return slot. 55 int ReturnAddrIndex = 0; 56 57 /// FrameIndex for return slot. 58 int FrameAddrIndex = 0; 59 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; 63 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; 68 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; 73 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; 90 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; 94 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; 98 99 /// True if this function has a subset of CSRs that is handled explicitly via 100 /// copies. 101 bool IsSplitCSR = false; 102 103 /// True if this function uses the red zone. 104 bool UsesRedZone = false; 105 106 /// True if this function has DYN_ALLOCA instructions. 107 bool HasDynAlloca = false; 108 109 /// True if this function has any preallocated calls. 110 bool HasPreallocatedCall = false; 111 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; 116 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; 120 121 /// Ajust stack for push2/pop2 122 bool PadForPush2Pop2 = false; 123 124 /// Candidate registers for push2/pop2 125 std::set<Register> CandidatesForPush2Pop2; 126 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; 131 132 MachineInstr *StackPtrSaveMI = nullptr; 133 134 std::optional<int> SwiftAsyncContextFrameIdx; 135 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; 141 142 private: 143 /// ForwardedMustTailRegParms - A list of virtual and physical registers 144 /// that must be forwarded to every musttail call. 145 SmallVector<ForwardedRegister, 1> ForwardedMustTailRegParms; 146 147 public: 148 X86MachineFunctionInfo() = default; 149 X86MachineFunctionInfo(const Function &F, const TargetSubtargetInfo *STI) {} 150 151 X86MachineFunctionInfo(const X86MachineFunctionInfo &) = default; 152 153 MachineFunctionInfo * 154 clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 155 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) 156 const override; 157 158 bool getForceFramePointer() const { return ForceFramePointer;} 159 void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; } 160 161 bool getHasPushSequences() const { return HasPushSequences; } 162 void setHasPushSequences(bool HasPush) { HasPushSequences = HasPush; } 163 164 bool getRestoreBasePointer() const { return RestoreBasePointerOffset!=0; } 165 void setRestoreBasePointer(const MachineFunction *MF); 166 void setRestoreBasePointer(unsigned CalleeSavedFrameSize) { 167 RestoreBasePointerOffset = -CalleeSavedFrameSize; 168 } 169 int getRestoreBasePointerOffset() const {return RestoreBasePointerOffset; } 170 171 DenseMap<int, unsigned>& getWinEHXMMSlotInfo() { return WinEHXMMSlotInfo; } 172 const DenseMap<int, unsigned>& getWinEHXMMSlotInfo() const { 173 return WinEHXMMSlotInfo; } 174 175 unsigned getCalleeSavedFrameSize() const { 176 return CalleeSavedFrameSize + 8 * padForPush2Pop2(); 177 } 178 void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; } 179 180 unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; } 181 void setBytesToPopOnReturn (unsigned bytes) { BytesToPopOnReturn = bytes;} 182 183 int getRAIndex() const { return ReturnAddrIndex; } 184 void setRAIndex(int Index) { ReturnAddrIndex = Index; } 185 186 int getFAIndex() const { return FrameAddrIndex; } 187 void setFAIndex(int Index) { FrameAddrIndex = Index; } 188 189 int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta; } 190 void setTCReturnAddrDelta(int delta) {TailCallReturnAddrDelta = delta;} 191 192 Register getSRetReturnReg() const { return SRetReturnReg; } 193 void setSRetReturnReg(Register Reg) { SRetReturnReg = Reg; } 194 195 Register getGlobalBaseReg() const { return GlobalBaseReg; } 196 void setGlobalBaseReg(Register Reg) { GlobalBaseReg = Reg; } 197 198 int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } 199 void setVarArgsFrameIndex(int Idx) { VarArgsFrameIndex = Idx; } 200 201 int getRegSaveFrameIndex() const { return RegSaveFrameIndex; } 202 void setRegSaveFrameIndex(int Idx) { RegSaveFrameIndex = Idx; } 203 204 unsigned getVarArgsGPOffset() const { return VarArgsGPOffset; } 205 void setVarArgsGPOffset(unsigned Offset) { VarArgsGPOffset = Offset; } 206 207 unsigned getVarArgsFPOffset() const { return VarArgsFPOffset; } 208 void setVarArgsFPOffset(unsigned Offset) { VarArgsFPOffset = Offset; } 209 210 unsigned getArgumentStackSize() const { return ArgumentStackSize; } 211 void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; } 212 213 unsigned getNumLocalDynamicTLSAccesses() const { return NumLocalDynamics; } 214 void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamics; } 215 216 bool getHasSEHFramePtrSave() const { return HasSEHFramePtrSave; } 217 void setHasSEHFramePtrSave(bool V) { HasSEHFramePtrSave = V; } 218 219 int getSEHFramePtrSaveIndex() const { return SEHFramePtrSaveIndex; } 220 void setSEHFramePtrSaveIndex(int Index) { SEHFramePtrSaveIndex = Index; } 221 222 SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() { 223 return ForwardedMustTailRegParms; 224 } 225 226 bool isSplitCSR() const { return IsSplitCSR; } 227 void setIsSplitCSR(bool s) { IsSplitCSR = s; } 228 229 bool getUsesRedZone() const { return UsesRedZone; } 230 void setUsesRedZone(bool V) { UsesRedZone = V; } 231 232 bool hasDynAlloca() const { return HasDynAlloca; } 233 void setHasDynAlloca(bool v) { HasDynAlloca = v; } 234 235 bool hasPreallocatedCall() const { return HasPreallocatedCall; } 236 void setHasPreallocatedCall(bool v) { HasPreallocatedCall = v; } 237 238 bool hasSwiftAsyncContext() const { return HasSwiftAsyncContext; } 239 void setHasSwiftAsyncContext(bool v) { HasSwiftAsyncContext = v; } 240 241 bool hasVirtualTileReg() const { return HasVirtualTileReg; } 242 void setHasVirtualTileReg(bool v) { HasVirtualTileReg = v; } 243 244 bool padForPush2Pop2() const { return PadForPush2Pop2; } 245 void setPadForPush2Pop2(bool V) { PadForPush2Pop2 = V; } 246 247 bool isCandidateForPush2Pop2(Register Reg) const { 248 return CandidatesForPush2Pop2.find(Reg) != CandidatesForPush2Pop2.end(); 249 } 250 void addCandidateForPush2Pop2(Register Reg) { 251 CandidatesForPush2Pop2.insert(Reg); 252 } 253 size_t getNumCandidatesForPush2Pop2() const { 254 return CandidatesForPush2Pop2.size(); 255 } 256 257 bool hasCFIAdjustCfa() const { return HasCFIAdjustCfa; } 258 void setHasCFIAdjustCfa(bool v) { HasCFIAdjustCfa = v; } 259 260 void setStackPtrSaveMI(MachineInstr *MI) { StackPtrSaveMI = MI; } 261 MachineInstr *getStackPtrSaveMI() const { return StackPtrSaveMI; } 262 263 std::optional<int> getSwiftAsyncContextFrameIdx() const { 264 return SwiftAsyncContextFrameIdx; 265 } 266 void setSwiftAsyncContextFrameIdx(int v) { SwiftAsyncContextFrameIdx = v; } 267 268 size_t getPreallocatedIdForCallSite(const Value *CS) { 269 auto Insert = PreallocatedIds.insert({CS, PreallocatedIds.size()}); 270 if (Insert.second) { 271 PreallocatedStackSizes.push_back(0); 272 PreallocatedArgOffsets.emplace_back(); 273 } 274 return Insert.first->second; 275 } 276 277 void setPreallocatedStackSize(size_t Id, size_t StackSize) { 278 PreallocatedStackSizes[Id] = StackSize; 279 } 280 281 size_t getPreallocatedStackSize(const size_t Id) { 282 assert(PreallocatedStackSizes[Id] != 0 && "stack size not set"); 283 return PreallocatedStackSizes[Id]; 284 } 285 286 void setPreallocatedArgOffsets(size_t Id, ArrayRef<size_t> AO) { 287 PreallocatedArgOffsets[Id].assign(AO.begin(), AO.end()); 288 } 289 290 ArrayRef<size_t> getPreallocatedArgOffsets(const size_t Id) { 291 assert(!PreallocatedArgOffsets[Id].empty() && "arg offsets not set"); 292 return PreallocatedArgOffsets[Id]; 293 } 294 }; 295 296 } // End llvm namespace 297 298 #endif 299