brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · 7f297b5 Raw
213 lines · c
1//===----------------------------------------------------------------------===//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/// \file10/// This file contains the declaration of the AArch64PrologueEmitter and11/// AArch64EpilogueEmitter classes, which are is used to emit the prologue and12/// epilogue on AArch64.13///14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64PROLOGUEEPILOGUE_H17#define LLVM_LIB_TARGET_AARCH64_AARCH64PROLOGUEEPILOGUE_H18 19#include "AArch64RegisterInfo.h"20#include "llvm/CodeGen/LivePhysRegs.h"21#include "llvm/CodeGen/MachineFunction.h"22 23namespace llvm {24 25class TargetLowering;26class AArch64Subtarget;27class AArch64FunctionInfo;28class AArch64FrameLowering;29 30struct SVEFrameSizes {31  struct {32    StackOffset CalleeSavesSize, LocalsSize;33  } PPR, ZPR;34};35 36struct SVEStackAllocations {37  StackOffset BeforePPRs, AfterPPRs, AfterZPRs;38  StackOffset totalSize() const { return BeforePPRs + AfterPPRs + AfterZPRs; }39};40 41class AArch64PrologueEpilogueCommon {42public:43  AArch64PrologueEpilogueCommon(MachineFunction &MF, MachineBasicBlock &MBB,44                                const AArch64FrameLowering &AFL);45 46  enum class SVEStackLayout {47    Default,48    Split,49    CalleeSavesAboveFrameRecord,50  };51 52protected:53  bool requiresGetVGCall() const;54 55  bool isVGInstruction(MachineBasicBlock::iterator MBBI,56                       const TargetLowering &TLI) const;57 58  // Convert callee-save register save/restore instruction to do stack pointer59  // decrement/increment to allocate/deallocate the callee-save stack area by60  // converting store/load to use pre/post increment version.61  MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(62      MachineBasicBlock::iterator MBBI, const DebugLoc &DL, int CSStackSizeInc,63      bool EmitCFI, MachineInstr::MIFlag FrameFlag = MachineInstr::FrameSetup,64      int CFAOffset = 0) const;65 66  // Fixup callee-save register save/restore instructions to take into account67  // combined SP bump by adding the local stack size to the stack offsets.68  void fixupCalleeSaveRestoreStackOffset(MachineInstr &MI,69                                         uint64_t LocalStackSize) const;70 71  bool shouldCombineCSRLocalStackBump(uint64_t StackBumpBytes) const;72 73  SVEFrameSizes getSVEStackFrameSizes() const;74  SVEStackAllocations getSVEStackAllocations(SVEFrameSizes const &);75 76  MachineFunction &MF;77  MachineBasicBlock &MBB;78 79  const MachineFrameInfo &MFI;80  const AArch64Subtarget &Subtarget;81  const AArch64FrameLowering &AFL;82  const AArch64RegisterInfo &RegInfo;83 84  // Common flags. These generally should not change outside of the (possibly85  // derived) constructor.86  bool HasFP = false;87  bool EmitCFI = false;     // Note: Set in derived constructors.88  bool IsFunclet = false;   // Note: Set in derived constructors.89  bool NeedsWinCFI = false; // Note: Can be changed in emitFramePointerSetup.90  bool HomPrologEpilog = false; // Note: Set in derived constructors.91  SVEStackLayout SVELayout = SVEStackLayout::Default;92 93  // Note: "HasWinCFI" is mutable as it can change in any "emit" function.94  mutable bool HasWinCFI = false;95 96  const TargetInstrInfo *TII = nullptr;97  AArch64FunctionInfo *AFI = nullptr;98};99 100/// A helper class for emitting the prologue. Substantial new functionality101/// should be factored into a new method. Where possible "emit*" methods should102/// be const, and any flags that change how the prologue is emitted should be103/// set in the constructor.104class AArch64PrologueEmitter final : public AArch64PrologueEpilogueCommon {105public:106  AArch64PrologueEmitter(MachineFunction &MF, MachineBasicBlock &MBB,107                         const AArch64FrameLowering &AFL);108 109  /// Emit the prologue.110  void emitPrologue();111 112  ~AArch64PrologueEmitter() {113    MF.setHasWinCFI(HasWinCFI);114#ifndef NDEBUG115    verifyPrologueClobbers();116#endif117  }118 119private:120  void allocateStackSpace(MachineBasicBlock::iterator MBBI,121                          int64_t RealignmentPadding, StackOffset AllocSize,122                          bool EmitCFI, StackOffset InitialOffset,123                          bool FollowupAllocs);124 125  void emitShadowCallStackPrologue(MachineBasicBlock::iterator MBBI,126                                   const DebugLoc &DL) const;127 128  void emitSwiftAsyncContextFramePointer(MachineBasicBlock::iterator MBBI,129                                         const DebugLoc &DL) const;130 131  void emitEmptyStackFramePrologue(int64_t NumBytes,132                                   MachineBasicBlock::iterator MBBI,133                                   const DebugLoc &DL) const;134 135  void emitFramePointerSetup(MachineBasicBlock::iterator MBBI,136                             const DebugLoc &DL, unsigned FixedObject);137 138  void emitDefineCFAWithFP(MachineBasicBlock::iterator MBBI,139                           unsigned FixedObject) const;140 141  void emitWindowsStackProbe(MachineBasicBlock::iterator MBBI,142                             const DebugLoc &DL, int64_t &NumBytes,143                             int64_t RealignmentPadding) const;144 145  void emitCalleeSavedGPRLocations(MachineBasicBlock::iterator MBBI) const;146  void emitCalleeSavedSVELocations(MachineBasicBlock::iterator MBBI) const;147 148  void determineLocalsStackSize(uint64_t StackSize, uint64_t PrologueSaveSize);149 150  const Function &F;151 152#ifndef NDEBUG153  mutable LivePhysRegs LiveRegs{RegInfo};154  MachineBasicBlock::iterator PrologueEndI;155 156  void collectBlockLiveins();157  void verifyPrologueClobbers() const;158#endif159 160  // Prologue flags. These generally should not change outside of the161  // constructor.162  bool EmitAsyncCFI = false;163  bool CombineSPBump = false; // Note: This is set in determineLocalsStackSize.164};165 166/// A helper class for emitting the epilogue. Substantial new functionality167/// should be factored into a new method. Where possible "emit*" methods should168/// be const, and any flags that change how the epilogue is emitted should be169/// set in the constructor.170class AArch64EpilogueEmitter final : public AArch64PrologueEpilogueCommon {171public:172  AArch64EpilogueEmitter(MachineFunction &MF, MachineBasicBlock &MBB,173                         const AArch64FrameLowering &AFL);174 175  /// Emit the epilogue.176  void emitEpilogue();177 178  ~AArch64EpilogueEmitter() { finalizeEpilogue(); }179 180private:181  bool shouldCombineCSRLocalStackBump(uint64_t StackBumpBytes) const;182 183  /// A helper for moving the SP to a negative offset from the FP, without184  /// deallocating any stack in the range FP to FP + Offset.185  void moveSPBelowFP(MachineBasicBlock::iterator MBBI, StackOffset Offset);186 187  void emitSwiftAsyncContextFramePointer(MachineBasicBlock::iterator MBBI,188                                         const DebugLoc &DL) const;189 190  void emitShadowCallStackEpilogue(MachineBasicBlock::iterator MBBI,191                                   const DebugLoc &DL) const;192 193  void emitCalleeSavedRestores(MachineBasicBlock::iterator MBBI,194                               bool SVE) const;195 196  void emitCalleeSavedGPRRestores(MachineBasicBlock::iterator MBBI) const {197    emitCalleeSavedRestores(MBBI, /*SVE=*/false);198  }199 200  void emitCalleeSavedSVERestores(MachineBasicBlock::iterator MBBI) const {201    emitCalleeSavedRestores(MBBI, /*SVE=*/true);202  }203 204  void finalizeEpilogue() const;205 206  MachineBasicBlock::iterator SEHEpilogueStartI;207  DebugLoc DL;208};209 210} // namespace llvm211 212#endif213