xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVFrameLowering.h (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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 
isStackIdSafeForLocalArea(unsigned StackId)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,
85                      MachineInstr::MIFlag Flag) const;
86 
87 protected:
88   const RISCVSubtarget &STI;
89 
90   bool hasFPImpl(const MachineFunction &MF) const override;
91 
92 private:
93   void determineFrameLayout(MachineFunction &MF) const;
94   void emitCalleeSavedRVVPrologCFI(MachineBasicBlock &MBB,
95                                    MachineBasicBlock::iterator MI,
96                                    bool HasFP) const;
97   void emitCalleeSavedRVVEpilogCFI(MachineBasicBlock &MBB,
98                                    MachineBasicBlock::iterator MI) const;
99   template <typename Emitter>
100   void emitCFIForCSI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
101                      const SmallVector<CalleeSavedInfo, 8> &CSI) const;
102   void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB,
103                        MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
104                        uint64_t &StackSize, int64_t CFAOffset) const;
105 
106   std::pair<int64_t, Align>
107   assignRVVStackObjectOffsets(MachineFunction &MF) const;
108   // Replace a StackProbe stub (if any) with the actual probe code inline
109   void inlineStackProbe(MachineFunction &MF,
110                         MachineBasicBlock &PrologueMBB) const override;
111   void allocateAndProbeStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
112                                    MachineBasicBlock::iterator MBBI,
113                                    const DebugLoc &DL, int64_t Amount,
114                                    MachineInstr::MIFlag Flag, bool EmitCFI,
115                                    bool DynAllocation) const;
116 };
117 } // namespace llvm
118 #endif
119