109467b48Spatrick //=- AArch64MachineFunctionInfo.h - AArch64 machine function info -*- C++ -*-=// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This file declares AArch64-specific per-machine-function information. 1009467b48Spatrick // 1109467b48Spatrick //===----------------------------------------------------------------------===// 1209467b48Spatrick 1309467b48Spatrick #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H 1409467b48Spatrick #define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H 1509467b48Spatrick 1609467b48Spatrick #include "llvm/ADT/ArrayRef.h" 1709467b48Spatrick #include "llvm/ADT/SmallPtrSet.h" 1809467b48Spatrick #include "llvm/ADT/SmallVector.h" 1909467b48Spatrick #include "llvm/CodeGen/CallingConvLower.h" 20097a140dSpatrick #include "llvm/CodeGen/MIRYamlMapping.h" 21*d415bd75Srobert #include "llvm/CodeGen/MachineFrameInfo.h" 2209467b48Spatrick #include "llvm/CodeGen/MachineFunction.h" 2309467b48Spatrick #include "llvm/IR/Function.h" 2409467b48Spatrick #include "llvm/MC/MCLinkerOptimizationHint.h" 2509467b48Spatrick #include <cassert> 26*d415bd75Srobert #include <optional> 2709467b48Spatrick 2809467b48Spatrick namespace llvm { 2909467b48Spatrick 30097a140dSpatrick namespace yaml { 31097a140dSpatrick struct AArch64FunctionInfo; 32097a140dSpatrick } // end namespace yaml 33097a140dSpatrick 34*d415bd75Srobert class AArch64Subtarget; 3509467b48Spatrick class MachineInstr; 3609467b48Spatrick 3709467b48Spatrick /// AArch64FunctionInfo - This class is derived from MachineFunctionInfo and 3809467b48Spatrick /// contains private AArch64-specific information for each MachineFunction. 3909467b48Spatrick class AArch64FunctionInfo final : public MachineFunctionInfo { 4009467b48Spatrick /// Number of bytes of arguments this function has on the stack. If the callee 4109467b48Spatrick /// is expected to restore the argument stack this should be a multiple of 16, 4209467b48Spatrick /// all usable during a tail call. 4309467b48Spatrick /// 4409467b48Spatrick /// The alternative would forbid tail call optimisation in some cases: if we 4509467b48Spatrick /// want to transfer control from a function with 8-bytes of stack-argument 4609467b48Spatrick /// space to a function with 16-bytes then misalignment of this value would 4709467b48Spatrick /// make a stack adjustment necessary, which could not be undone by the 4809467b48Spatrick /// callee. 4909467b48Spatrick unsigned BytesInStackArgArea = 0; 5009467b48Spatrick 5109467b48Spatrick /// The number of bytes to restore to deallocate space for incoming 5209467b48Spatrick /// arguments. Canonically 0 in the C calling convention, but non-zero when 5309467b48Spatrick /// callee is expected to pop the args. 5409467b48Spatrick unsigned ArgumentStackToRestore = 0; 5509467b48Spatrick 5673471bf0Spatrick /// Space just below incoming stack pointer reserved for arguments being 5773471bf0Spatrick /// passed on the stack during a tail call. This will be the difference 5873471bf0Spatrick /// between the largest tail call argument space needed in this function and 5973471bf0Spatrick /// what's already available by reusing space of incoming arguments. 6073471bf0Spatrick unsigned TailCallReservedStack = 0; 6173471bf0Spatrick 6209467b48Spatrick /// HasStackFrame - True if this function has a stack frame. Set by 6309467b48Spatrick /// determineCalleeSaves(). 6409467b48Spatrick bool HasStackFrame = false; 6509467b48Spatrick 6609467b48Spatrick /// Amount of stack frame size, not including callee-saved registers. 6709467b48Spatrick uint64_t LocalStackSize = 0; 6809467b48Spatrick 6909467b48Spatrick /// The start and end frame indices for the SVE callee saves. 7009467b48Spatrick int MinSVECSFrameIndex = 0; 7109467b48Spatrick int MaxSVECSFrameIndex = 0; 7209467b48Spatrick 7309467b48Spatrick /// Amount of stack frame size used for saving callee-saved registers. 7409467b48Spatrick unsigned CalleeSavedStackSize = 0; 7509467b48Spatrick unsigned SVECalleeSavedStackSize = 0; 7609467b48Spatrick bool HasCalleeSavedStackSize = false; 7709467b48Spatrick 7809467b48Spatrick /// Number of TLS accesses using the special (combinable) 7909467b48Spatrick /// _TLS_MODULE_BASE_ symbol. 8009467b48Spatrick unsigned NumLocalDynamicTLSAccesses = 0; 8109467b48Spatrick 8209467b48Spatrick /// FrameIndex for start of varargs area for arguments passed on the 8309467b48Spatrick /// stack. 8409467b48Spatrick int VarArgsStackIndex = 0; 8509467b48Spatrick 86*d415bd75Srobert /// Offset of start of varargs area for arguments passed on the stack. 87*d415bd75Srobert unsigned VarArgsStackOffset = 0; 88*d415bd75Srobert 8909467b48Spatrick /// FrameIndex for start of varargs area for arguments passed in 9009467b48Spatrick /// general purpose registers. 9109467b48Spatrick int VarArgsGPRIndex = 0; 9209467b48Spatrick 9309467b48Spatrick /// Size of the varargs area for arguments passed in general purpose 9409467b48Spatrick /// registers. 9509467b48Spatrick unsigned VarArgsGPRSize = 0; 9609467b48Spatrick 9709467b48Spatrick /// FrameIndex for start of varargs area for arguments passed in 9809467b48Spatrick /// floating-point registers. 9909467b48Spatrick int VarArgsFPRIndex = 0; 10009467b48Spatrick 10109467b48Spatrick /// Size of the varargs area for arguments passed in floating-point 10209467b48Spatrick /// registers. 10309467b48Spatrick unsigned VarArgsFPRSize = 0; 10409467b48Spatrick 10509467b48Spatrick /// True if this function has a subset of CSRs that is handled explicitly via 10609467b48Spatrick /// copies. 10709467b48Spatrick bool IsSplitCSR = false; 10809467b48Spatrick 10909467b48Spatrick /// True when the stack gets realigned dynamically because the size of stack 11009467b48Spatrick /// frame is unknown at compile time. e.g., in case of VLAs. 11109467b48Spatrick bool StackRealigned = false; 11209467b48Spatrick 11309467b48Spatrick /// True when the callee-save stack area has unused gaps that may be used for 11409467b48Spatrick /// other stack allocations. 11509467b48Spatrick bool CalleeSaveStackHasFreeSpace = false; 11609467b48Spatrick 11709467b48Spatrick /// SRetReturnReg - sret lowering includes returning the value of the 11809467b48Spatrick /// returned struct in a register. This field holds the virtual register into 11909467b48Spatrick /// which the sret argument is passed. 120*d415bd75Srobert Register SRetReturnReg; 121*d415bd75Srobert 12209467b48Spatrick /// SVE stack size (for predicates and data vectors) are maintained here 12309467b48Spatrick /// rather than in FrameInfo, as the placement and Stack IDs are target 12409467b48Spatrick /// specific. 12509467b48Spatrick uint64_t StackSizeSVE = 0; 12609467b48Spatrick 12709467b48Spatrick /// HasCalculatedStackSizeSVE indicates whether StackSizeSVE is valid. 12809467b48Spatrick bool HasCalculatedStackSizeSVE = false; 12909467b48Spatrick 13009467b48Spatrick /// Has a value when it is known whether or not the function uses a 13109467b48Spatrick /// redzone, and no value otherwise. 13209467b48Spatrick /// Initialized during frame lowering, unless the function has the noredzone 13309467b48Spatrick /// attribute, in which case it is set to false at construction. 134*d415bd75Srobert std::optional<bool> HasRedZone; 13509467b48Spatrick 13609467b48Spatrick /// ForwardedMustTailRegParms - A list of virtual and physical registers 13709467b48Spatrick /// that must be forwarded to every musttail call. 13809467b48Spatrick SmallVector<ForwardedRegister, 1> ForwardedMustTailRegParms; 13909467b48Spatrick 14073471bf0Spatrick /// FrameIndex for the tagged base pointer. 141*d415bd75Srobert std::optional<int> TaggedBasePointerIndex; 14273471bf0Spatrick 14373471bf0Spatrick /// Offset from SP-at-entry to the tagged base pointer. 14473471bf0Spatrick /// Tagged base pointer is set up to point to the first (lowest address) 14573471bf0Spatrick /// tagged stack slot. 14673471bf0Spatrick unsigned TaggedBasePointerOffset; 14709467b48Spatrick 148097a140dSpatrick /// OutliningStyle denotes, if a function was outined, how it was outlined, 149097a140dSpatrick /// e.g. Tail Call, Thunk, or Function if none apply. 150*d415bd75Srobert std::optional<std::string> OutliningStyle; 151097a140dSpatrick 15273471bf0Spatrick // Offset from SP-after-callee-saved-spills (i.e. SP-at-entry minus 15373471bf0Spatrick // CalleeSavedStackSize) to the address of the frame record. 15473471bf0Spatrick int CalleeSaveBaseToFrameRecordOffset = 0; 15573471bf0Spatrick 15673471bf0Spatrick /// SignReturnAddress is true if PAC-RET is enabled for the function with 15773471bf0Spatrick /// defaults being sign non-leaf functions only, with the B key. 15873471bf0Spatrick bool SignReturnAddress = false; 15973471bf0Spatrick 16073471bf0Spatrick /// SignReturnAddressAll modifies the default PAC-RET mode to signing leaf 16173471bf0Spatrick /// functions as well. 16273471bf0Spatrick bool SignReturnAddressAll = false; 16373471bf0Spatrick 16473471bf0Spatrick /// SignWithBKey modifies the default PAC-RET mode to signing with the B key. 16573471bf0Spatrick bool SignWithBKey = false; 16673471bf0Spatrick 16773471bf0Spatrick /// BranchTargetEnforcement enables placing BTI instructions at potential 16873471bf0Spatrick /// indirect branch destinations. 16973471bf0Spatrick bool BranchTargetEnforcement = false; 17073471bf0Spatrick 17173471bf0Spatrick /// Whether this function has an extended frame record [Ctx, FP, LR]. If so, 17273471bf0Spatrick /// bit 60 of the in-memory FP will be 1 to enable other tools to detect the 17373471bf0Spatrick /// extended record. 17473471bf0Spatrick bool HasSwiftAsyncContext = false; 17573471bf0Spatrick 17673471bf0Spatrick /// The stack slot where the Swift asynchronous context is stored. 17773471bf0Spatrick int SwiftAsyncContextFrameIdx = std::numeric_limits<int>::max(); 17873471bf0Spatrick 179*d415bd75Srobert bool IsMTETagged = false; 180*d415bd75Srobert 181*d415bd75Srobert /// The function has Scalable Vector or Scalable Predicate register argument 182*d415bd75Srobert /// or return type 183*d415bd75Srobert bool IsSVECC = false; 184*d415bd75Srobert 185*d415bd75Srobert /// The frame-index for the TPIDR2 object used for lazy saves. 186*d415bd75Srobert Register LazySaveTPIDR2Obj = 0; 187*d415bd75Srobert 188*d415bd75Srobert 189*d415bd75Srobert /// True if the function need unwind information. 190*d415bd75Srobert mutable std::optional<bool> NeedsDwarfUnwindInfo; 191*d415bd75Srobert 192*d415bd75Srobert /// True if the function need asynchronous unwind information. 193*d415bd75Srobert mutable std::optional<bool> NeedsAsyncDwarfUnwindInfo; 194*d415bd75Srobert 19509467b48Spatrick public: 196*d415bd75Srobert AArch64FunctionInfo(const Function &F, const AArch64Subtarget *STI); 197*d415bd75Srobert 198*d415bd75Srobert MachineFunctionInfo * 199*d415bd75Srobert clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 200*d415bd75Srobert const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) 201*d415bd75Srobert const override; 202*d415bd75Srobert isSVECC()203*d415bd75Srobert bool isSVECC() const { return IsSVECC; }; setIsSVECC(bool s)204*d415bd75Srobert void setIsSVECC(bool s) { IsSVECC = s; }; 205*d415bd75Srobert getLazySaveTPIDR2Obj()206*d415bd75Srobert unsigned getLazySaveTPIDR2Obj() const { return LazySaveTPIDR2Obj; } setLazySaveTPIDR2Obj(unsigned Reg)207*d415bd75Srobert void setLazySaveTPIDR2Obj(unsigned Reg) { LazySaveTPIDR2Obj = Reg; } 20809467b48Spatrick 209097a140dSpatrick void initializeBaseYamlFields(const yaml::AArch64FunctionInfo &YamlMFI); 21009467b48Spatrick getBytesInStackArgArea()21109467b48Spatrick unsigned getBytesInStackArgArea() const { return BytesInStackArgArea; } setBytesInStackArgArea(unsigned bytes)21209467b48Spatrick void setBytesInStackArgArea(unsigned bytes) { BytesInStackArgArea = bytes; } 21309467b48Spatrick getArgumentStackToRestore()21409467b48Spatrick unsigned getArgumentStackToRestore() const { return ArgumentStackToRestore; } setArgumentStackToRestore(unsigned bytes)21509467b48Spatrick void setArgumentStackToRestore(unsigned bytes) { 21609467b48Spatrick ArgumentStackToRestore = bytes; 21709467b48Spatrick } 21809467b48Spatrick getTailCallReservedStack()21973471bf0Spatrick unsigned getTailCallReservedStack() const { return TailCallReservedStack; } setTailCallReservedStack(unsigned bytes)22073471bf0Spatrick void setTailCallReservedStack(unsigned bytes) { 22173471bf0Spatrick TailCallReservedStack = bytes; 22273471bf0Spatrick } 22373471bf0Spatrick hasCalculatedStackSizeSVE()22409467b48Spatrick bool hasCalculatedStackSizeSVE() const { return HasCalculatedStackSizeSVE; } 22509467b48Spatrick setStackSizeSVE(uint64_t S)22609467b48Spatrick void setStackSizeSVE(uint64_t S) { 22709467b48Spatrick HasCalculatedStackSizeSVE = true; 22809467b48Spatrick StackSizeSVE = S; 22909467b48Spatrick } 23009467b48Spatrick getStackSizeSVE()23109467b48Spatrick uint64_t getStackSizeSVE() const { return StackSizeSVE; } 23209467b48Spatrick hasStackFrame()23309467b48Spatrick bool hasStackFrame() const { return HasStackFrame; } setHasStackFrame(bool s)23409467b48Spatrick void setHasStackFrame(bool s) { HasStackFrame = s; } 23509467b48Spatrick isStackRealigned()23609467b48Spatrick bool isStackRealigned() const { return StackRealigned; } setStackRealigned(bool s)23709467b48Spatrick void setStackRealigned(bool s) { StackRealigned = s; } 23809467b48Spatrick hasCalleeSaveStackFreeSpace()23909467b48Spatrick bool hasCalleeSaveStackFreeSpace() const { 24009467b48Spatrick return CalleeSaveStackHasFreeSpace; 24109467b48Spatrick } setCalleeSaveStackHasFreeSpace(bool s)24209467b48Spatrick void setCalleeSaveStackHasFreeSpace(bool s) { 24309467b48Spatrick CalleeSaveStackHasFreeSpace = s; 24409467b48Spatrick } isSplitCSR()24509467b48Spatrick bool isSplitCSR() const { return IsSplitCSR; } setIsSplitCSR(bool s)24609467b48Spatrick void setIsSplitCSR(bool s) { IsSplitCSR = s; } 24709467b48Spatrick setLocalStackSize(uint64_t Size)24809467b48Spatrick void setLocalStackSize(uint64_t Size) { LocalStackSize = Size; } getLocalStackSize()24909467b48Spatrick uint64_t getLocalStackSize() const { return LocalStackSize; } 25009467b48Spatrick setOutliningStyle(std::string Style)251097a140dSpatrick void setOutliningStyle(std::string Style) { OutliningStyle = Style; } getOutliningStyle()252*d415bd75Srobert std::optional<std::string> getOutliningStyle() const { 253*d415bd75Srobert return OutliningStyle; 254*d415bd75Srobert } 255097a140dSpatrick setCalleeSavedStackSize(unsigned Size)25609467b48Spatrick void setCalleeSavedStackSize(unsigned Size) { 25709467b48Spatrick CalleeSavedStackSize = Size; 25809467b48Spatrick HasCalleeSavedStackSize = true; 25909467b48Spatrick } 26009467b48Spatrick 26109467b48Spatrick // When CalleeSavedStackSize has not been set (for example when 26209467b48Spatrick // some MachineIR pass is run in isolation), then recalculate 26309467b48Spatrick // the CalleeSavedStackSize directly from the CalleeSavedInfo. 26409467b48Spatrick // Note: This information can only be recalculated after PEI 26509467b48Spatrick // has assigned offsets to the callee save objects. getCalleeSavedStackSize(const MachineFrameInfo & MFI)26609467b48Spatrick unsigned getCalleeSavedStackSize(const MachineFrameInfo &MFI) const { 26709467b48Spatrick bool ValidateCalleeSavedStackSize = false; 26809467b48Spatrick 26909467b48Spatrick #ifndef NDEBUG 27009467b48Spatrick // Make sure the calculated size derived from the CalleeSavedInfo 27109467b48Spatrick // equals the cached size that was calculated elsewhere (e.g. in 27209467b48Spatrick // determineCalleeSaves). 27309467b48Spatrick ValidateCalleeSavedStackSize = HasCalleeSavedStackSize; 27409467b48Spatrick #endif 27509467b48Spatrick 27609467b48Spatrick if (!HasCalleeSavedStackSize || ValidateCalleeSavedStackSize) { 27709467b48Spatrick assert(MFI.isCalleeSavedInfoValid() && "CalleeSavedInfo not calculated"); 27809467b48Spatrick if (MFI.getCalleeSavedInfo().empty()) 27909467b48Spatrick return 0; 28009467b48Spatrick 28109467b48Spatrick int64_t MinOffset = std::numeric_limits<int64_t>::max(); 28209467b48Spatrick int64_t MaxOffset = std::numeric_limits<int64_t>::min(); 28309467b48Spatrick for (const auto &Info : MFI.getCalleeSavedInfo()) { 28409467b48Spatrick int FrameIdx = Info.getFrameIdx(); 28509467b48Spatrick if (MFI.getStackID(FrameIdx) != TargetStackID::Default) 28609467b48Spatrick continue; 28709467b48Spatrick int64_t Offset = MFI.getObjectOffset(FrameIdx); 28809467b48Spatrick int64_t ObjSize = MFI.getObjectSize(FrameIdx); 28909467b48Spatrick MinOffset = std::min<int64_t>(Offset, MinOffset); 29009467b48Spatrick MaxOffset = std::max<int64_t>(Offset + ObjSize, MaxOffset); 29109467b48Spatrick } 29209467b48Spatrick 29373471bf0Spatrick if (SwiftAsyncContextFrameIdx != std::numeric_limits<int>::max()) { 29473471bf0Spatrick int64_t Offset = MFI.getObjectOffset(getSwiftAsyncContextFrameIdx()); 29573471bf0Spatrick int64_t ObjSize = MFI.getObjectSize(getSwiftAsyncContextFrameIdx()); 29673471bf0Spatrick MinOffset = std::min<int64_t>(Offset, MinOffset); 29773471bf0Spatrick MaxOffset = std::max<int64_t>(Offset + ObjSize, MaxOffset); 29873471bf0Spatrick } 29973471bf0Spatrick 30009467b48Spatrick unsigned Size = alignTo(MaxOffset - MinOffset, 16); 30109467b48Spatrick assert((!HasCalleeSavedStackSize || getCalleeSavedStackSize() == Size) && 30209467b48Spatrick "Invalid size calculated for callee saves"); 30309467b48Spatrick return Size; 30409467b48Spatrick } 30509467b48Spatrick 30609467b48Spatrick return getCalleeSavedStackSize(); 30709467b48Spatrick } 30809467b48Spatrick getCalleeSavedStackSize()30909467b48Spatrick unsigned getCalleeSavedStackSize() const { 31009467b48Spatrick assert(HasCalleeSavedStackSize && 31109467b48Spatrick "CalleeSavedStackSize has not been calculated"); 31209467b48Spatrick return CalleeSavedStackSize; 31309467b48Spatrick } 31409467b48Spatrick 31509467b48Spatrick // Saves the CalleeSavedStackSize for SVE vectors in 'scalable bytes' setSVECalleeSavedStackSize(unsigned Size)31609467b48Spatrick void setSVECalleeSavedStackSize(unsigned Size) { 31709467b48Spatrick SVECalleeSavedStackSize = Size; 31809467b48Spatrick } getSVECalleeSavedStackSize()31909467b48Spatrick unsigned getSVECalleeSavedStackSize() const { 32009467b48Spatrick return SVECalleeSavedStackSize; 32109467b48Spatrick } 32209467b48Spatrick setMinMaxSVECSFrameIndex(int Min,int Max)32309467b48Spatrick void setMinMaxSVECSFrameIndex(int Min, int Max) { 32409467b48Spatrick MinSVECSFrameIndex = Min; 32509467b48Spatrick MaxSVECSFrameIndex = Max; 32609467b48Spatrick } 32709467b48Spatrick getMinSVECSFrameIndex()32809467b48Spatrick int getMinSVECSFrameIndex() const { return MinSVECSFrameIndex; } getMaxSVECSFrameIndex()32909467b48Spatrick int getMaxSVECSFrameIndex() const { return MaxSVECSFrameIndex; } 33009467b48Spatrick incNumLocalDynamicTLSAccesses()33109467b48Spatrick void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamicTLSAccesses; } getNumLocalDynamicTLSAccesses()33209467b48Spatrick unsigned getNumLocalDynamicTLSAccesses() const { 33309467b48Spatrick return NumLocalDynamicTLSAccesses; 33409467b48Spatrick } 33509467b48Spatrick hasRedZone()336*d415bd75Srobert std::optional<bool> hasRedZone() const { return HasRedZone; } setHasRedZone(bool s)33709467b48Spatrick void setHasRedZone(bool s) { HasRedZone = s; } 33809467b48Spatrick getVarArgsStackIndex()33909467b48Spatrick int getVarArgsStackIndex() const { return VarArgsStackIndex; } setVarArgsStackIndex(int Index)34009467b48Spatrick void setVarArgsStackIndex(int Index) { VarArgsStackIndex = Index; } 34109467b48Spatrick getVarArgsStackOffset()342*d415bd75Srobert unsigned getVarArgsStackOffset() const { return VarArgsStackOffset; } setVarArgsStackOffset(unsigned Offset)343*d415bd75Srobert void setVarArgsStackOffset(unsigned Offset) { VarArgsStackOffset = Offset; } 344*d415bd75Srobert getVarArgsGPRIndex()34509467b48Spatrick int getVarArgsGPRIndex() const { return VarArgsGPRIndex; } setVarArgsGPRIndex(int Index)34609467b48Spatrick void setVarArgsGPRIndex(int Index) { VarArgsGPRIndex = Index; } 34709467b48Spatrick getVarArgsGPRSize()34809467b48Spatrick unsigned getVarArgsGPRSize() const { return VarArgsGPRSize; } setVarArgsGPRSize(unsigned Size)34909467b48Spatrick void setVarArgsGPRSize(unsigned Size) { VarArgsGPRSize = Size; } 35009467b48Spatrick getVarArgsFPRIndex()35109467b48Spatrick int getVarArgsFPRIndex() const { return VarArgsFPRIndex; } setVarArgsFPRIndex(int Index)35209467b48Spatrick void setVarArgsFPRIndex(int Index) { VarArgsFPRIndex = Index; } 35309467b48Spatrick getVarArgsFPRSize()35409467b48Spatrick unsigned getVarArgsFPRSize() const { return VarArgsFPRSize; } setVarArgsFPRSize(unsigned Size)35509467b48Spatrick void setVarArgsFPRSize(unsigned Size) { VarArgsFPRSize = Size; } 35609467b48Spatrick getSRetReturnReg()35709467b48Spatrick unsigned getSRetReturnReg() const { return SRetReturnReg; } setSRetReturnReg(unsigned Reg)35809467b48Spatrick void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; } 35909467b48Spatrick getJumpTableEntrySize(int Idx)36009467b48Spatrick unsigned getJumpTableEntrySize(int Idx) const { 36173471bf0Spatrick return JumpTableEntryInfo[Idx].first; 36209467b48Spatrick } getJumpTableEntryPCRelSymbol(int Idx)36309467b48Spatrick MCSymbol *getJumpTableEntryPCRelSymbol(int Idx) const { 36473471bf0Spatrick return JumpTableEntryInfo[Idx].second; 36509467b48Spatrick } setJumpTableEntryInfo(int Idx,unsigned Size,MCSymbol * PCRelSym)36609467b48Spatrick void setJumpTableEntryInfo(int Idx, unsigned Size, MCSymbol *PCRelSym) { 36773471bf0Spatrick if ((unsigned)Idx >= JumpTableEntryInfo.size()) 36873471bf0Spatrick JumpTableEntryInfo.resize(Idx+1); 36909467b48Spatrick JumpTableEntryInfo[Idx] = std::make_pair(Size, PCRelSym); 37009467b48Spatrick } 37109467b48Spatrick 37209467b48Spatrick using SetOfInstructions = SmallPtrSet<const MachineInstr *, 16>; 37309467b48Spatrick getLOHRelated()37409467b48Spatrick const SetOfInstructions &getLOHRelated() const { return LOHRelated; } 37509467b48Spatrick 37609467b48Spatrick // Shortcuts for LOH related types. 37709467b48Spatrick class MILOHDirective { 37809467b48Spatrick MCLOHType Kind; 37909467b48Spatrick 38009467b48Spatrick /// Arguments of this directive. Order matters. 38109467b48Spatrick SmallVector<const MachineInstr *, 3> Args; 38209467b48Spatrick 38309467b48Spatrick public: 38409467b48Spatrick using LOHArgs = ArrayRef<const MachineInstr *>; 38509467b48Spatrick MILOHDirective(MCLOHType Kind,LOHArgs Args)38609467b48Spatrick MILOHDirective(MCLOHType Kind, LOHArgs Args) 38709467b48Spatrick : Kind(Kind), Args(Args.begin(), Args.end()) { 38809467b48Spatrick assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!"); 38909467b48Spatrick } 39009467b48Spatrick getKind()39109467b48Spatrick MCLOHType getKind() const { return Kind; } getArgs()39209467b48Spatrick LOHArgs getArgs() const { return Args; } 39309467b48Spatrick }; 39409467b48Spatrick 39509467b48Spatrick using MILOHArgs = MILOHDirective::LOHArgs; 39609467b48Spatrick using MILOHContainer = SmallVector<MILOHDirective, 32>; 39709467b48Spatrick getLOHContainer()39809467b48Spatrick const MILOHContainer &getLOHContainer() const { return LOHContainerSet; } 39909467b48Spatrick 40009467b48Spatrick /// Add a LOH directive of this @p Kind and this @p Args. addLOHDirective(MCLOHType Kind,MILOHArgs Args)40109467b48Spatrick void addLOHDirective(MCLOHType Kind, MILOHArgs Args) { 40209467b48Spatrick LOHContainerSet.push_back(MILOHDirective(Kind, Args)); 40309467b48Spatrick LOHRelated.insert(Args.begin(), Args.end()); 40409467b48Spatrick } 40509467b48Spatrick getForwardedMustTailRegParms()40609467b48Spatrick SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() { 40709467b48Spatrick return ForwardedMustTailRegParms; 40809467b48Spatrick } 40909467b48Spatrick getTaggedBasePointerIndex()410*d415bd75Srobert std::optional<int> getTaggedBasePointerIndex() const { 41173471bf0Spatrick return TaggedBasePointerIndex; 41273471bf0Spatrick } setTaggedBasePointerIndex(int Index)41373471bf0Spatrick void setTaggedBasePointerIndex(int Index) { TaggedBasePointerIndex = Index; } 41473471bf0Spatrick getTaggedBasePointerOffset()41509467b48Spatrick unsigned getTaggedBasePointerOffset() const { 41609467b48Spatrick return TaggedBasePointerOffset; 41709467b48Spatrick } setTaggedBasePointerOffset(unsigned Offset)41809467b48Spatrick void setTaggedBasePointerOffset(unsigned Offset) { 41909467b48Spatrick TaggedBasePointerOffset = Offset; 42009467b48Spatrick } 42109467b48Spatrick getCalleeSaveBaseToFrameRecordOffset()42273471bf0Spatrick int getCalleeSaveBaseToFrameRecordOffset() const { 42373471bf0Spatrick return CalleeSaveBaseToFrameRecordOffset; 42473471bf0Spatrick } setCalleeSaveBaseToFrameRecordOffset(int Offset)42573471bf0Spatrick void setCalleeSaveBaseToFrameRecordOffset(int Offset) { 42673471bf0Spatrick CalleeSaveBaseToFrameRecordOffset = Offset; 42773471bf0Spatrick } 42873471bf0Spatrick 429*d415bd75Srobert bool shouldSignReturnAddress(const MachineFunction &MF) const; 43073471bf0Spatrick bool shouldSignReturnAddress(bool SpillsLR) const; 43173471bf0Spatrick shouldSignWithBKey()43273471bf0Spatrick bool shouldSignWithBKey() const { return SignWithBKey; } isMTETagged()433*d415bd75Srobert bool isMTETagged() const { return IsMTETagged; } 43473471bf0Spatrick branchTargetEnforcement()43573471bf0Spatrick bool branchTargetEnforcement() const { return BranchTargetEnforcement; } 43673471bf0Spatrick setHasSwiftAsyncContext(bool HasContext)43773471bf0Spatrick void setHasSwiftAsyncContext(bool HasContext) { 43873471bf0Spatrick HasSwiftAsyncContext = HasContext; 43973471bf0Spatrick } hasSwiftAsyncContext()44073471bf0Spatrick bool hasSwiftAsyncContext() const { return HasSwiftAsyncContext; } 44173471bf0Spatrick setSwiftAsyncContextFrameIdx(int FI)44273471bf0Spatrick void setSwiftAsyncContextFrameIdx(int FI) { 44373471bf0Spatrick SwiftAsyncContextFrameIdx = FI; 44473471bf0Spatrick } getSwiftAsyncContextFrameIdx()44573471bf0Spatrick int getSwiftAsyncContextFrameIdx() const { return SwiftAsyncContextFrameIdx; } 44673471bf0Spatrick 447*d415bd75Srobert bool needsDwarfUnwindInfo(const MachineFunction &MF) const; 448*d415bd75Srobert bool needsAsyncDwarfUnwindInfo(const MachineFunction &MF) const; 449*d415bd75Srobert 45009467b48Spatrick private: 45109467b48Spatrick // Hold the lists of LOHs. 45209467b48Spatrick MILOHContainer LOHContainerSet; 45309467b48Spatrick SetOfInstructions LOHRelated; 45409467b48Spatrick 45573471bf0Spatrick SmallVector<std::pair<unsigned, MCSymbol *>, 2> JumpTableEntryInfo; 45609467b48Spatrick }; 45709467b48Spatrick 458097a140dSpatrick namespace yaml { 459097a140dSpatrick struct AArch64FunctionInfo final : public yaml::MachineFunctionInfo { 460*d415bd75Srobert std::optional<bool> HasRedZone; 461097a140dSpatrick 462097a140dSpatrick AArch64FunctionInfo() = default; 463097a140dSpatrick AArch64FunctionInfo(const llvm::AArch64FunctionInfo &MFI); 464097a140dSpatrick 465097a140dSpatrick void mappingImpl(yaml::IO &YamlIO) override; 466097a140dSpatrick ~AArch64FunctionInfo() = default; 467097a140dSpatrick }; 468097a140dSpatrick 469097a140dSpatrick template <> struct MappingTraits<AArch64FunctionInfo> { 470097a140dSpatrick static void mapping(IO &YamlIO, AArch64FunctionInfo &MFI) { 471097a140dSpatrick YamlIO.mapOptional("hasRedZone", MFI.HasRedZone); 472097a140dSpatrick } 473097a140dSpatrick }; 474097a140dSpatrick 475097a140dSpatrick } // end namespace yaml 476097a140dSpatrick 47709467b48Spatrick } // end namespace llvm 47809467b48Spatrick 47909467b48Spatrick #endif // LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEFUNCTIONINFO_H 480