1 //===-- RISCVFrameLowering.h - Define frame lowering for RISCV -*- 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 RISCV-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       : TargetFrameLowering(StackGrowsDown,
26                             /*StackAlignment=*/Align(16),
27                             /*LocalAreaOffset=*/0,
28                             /*TransientStackAlignment=*/Align(16)),
29         STI(STI) {}
30 
31   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
32   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
33 
34   uint64_t getStackSizeWithRVVPadding(const MachineFunction &MF) const;
35 
36   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
37                                      Register &FrameReg) const override;
38 
39   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
40                             RegScavenger *RS) const override;
41 
42   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
43                                            RegScavenger *RS) const override;
44 
45   bool hasFP(const MachineFunction &MF) const override;
46 
47   bool hasBP(const MachineFunction &MF) const;
48 
49   bool hasReservedCallFrame(const MachineFunction &MF) const override;
50   MachineBasicBlock::iterator
51   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
52                                 MachineBasicBlock::iterator MI) const override;
53   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
54                                  MachineBasicBlock::iterator MI,
55                                  ArrayRef<CalleeSavedInfo> CSI,
56                                  const TargetRegisterInfo *TRI) const override;
57   bool
58   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
59                               MachineBasicBlock::iterator MI,
60                               MutableArrayRef<CalleeSavedInfo> CSI,
61                               const TargetRegisterInfo *TRI) const override;
62 
63   // Get the first stack adjustment amount for SplitSPAdjust.
64   // Return 0 if we don't want to to split the SP adjustment in prologue and
65   // epilogue.
66   uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const;
67 
68   bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
69   bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
70 
71   bool enableShrinkWrapping(const MachineFunction &MF) const override;
72 
73   bool isSupportedStackID(TargetStackID::Value ID) const override;
74   TargetStackID::Value getStackIDForScalableVectors() const override;
75 
76   bool isStackIdSafeForLocalArea(unsigned StackId) const override {
77     // We don't support putting RISCV Vector objects into the pre-allocated
78     // local frame block at the moment.
79     return StackId != TargetStackID::ScalableVector;
80   }
81 
82 protected:
83   const RISCVSubtarget &STI;
84 
85 private:
86   void determineFrameLayout(MachineFunction &MF) const;
87   void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
88                          MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
89                          int64_t Amount, MachineInstr::MIFlag Flag) const;
90   std::pair<int64_t, Align>
91   assignRVVStackObjectOffsets(MachineFunction &MF) const;
92 };
93 } // namespace llvm
94 #endif
95