1 //==-- AArch64FrameLowering.h - TargetFrameLowering for AArch64 --*- 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 // 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H 14 #define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H 15 16 #include "llvm/Support/TypeSize.h" 17 #include "llvm/CodeGen/TargetFrameLowering.h" 18 19 namespace llvm { 20 21 class AArch64FrameLowering : public TargetFrameLowering { 22 public: 23 explicit AArch64FrameLowering() 24 : TargetFrameLowering(StackGrowsDown, Align(16), 0, Align(16), 25 true /*StackRealignable*/) {} 26 27 void resetCFIToInitialState(MachineBasicBlock &MBB) const override; 28 29 MachineBasicBlock::iterator 30 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 31 MachineBasicBlock::iterator I) const override; 32 33 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into 34 /// the function. 35 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 36 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 37 38 bool enableCFIFixup(MachineFunction &MF) const override; 39 40 bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; 41 42 StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, 43 Register &FrameReg) const override; 44 StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI, 45 Register &FrameReg, bool PreferFP, 46 bool ForSimm) const; 47 StackOffset resolveFrameOffsetReference(const MachineFunction &MF, 48 int64_t ObjectOffset, bool isFixed, 49 bool isSVE, Register &FrameReg, 50 bool PreferFP, bool ForSimm) const; 51 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 52 MachineBasicBlock::iterator MI, 53 ArrayRef<CalleeSavedInfo> CSI, 54 const TargetRegisterInfo *TRI) const override; 55 56 bool 57 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 58 MachineBasicBlock::iterator MI, 59 MutableArrayRef<CalleeSavedInfo> CSI, 60 const TargetRegisterInfo *TRI) const override; 61 62 /// Can this function use the red zone for local allocations. 63 bool canUseRedZone(const MachineFunction &MF) const; 64 65 bool hasFP(const MachineFunction &MF) const override; 66 bool hasReservedCallFrame(const MachineFunction &MF) const override; 67 68 bool assignCalleeSavedSpillSlots(MachineFunction &MF, 69 const TargetRegisterInfo *TRI, 70 std::vector<CalleeSavedInfo> &CSI, 71 unsigned &MinCSFrameIndex, 72 unsigned &MaxCSFrameIndex) const override; 73 74 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, 75 RegScavenger *RS) const override; 76 77 /// Returns true if the target will correctly handle shrink wrapping. 78 bool enableShrinkWrapping(const MachineFunction &MF) const override { 79 return true; 80 } 81 82 bool enableStackSlotScavenging(const MachineFunction &MF) const override; 83 TargetStackID::Value getStackIDForScalableVectors() const override; 84 85 void processFunctionBeforeFrameFinalized(MachineFunction &MF, 86 RegScavenger *RS) const override; 87 88 void 89 processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, 90 RegScavenger *RS) const override; 91 92 unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override; 93 94 unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const; 95 96 StackOffset 97 getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, 98 Register &FrameReg, 99 bool IgnoreSPUpdates) const override; 100 StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, 101 int FI) const override; 102 int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const; 103 104 bool isSupportedStackID(TargetStackID::Value ID) const override { 105 switch (ID) { 106 default: 107 return false; 108 case TargetStackID::Default: 109 case TargetStackID::ScalableVector: 110 case TargetStackID::NoAlloc: 111 return true; 112 } 113 } 114 115 bool isStackIdSafeForLocalArea(unsigned StackId) const override { 116 // We don't support putting SVE objects into the pre-allocated local 117 // frame block at the moment. 118 return StackId != TargetStackID::ScalableVector; 119 } 120 121 void 122 orderFrameObjects(const MachineFunction &MF, 123 SmallVectorImpl<int> &ObjectsToAllocate) const override; 124 125 private: 126 /// Returns true if a homogeneous prolog or epilog code can be emitted 127 /// for the size optimization. If so, HOM_Prolog/HOM_Epilog pseudo 128 /// instructions are emitted in place. When Exit block is given, this check is 129 /// for epilog. 130 bool homogeneousPrologEpilog(MachineFunction &MF, 131 MachineBasicBlock *Exit = nullptr) const; 132 133 /// Returns true if CSRs should be paired. 134 bool producePairRegisters(MachineFunction &MF) const; 135 136 bool shouldCombineCSRLocalStackBump(MachineFunction &MF, 137 uint64_t StackBumpBytes) const; 138 139 int64_t estimateSVEStackObjectOffsets(MachineFrameInfo &MF) const; 140 int64_t assignSVEStackObjectOffsets(MachineFrameInfo &MF, 141 int &MinCSFrameIndex, 142 int &MaxCSFrameIndex) const; 143 bool shouldCombineCSRLocalStackBumpInEpilogue(MachineBasicBlock &MBB, 144 unsigned StackBumpBytes) const; 145 void emitCalleeSavedGPRLocations(MachineBasicBlock &MBB, 146 MachineBasicBlock::iterator MBBI) const; 147 void emitCalleeSavedSVELocations(MachineBasicBlock &MBB, 148 MachineBasicBlock::iterator MBBI) const; 149 void emitCalleeSavedGPRRestores(MachineBasicBlock &MBB, 150 MachineBasicBlock::iterator MBBI) const; 151 void emitCalleeSavedSVERestores(MachineBasicBlock &MBB, 152 MachineBasicBlock::iterator MBBI) const; 153 void allocateStackSpace(MachineBasicBlock &MBB, 154 MachineBasicBlock::iterator MBBI, 155 int64_t RealignmentPadding, StackOffset AllocSize, 156 bool NeedsWinCFI, bool *HasWinCFI, bool EmitCFI, 157 StackOffset InitialOffset, bool FollowupAllocs) const; 158 159 /// Emit target zero call-used regs. 160 void emitZeroCallUsedRegs(BitVector RegsToZero, 161 MachineBasicBlock &MBB) const override; 162 163 /// Replace a StackProbe stub (if any) with the actual probe code inline 164 void inlineStackProbe(MachineFunction &MF, 165 MachineBasicBlock &PrologueMBB) const override; 166 167 void inlineStackProbeFixed(MachineBasicBlock::iterator MBBI, 168 Register ScratchReg, int64_t FrameSize, 169 StackOffset CFAOffset) const; 170 171 MachineBasicBlock::iterator 172 inlineStackProbeLoopExactMultiple(MachineBasicBlock::iterator MBBI, 173 int64_t NegProbeSize, 174 Register TargetReg) const; 175 }; 176 177 } // End llvm namespace 178 179 #endif 180