xref: /llvm-project/llvm/lib/Target/RISCV/RISCVFrameLowering.h (revision 01d7f434d21a70158094a9c7da971ce9e0d0915c)
1 //===-- RISCVFrameLowering.h - Define frame lowering for RISC-V -*- 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 // This class implements RISC-V specific bits of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H
14 #define LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H
15 
16 #include "llvm/CodeGen/TargetFrameLowering.h"
17 #include "llvm/Support/TypeSize.h"
18 
19 namespace llvm {
20 class RISCVSubtarget;
21 
22 class RISCVFrameLowering : public TargetFrameLowering {
23 public:
24   explicit RISCVFrameLowering(const RISCVSubtarget &STI);
25 
26   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
27   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
28 
29   uint64_t getStackSizeWithRVVPadding(const MachineFunction &MF) const;
30 
31   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
32                                      Register &FrameReg) const override;
33 
34   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
35                             RegScavenger *RS) const override;
36 
37   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
38                                            RegScavenger *RS) const override;
39 
40   bool hasBP(const MachineFunction &MF) const;
41 
42   bool hasReservedCallFrame(const MachineFunction &MF) const override;
43   MachineBasicBlock::iterator
44   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
45                                 MachineBasicBlock::iterator MI) const override;
46 
47   bool assignCalleeSavedSpillSlots(MachineFunction &MF,
48                                    const TargetRegisterInfo *TRI,
49                                    std::vector<CalleeSavedInfo> &CSI,
50                                    unsigned &MinCSFrameIndex,
51                                    unsigned &MaxCSFrameIndex) const override;
52   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
53                                  MachineBasicBlock::iterator MI,
54                                  ArrayRef<CalleeSavedInfo> CSI,
55                                  const TargetRegisterInfo *TRI) const override;
56   bool
57   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
58                               MachineBasicBlock::iterator MI,
59                               MutableArrayRef<CalleeSavedInfo> CSI,
60                               const TargetRegisterInfo *TRI) const override;
61 
62   // Get the first stack adjustment amount for SplitSPAdjust.
63   // Return 0 if we don't want to split the SP adjustment in prologue and
64   // epilogue.
65   uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const;
66 
67   bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
68   bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
69 
70   bool enableShrinkWrapping(const MachineFunction &MF) const override;
71 
72   bool isSupportedStackID(TargetStackID::Value ID) const override;
73   TargetStackID::Value getStackIDForScalableVectors() const override;
74 
75   bool isStackIdSafeForLocalArea(unsigned StackId) const override {
76     // We don't support putting RISC-V Vector objects into the pre-allocated
77     // local frame block at the moment.
78     return StackId != TargetStackID::ScalableVector;
79   }
80 
81   void allocateStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
82                      MachineFunction &MF, uint64_t Offset,
83                      uint64_t RealStackSize, bool EmitCFI, bool NeedProbe,
84                      uint64_t ProbeSize, bool DynAllocation) const;
85 
86 protected:
87   const RISCVSubtarget &STI;
88 
89   bool hasFPImpl(const MachineFunction &MF) const override;
90 
91 private:
92   void determineFrameLayout(MachineFunction &MF) const;
93   void emitCalleeSavedRVVPrologCFI(MachineBasicBlock &MBB,
94                                    MachineBasicBlock::iterator MI,
95                                    bool HasFP) const;
96   void emitCalleeSavedRVVEpilogCFI(MachineBasicBlock &MBB,
97                                    MachineBasicBlock::iterator MI) const;
98   template <typename Emitter>
99   void emitCFIForCSI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
100                      const SmallVector<CalleeSavedInfo, 8> &CSI) const;
101   void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB,
102                        MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
103                        uint64_t &StackSize, int64_t CFAOffset) const;
104 
105   std::pair<int64_t, Align>
106   assignRVVStackObjectOffsets(MachineFunction &MF) const;
107   // Replace a StackProbe stub (if any) with the actual probe code inline
108   void inlineStackProbe(MachineFunction &MF,
109                         MachineBasicBlock &PrologueMBB) const override;
110   void allocateAndProbeStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
111                                    MachineBasicBlock::iterator MBBI,
112                                    const DebugLoc &DL, int64_t Amount,
113                                    MachineInstr::MIFlag Flag, bool EmitCFI,
114                                    bool DynAllocation) const;
115 };
116 } // namespace llvm
117 #endif
118