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