1 //=- AArch64MachineFunctionInfo.h - AArch64 machine function info -*- C++ -*-=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares AArch64-specific per-machine-function information. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H 15 #define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H 16 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/Optional.h" 19 #include "llvm/ADT/SmallPtrSet.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/CodeGen/CallingConvLower.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/MC/MCLinkerOptimizationHint.h" 24 #include <cassert> 25 26 namespace llvm { 27 28 class MachineInstr; 29 30 /// AArch64FunctionInfo - This class is derived from MachineFunctionInfo and 31 /// contains private AArch64-specific information for each MachineFunction. 32 class AArch64FunctionInfo final : public MachineFunctionInfo { 33 /// Number of bytes of arguments this function has on the stack. If the callee 34 /// is expected to restore the argument stack this should be a multiple of 16, 35 /// all usable during a tail call. 36 /// 37 /// The alternative would forbid tail call optimisation in some cases: if we 38 /// want to transfer control from a function with 8-bytes of stack-argument 39 /// space to a function with 16-bytes then misalignment of this value would 40 /// make a stack adjustment necessary, which could not be undone by the 41 /// callee. 42 unsigned BytesInStackArgArea = 0; 43 44 /// The number of bytes to restore to deallocate space for incoming 45 /// arguments. Canonically 0 in the C calling convention, but non-zero when 46 /// callee is expected to pop the args. 47 unsigned ArgumentStackToRestore = 0; 48 49 /// HasStackFrame - True if this function has a stack frame. Set by 50 /// determineCalleeSaves(). 51 bool HasStackFrame = false; 52 53 /// Amount of stack frame size, not including callee-saved registers. 54 unsigned LocalStackSize; 55 56 /// Amount of stack frame size used for saving callee-saved registers. 57 unsigned CalleeSavedStackSize; 58 59 /// Number of TLS accesses using the special (combinable) 60 /// _TLS_MODULE_BASE_ symbol. 61 unsigned NumLocalDynamicTLSAccesses = 0; 62 63 /// FrameIndex for start of varargs area for arguments passed on the 64 /// stack. 65 int VarArgsStackIndex = 0; 66 67 /// FrameIndex for start of varargs area for arguments passed in 68 /// general purpose registers. 69 int VarArgsGPRIndex = 0; 70 71 /// Size of the varargs area for arguments passed in general purpose 72 /// registers. 73 unsigned VarArgsGPRSize = 0; 74 75 /// FrameIndex for start of varargs area for arguments passed in 76 /// floating-point registers. 77 int VarArgsFPRIndex = 0; 78 79 /// Size of the varargs area for arguments passed in floating-point 80 /// registers. 81 unsigned VarArgsFPRSize = 0; 82 83 /// True if this function has a subset of CSRs that is handled explicitly via 84 /// copies. 85 bool IsSplitCSR = false; 86 87 /// True when the stack gets realigned dynamically because the size of stack 88 /// frame is unknown at compile time. e.g., in case of VLAs. 89 bool StackRealigned = false; 90 91 /// True when the callee-save stack area has unused gaps that may be used for 92 /// other stack allocations. 93 bool CalleeSaveStackHasFreeSpace = false; 94 95 /// Has a value when it is known whether or not the function uses a 96 /// redzone, and no value otherwise. 97 /// Initialized during frame lowering, unless the function has the noredzone 98 /// attribute, in which case it is set to false at construction. 99 Optional<bool> HasRedZone; 100 101 /// ForwardedMustTailRegParms - A list of virtual and physical registers 102 /// that must be forwarded to every musttail call. 103 SmallVector<ForwardedRegister, 1> ForwardedMustTailRegParms; 104 public: 105 AArch64FunctionInfo() = default; 106 AArch64FunctionInfo(MachineFunction & MF)107 explicit AArch64FunctionInfo(MachineFunction &MF) { 108 (void)MF; 109 110 // If we already know that the function doesn't have a redzone, set 111 // HasRedZone here. 112 if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone)) 113 HasRedZone = false; 114 } 115 getBytesInStackArgArea()116 unsigned getBytesInStackArgArea() const { return BytesInStackArgArea; } setBytesInStackArgArea(unsigned bytes)117 void setBytesInStackArgArea(unsigned bytes) { BytesInStackArgArea = bytes; } 118 getArgumentStackToRestore()119 unsigned getArgumentStackToRestore() const { return ArgumentStackToRestore; } setArgumentStackToRestore(unsigned bytes)120 void setArgumentStackToRestore(unsigned bytes) { 121 ArgumentStackToRestore = bytes; 122 } 123 hasStackFrame()124 bool hasStackFrame() const { return HasStackFrame; } setHasStackFrame(bool s)125 void setHasStackFrame(bool s) { HasStackFrame = s; } 126 isStackRealigned()127 bool isStackRealigned() const { return StackRealigned; } setStackRealigned(bool s)128 void setStackRealigned(bool s) { StackRealigned = s; } 129 hasCalleeSaveStackFreeSpace()130 bool hasCalleeSaveStackFreeSpace() const { 131 return CalleeSaveStackHasFreeSpace; 132 } setCalleeSaveStackHasFreeSpace(bool s)133 void setCalleeSaveStackHasFreeSpace(bool s) { 134 CalleeSaveStackHasFreeSpace = s; 135 } 136 isSplitCSR()137 bool isSplitCSR() const { return IsSplitCSR; } setIsSplitCSR(bool s)138 void setIsSplitCSR(bool s) { IsSplitCSR = s; } 139 setLocalStackSize(unsigned Size)140 void setLocalStackSize(unsigned Size) { LocalStackSize = Size; } getLocalStackSize()141 unsigned getLocalStackSize() const { return LocalStackSize; } 142 setCalleeSavedStackSize(unsigned Size)143 void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; } getCalleeSavedStackSize()144 unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; } 145 incNumLocalDynamicTLSAccesses()146 void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamicTLSAccesses; } getNumLocalDynamicTLSAccesses()147 unsigned getNumLocalDynamicTLSAccesses() const { 148 return NumLocalDynamicTLSAccesses; 149 } 150 hasRedZone()151 Optional<bool> hasRedZone() const { return HasRedZone; } setHasRedZone(bool s)152 void setHasRedZone(bool s) { HasRedZone = s; } 153 getVarArgsStackIndex()154 int getVarArgsStackIndex() const { return VarArgsStackIndex; } setVarArgsStackIndex(int Index)155 void setVarArgsStackIndex(int Index) { VarArgsStackIndex = Index; } 156 getVarArgsGPRIndex()157 int getVarArgsGPRIndex() const { return VarArgsGPRIndex; } setVarArgsGPRIndex(int Index)158 void setVarArgsGPRIndex(int Index) { VarArgsGPRIndex = Index; } 159 getVarArgsGPRSize()160 unsigned getVarArgsGPRSize() const { return VarArgsGPRSize; } setVarArgsGPRSize(unsigned Size)161 void setVarArgsGPRSize(unsigned Size) { VarArgsGPRSize = Size; } 162 getVarArgsFPRIndex()163 int getVarArgsFPRIndex() const { return VarArgsFPRIndex; } setVarArgsFPRIndex(int Index)164 void setVarArgsFPRIndex(int Index) { VarArgsFPRIndex = Index; } 165 getVarArgsFPRSize()166 unsigned getVarArgsFPRSize() const { return VarArgsFPRSize; } setVarArgsFPRSize(unsigned Size)167 void setVarArgsFPRSize(unsigned Size) { VarArgsFPRSize = Size; } 168 getJumpTableEntrySize(int Idx)169 unsigned getJumpTableEntrySize(int Idx) const { 170 auto It = JumpTableEntryInfo.find(Idx); 171 if (It != JumpTableEntryInfo.end()) 172 return It->second.first; 173 return 4; 174 } getJumpTableEntryPCRelSymbol(int Idx)175 MCSymbol *getJumpTableEntryPCRelSymbol(int Idx) const { 176 return JumpTableEntryInfo.find(Idx)->second.second; 177 } setJumpTableEntryInfo(int Idx,unsigned Size,MCSymbol * PCRelSym)178 void setJumpTableEntryInfo(int Idx, unsigned Size, MCSymbol *PCRelSym) { 179 JumpTableEntryInfo[Idx] = std::make_pair(Size, PCRelSym); 180 } 181 182 using SetOfInstructions = SmallPtrSet<const MachineInstr *, 16>; 183 getLOHRelated()184 const SetOfInstructions &getLOHRelated() const { return LOHRelated; } 185 186 // Shortcuts for LOH related types. 187 class MILOHDirective { 188 MCLOHType Kind; 189 190 /// Arguments of this directive. Order matters. 191 SmallVector<const MachineInstr *, 3> Args; 192 193 public: 194 using LOHArgs = ArrayRef<const MachineInstr *>; 195 MILOHDirective(MCLOHType Kind,LOHArgs Args)196 MILOHDirective(MCLOHType Kind, LOHArgs Args) 197 : Kind(Kind), Args(Args.begin(), Args.end()) { 198 assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!"); 199 } 200 getKind()201 MCLOHType getKind() const { return Kind; } getArgs()202 LOHArgs getArgs() const { return Args; } 203 }; 204 205 using MILOHArgs = MILOHDirective::LOHArgs; 206 using MILOHContainer = SmallVector<MILOHDirective, 32>; 207 getLOHContainer()208 const MILOHContainer &getLOHContainer() const { return LOHContainerSet; } 209 210 /// Add a LOH directive of this @p Kind and this @p Args. addLOHDirective(MCLOHType Kind,MILOHArgs Args)211 void addLOHDirective(MCLOHType Kind, MILOHArgs Args) { 212 LOHContainerSet.push_back(MILOHDirective(Kind, Args)); 213 LOHRelated.insert(Args.begin(), Args.end()); 214 } 215 getForwardedMustTailRegParms()216 SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() { 217 return ForwardedMustTailRegParms; 218 } 219 220 private: 221 // Hold the lists of LOHs. 222 MILOHContainer LOHContainerSet; 223 SetOfInstructions LOHRelated; 224 225 DenseMap<int, std::pair<unsigned, MCSymbol *>> JumpTableEntryInfo; 226 }; 227 228 } // end namespace llvm 229 230 #endif // LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H 231