brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.9 KiB · 32a9bd8 Raw
261 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9//10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H14#define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H15 16#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"17#include "llvm/CodeGen/TargetFrameLowering.h"18#include "llvm/Support/TypeSize.h"19 20namespace llvm {21 22class TargetLowering;23class AArch64FunctionInfo;24class AArch64PrologueEmitter;25class AArch64EpilogueEmitter;26 27struct SVEStackSizes {28  uint64_t ZPRStackSize{0};29  uint64_t PPRStackSize{0};30};31 32class AArch64FrameLowering : public TargetFrameLowering {33public:34  explicit AArch64FrameLowering()35      : TargetFrameLowering(StackGrowsDown, Align(16), 0, Align(16),36                            true /*StackRealignable*/) {}37 38  void resetCFIToInitialState(MachineBasicBlock &MBB) const override;39 40  MachineBasicBlock::iterator41  eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,42                                MachineBasicBlock::iterator I) const override;43 44  /// emitProlog/emitEpilog - These methods insert prolog and epilog code into45  /// the function.46  void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;47  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;48 49  /// Harden the entire function with pac-ret.50  ///51  /// If pac-ret+leaf is requested, we want to harden as much code as possible.52  /// This function inserts pac-ret hardening at the points where prologue and53  /// epilogue are traditionally inserted, ignoring possible shrink-wrapping54  /// optimization.55  void emitPacRetPlusLeafHardening(MachineFunction &MF) const;56 57  bool enableCFIFixup(const MachineFunction &MF) const override;58 59  bool enableFullCFIFixup(const MachineFunction &MF) const override;60 61  bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;62 63  StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,64                                     Register &FrameReg) const override;65  StackOffset getFrameIndexReferenceFromSP(const MachineFunction &MF,66                                           int FI) const override;67  StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI,68                                         Register &FrameReg, bool PreferFP,69                                         bool ForSimm) const;70  StackOffset resolveFrameOffsetReference(const MachineFunction &MF,71                                          int64_t ObjectOffset, bool isFixed,72                                          TargetStackID::Value StackID,73                                          Register &FrameReg, bool PreferFP,74                                          bool ForSimm) const;75  bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,76                                 MachineBasicBlock::iterator MI,77                                 ArrayRef<CalleeSavedInfo> CSI,78                                 const TargetRegisterInfo *TRI) const override;79 80  bool81  restoreCalleeSavedRegisters(MachineBasicBlock &MBB,82                              MachineBasicBlock::iterator MI,83                              MutableArrayRef<CalleeSavedInfo> CSI,84                              const TargetRegisterInfo *TRI) const override;85 86  /// Can this function use the red zone for local allocations.87  bool canUseRedZone(const MachineFunction &MF) const;88 89  bool hasReservedCallFrame(const MachineFunction &MF) const override;90 91  bool assignCalleeSavedSpillSlots(MachineFunction &MF,92                                   const TargetRegisterInfo *TRI,93                                   std::vector<CalleeSavedInfo> &CSI,94                                   unsigned &MinCSFrameIndex,95                                   unsigned &MaxCSFrameIndex) const override;96 97  void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,98                            RegScavenger *RS) const override;99 100  /// Returns true if the target will correctly handle shrink wrapping.101  bool enableShrinkWrapping(const MachineFunction &MF) const override {102    return true;103  }104 105  bool enableStackSlotScavenging(const MachineFunction &MF) const override;106  TargetStackID::Value getStackIDForScalableVectors() const override;107 108  void processFunctionBeforeFrameFinalized(MachineFunction &MF,109                                           RegScavenger *RS) const override;110 111  void112  processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF,113                                            RegScavenger *RS) const override;114 115  unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;116 117  unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;118 119  StackOffset120  getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,121                                 Register &FrameReg,122                                 bool IgnoreSPUpdates) const override;123  StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF,124                                             int FI) const override;125  int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const;126 127  bool isSupportedStackID(TargetStackID::Value ID) const override {128    switch (ID) {129    default:130      return false;131    case TargetStackID::Default:132    case TargetStackID::ScalableVector:133    case TargetStackID::ScalablePredicateVector:134    case TargetStackID::NoAlloc:135      return true;136    }137  }138 139  bool isStackIdSafeForLocalArea(unsigned StackId) const override {140    // We don't support putting SVE objects into the pre-allocated local141    // frame block at the moment.142    return (StackId != TargetStackID::ScalableVector &&143            StackId != TargetStackID::ScalablePredicateVector);144  }145 146  void147  orderFrameObjects(const MachineFunction &MF,148                    SmallVectorImpl<int> &ObjectsToAllocate) const override;149 150  bool isFPReserved(const MachineFunction &MF) const;151 152  bool needsWinCFI(const MachineFunction &MF) const;153 154  bool requiresSaveVG(const MachineFunction &MF) const;155 156  /// Returns the size of the entire ZPR stackframe (calleesaves + spills).157  StackOffset getZPRStackSize(const MachineFunction &MF) const;158 159  /// Returns the size of the entire PPR stackframe (calleesaves + spills +160  /// hazard padding).161  StackOffset getPPRStackSize(const MachineFunction &MF) const;162 163  /// Returns the size of the entire SVE stackframe (PPRs + ZPRs).164  StackOffset getSVEStackSize(const MachineFunction &MF) const {165    return getZPRStackSize(MF) + getPPRStackSize(MF);166  }167 168  friend class AArch64PrologueEpilogueCommon;169  friend class AArch64PrologueEmitter;170  friend class AArch64EpilogueEmitter;171 172protected:173  bool hasFPImpl(const MachineFunction &MF) const override;174 175private:176  /// Returns true if a homogeneous prolog or epilog code can be emitted177  /// for the size optimization. If so, HOM_Prolog/HOM_Epilog pseudo178  /// instructions are emitted in place. When Exit block is given, this check is179  /// for epilog.180  bool homogeneousPrologEpilog(MachineFunction &MF,181                               MachineBasicBlock *Exit = nullptr) const;182 183  /// Returns true if CSRs should be paired.184  bool producePairRegisters(MachineFunction &MF) const;185 186  /// Make a determination whether a Hazard slot is used and create it if187  /// needed.188  void determineStackHazardSlot(MachineFunction &MF,189                                BitVector &SavedRegs) const;190 191  /// Emit target zero call-used regs.192  void emitZeroCallUsedRegs(BitVector RegsToZero,193                            MachineBasicBlock &MBB) const override;194 195  /// Replace a StackProbe stub (if any) with the actual probe code inline196  void inlineStackProbe(MachineFunction &MF,197                        MachineBasicBlock &PrologueMBB) const override;198 199  void inlineStackProbeFixed(MachineBasicBlock::iterator MBBI,200                             Register ScratchReg, int64_t FrameSize,201                             StackOffset CFAOffset) const;202 203  MachineBasicBlock::iterator204  inlineStackProbeLoopExactMultiple(MachineBasicBlock::iterator MBBI,205                                    int64_t NegProbeSize,206                                    Register TargetReg) const;207 208  void emitRemarks(const MachineFunction &MF,209                   MachineOptimizationRemarkEmitter *ORE) const override;210 211  bool windowsRequiresStackProbe(const MachineFunction &MF,212                                 uint64_t StackSizeInBytes) const;213 214  bool shouldSignReturnAddressEverywhere(const MachineFunction &MF) const;215 216  StackOffset getFPOffset(const MachineFunction &MF,217                          int64_t ObjectOffset) const;218 219  StackOffset getStackOffset(const MachineFunction &MF,220                             int64_t ObjectOffset) const;221 222  // Given a load or a store instruction, generate an appropriate unwinding SEH223  // code on Windows.224  MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI,225                                        const TargetInstrInfo &TII,226                                        MachineInstr::MIFlag Flag) const;227 228  /// Returns how much of the incoming argument stack area (in bytes) we should229  /// clean up in an epilogue. For the C calling convention this will be 0, for230  /// guaranteed tail call conventions it can be positive (a normal return or a231  /// tail call to a function that uses less stack space for arguments) or232  /// negative (for a tail call to a function that needs more stack space than233  /// us for arguments).234  int64_t getArgumentStackToRestore(MachineFunction &MF,235                                    MachineBasicBlock &MBB) const;236 237  // Find a scratch register that we can use at the start of the prologue to238  // re-align the stack pointer.  We avoid using callee-save registers since239  // they may appear to be free when this is called from canUseAsPrologue240  // (during shrink wrapping), but then no longer be free when this is called241  // from emitPrologue.242  //243  // FIXME: This is a bit conservative, since in the above case we could use one244  // of the callee-save registers as a scratch temp to re-align the stack245  // pointer, but we would then have to make sure that we were in fact saving at246  // least one callee-save register in the prologue, which is additional247  // complexity that doesn't seem worth the benefit.248  Register findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB,249                                            bool HasCall = false) const;250 251  /// Returns the size of the fixed object area (allocated next to sp on entry)252  /// On Win64 this may include a var args area and an UnwindHelp object for EH.253  unsigned getFixedObjectSize(const MachineFunction &MF,254                              const AArch64FunctionInfo *AFI, bool IsWin64,255                              bool IsFunclet) const;256};257 258} // End llvm namespace259 260#endif261