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/IR/Function.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 /// SRetReturnReg - sret lowering includes returning the value of the 96 /// returned struct in a register. This field holds the virtual register into 97 /// which the sret argument is passed. 98 unsigned SRetReturnReg = 0; 99 /// SVE stack size (for predicates and data vectors) are maintained here 100 /// rather than in FrameInfo, as the placement and Stack IDs are target 101 /// specific. 102 uint64_t StackSizeSVE = 0; 103 104 /// HasCalculatedStackSizeSVE indicates whether StackSizeSVE is valid. 105 bool HasCalculatedStackSizeSVE = false; 106 107 /// Has a value when it is known whether or not the function uses a 108 /// redzone, and no value otherwise. 109 /// Initialized during frame lowering, unless the function has the noredzone 110 /// attribute, in which case it is set to false at construction. 111 Optional<bool> HasRedZone; 112 113 /// ForwardedMustTailRegParms - A list of virtual and physical registers 114 /// that must be forwarded to every musttail call. 115 SmallVector<ForwardedRegister, 1> ForwardedMustTailRegParms; 116 117 // Offset from SP-at-entry to the tagged base pointer. 118 // Tagged base pointer is set up to point to the first (lowest address) tagged 119 // stack slot. 120 unsigned TaggedBasePointerOffset; 121 122 public: 123 AArch64FunctionInfo() = default; 124 125 explicit AArch64FunctionInfo(MachineFunction &MF) { 126 (void)MF; 127 128 // If we already know that the function doesn't have a redzone, set 129 // HasRedZone here. 130 if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone)) 131 HasRedZone = false; 132 } 133 134 unsigned getBytesInStackArgArea() const { return BytesInStackArgArea; } 135 void setBytesInStackArgArea(unsigned bytes) { BytesInStackArgArea = bytes; } 136 137 unsigned getArgumentStackToRestore() const { return ArgumentStackToRestore; } 138 void setArgumentStackToRestore(unsigned bytes) { 139 ArgumentStackToRestore = bytes; 140 } 141 142 bool hasCalculatedStackSizeSVE() const { return HasCalculatedStackSizeSVE; } 143 144 void setStackSizeSVE(uint64_t S) { 145 HasCalculatedStackSizeSVE = true; 146 StackSizeSVE = S; 147 } 148 149 uint64_t getStackSizeSVE() const { return StackSizeSVE; } 150 151 bool hasStackFrame() const { return HasStackFrame; } 152 void setHasStackFrame(bool s) { HasStackFrame = s; } 153 154 bool isStackRealigned() const { return StackRealigned; } 155 void setStackRealigned(bool s) { StackRealigned = s; } 156 157 bool hasCalleeSaveStackFreeSpace() const { 158 return CalleeSaveStackHasFreeSpace; 159 } 160 void setCalleeSaveStackHasFreeSpace(bool s) { 161 CalleeSaveStackHasFreeSpace = s; 162 } 163 164 bool isSplitCSR() const { return IsSplitCSR; } 165 void setIsSplitCSR(bool s) { IsSplitCSR = s; } 166 167 void setLocalStackSize(unsigned Size) { LocalStackSize = Size; } 168 unsigned getLocalStackSize() const { return LocalStackSize; } 169 170 void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; } 171 unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; } 172 173 void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamicTLSAccesses; } 174 unsigned getNumLocalDynamicTLSAccesses() const { 175 return NumLocalDynamicTLSAccesses; 176 } 177 178 Optional<bool> hasRedZone() const { return HasRedZone; } 179 void setHasRedZone(bool s) { HasRedZone = s; } 180 181 int getVarArgsStackIndex() const { return VarArgsStackIndex; } 182 void setVarArgsStackIndex(int Index) { VarArgsStackIndex = Index; } 183 184 int getVarArgsGPRIndex() const { return VarArgsGPRIndex; } 185 void setVarArgsGPRIndex(int Index) { VarArgsGPRIndex = Index; } 186 187 unsigned getVarArgsGPRSize() const { return VarArgsGPRSize; } 188 void setVarArgsGPRSize(unsigned Size) { VarArgsGPRSize = Size; } 189 190 int getVarArgsFPRIndex() const { return VarArgsFPRIndex; } 191 void setVarArgsFPRIndex(int Index) { VarArgsFPRIndex = Index; } 192 193 unsigned getVarArgsFPRSize() const { return VarArgsFPRSize; } 194 void setVarArgsFPRSize(unsigned Size) { VarArgsFPRSize = Size; } 195 196 unsigned getSRetReturnReg() const { return SRetReturnReg; } 197 void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } 198 199 unsigned getJumpTableEntrySize(int Idx) const { 200 auto It = JumpTableEntryInfo.find(Idx); 201 if (It != JumpTableEntryInfo.end()) 202 return It->second.first; 203 return 4; 204 } 205 MCSymbol *getJumpTableEntryPCRelSymbol(int Idx) const { 206 return JumpTableEntryInfo.find(Idx)->second.second; 207 } 208 void setJumpTableEntryInfo(int Idx, unsigned Size, MCSymbol *PCRelSym) { 209 JumpTableEntryInfo[Idx] = std::make_pair(Size, PCRelSym); 210 } 211 212 using SetOfInstructions = SmallPtrSet<const MachineInstr *, 16>; 213 214 const SetOfInstructions &getLOHRelated() const { return LOHRelated; } 215 216 // Shortcuts for LOH related types. 217 class MILOHDirective { 218 MCLOHType Kind; 219 220 /// Arguments of this directive. Order matters. 221 SmallVector<const MachineInstr *, 3> Args; 222 223 public: 224 using LOHArgs = ArrayRef<const MachineInstr *>; 225 226 MILOHDirective(MCLOHType Kind, LOHArgs Args) 227 : Kind(Kind), Args(Args.begin(), Args.end()) { 228 assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!"); 229 } 230 231 MCLOHType getKind() const { return Kind; } 232 LOHArgs getArgs() const { return Args; } 233 }; 234 235 using MILOHArgs = MILOHDirective::LOHArgs; 236 using MILOHContainer = SmallVector<MILOHDirective, 32>; 237 238 const MILOHContainer &getLOHContainer() const { return LOHContainerSet; } 239 240 /// Add a LOH directive of this @p Kind and this @p Args. 241 void addLOHDirective(MCLOHType Kind, MILOHArgs Args) { 242 LOHContainerSet.push_back(MILOHDirective(Kind, Args)); 243 LOHRelated.insert(Args.begin(), Args.end()); 244 } 245 246 SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() { 247 return ForwardedMustTailRegParms; 248 } 249 250 unsigned getTaggedBasePointerOffset() const { 251 return TaggedBasePointerOffset; 252 } 253 void setTaggedBasePointerOffset(unsigned Offset) { 254 TaggedBasePointerOffset = Offset; 255 } 256 257 private: 258 // Hold the lists of LOHs. 259 MILOHContainer LOHContainerSet; 260 SetOfInstructions LOHRelated; 261 262 DenseMap<int, std::pair<unsigned, MCSymbol *>> JumpTableEntryInfo; 263 }; 264 265 } // end namespace llvm 266 267 #endif // LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H 268