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
19namespace llvm {
20
21class AArch64FrameLowering : public TargetFrameLowering {
22public:
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
125private:
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