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