1 | //=- RISCVMachineFunctionInfo.h - RISC-V machine function info ----*- 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 file declares RISCV-specific per-machine-function information. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H |
14 | #define LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H |
15 | |
16 | #include "RISCVSubtarget.h" |
17 | #include "llvm/CodeGen/MIRYamlMapping.h" |
18 | #include "llvm/CodeGen/MachineFrameInfo.h" |
19 | #include "llvm/CodeGen/MachineFunction.h" |
20 | |
21 | namespace llvm { |
22 | |
23 | class RISCVMachineFunctionInfo; |
24 | |
25 | namespace yaml { |
26 | struct RISCVMachineFunctionInfo final : public yaml::MachineFunctionInfo { |
27 | int VarArgsFrameIndex; |
28 | int VarArgsSaveSize; |
29 | |
30 | RISCVMachineFunctionInfo() = default; |
31 | RISCVMachineFunctionInfo(const llvm::RISCVMachineFunctionInfo &MFI); |
32 | |
33 | void mappingImpl(yaml::IO &YamlIO) override; |
34 | ~RISCVMachineFunctionInfo() = default; |
35 | }; |
36 | |
37 | template <> struct MappingTraits<RISCVMachineFunctionInfo> { |
38 | static void mapping(IO &YamlIO, RISCVMachineFunctionInfo &MFI) { |
39 | YamlIO.mapOptional(Key: "varArgsFrameIndex" , Val&: MFI.VarArgsFrameIndex); |
40 | YamlIO.mapOptional(Key: "varArgsSaveSize" , Val&: MFI.VarArgsSaveSize); |
41 | } |
42 | }; |
43 | } // end namespace yaml |
44 | |
45 | /// RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo |
46 | /// and contains private RISCV-specific information for each MachineFunction. |
47 | class RISCVMachineFunctionInfo : public MachineFunctionInfo { |
48 | private: |
49 | /// FrameIndex for start of varargs area |
50 | int VarArgsFrameIndex = 0; |
51 | /// Size of the save area used for varargs |
52 | int VarArgsSaveSize = 0; |
53 | /// FrameIndex used for transferring values between 64-bit FPRs and a pair |
54 | /// of 32-bit GPRs via the stack. |
55 | int MoveF64FrameIndex = -1; |
56 | /// FrameIndex of the spill slot for the scratch register in BranchRelaxation. |
57 | int BranchRelaxationScratchFrameIndex = -1; |
58 | /// Size of any opaque stack adjustment due to save/restore libcalls. |
59 | unsigned LibCallStackSize = 0; |
60 | /// Size of RVV stack. |
61 | uint64_t RVVStackSize = 0; |
62 | /// Alignment of RVV stack. |
63 | Align RVVStackAlign; |
64 | /// Padding required to keep RVV stack aligned within the main stack. |
65 | uint64_t RVVPadding = 0; |
66 | /// Size of stack frame to save callee saved registers |
67 | unsigned CalleeSavedStackSize = 0; |
68 | /// Is there any vector argument or return? |
69 | bool IsVectorCall = false; |
70 | |
71 | /// Registers that have been sign extended from i32. |
72 | SmallVector<Register, 8> SExt32Registers; |
73 | |
74 | /// Size of stack frame for Zcmp PUSH/POP |
75 | unsigned RVPushStackSize = 0; |
76 | unsigned RVPushRegs = 0; |
77 | int RVPushRlist = llvm::RISCVZC::RLISTENCODE::INVALID_RLIST; |
78 | |
79 | public: |
80 | RISCVMachineFunctionInfo(const Function &F, const TargetSubtargetInfo *STI) {} |
81 | |
82 | MachineFunctionInfo * |
83 | clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, |
84 | const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) |
85 | const override; |
86 | |
87 | int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } |
88 | void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } |
89 | |
90 | unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; } |
91 | void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; } |
92 | |
93 | int getMoveF64FrameIndex(MachineFunction &MF) { |
94 | if (MoveF64FrameIndex == -1) |
95 | MoveF64FrameIndex = |
96 | MF.getFrameInfo().CreateStackObject(Size: 8, Alignment: Align(8), isSpillSlot: false); |
97 | return MoveF64FrameIndex; |
98 | } |
99 | |
100 | int getBranchRelaxationScratchFrameIndex() const { |
101 | return BranchRelaxationScratchFrameIndex; |
102 | } |
103 | void setBranchRelaxationScratchFrameIndex(int Index) { |
104 | BranchRelaxationScratchFrameIndex = Index; |
105 | } |
106 | |
107 | unsigned getReservedSpillsSize() const { |
108 | return LibCallStackSize + RVPushStackSize; |
109 | } |
110 | |
111 | unsigned getLibCallStackSize() const { return LibCallStackSize; } |
112 | void setLibCallStackSize(unsigned Size) { LibCallStackSize = Size; } |
113 | |
114 | bool useSaveRestoreLibCalls(const MachineFunction &MF) const { |
115 | // We cannot use fixed locations for the callee saved spill slots if the |
116 | // function uses a varargs save area, or is an interrupt handler. |
117 | return !isPushable(MF) && |
118 | MF.getSubtarget<RISCVSubtarget>().enableSaveRestore() && |
119 | VarArgsSaveSize == 0 && !MF.getFrameInfo().hasTailCall() && |
120 | !MF.getFunction().hasFnAttribute(Kind: "interrupt" ); |
121 | } |
122 | |
123 | uint64_t getRVVStackSize() const { return RVVStackSize; } |
124 | void setRVVStackSize(uint64_t Size) { RVVStackSize = Size; } |
125 | |
126 | Align getRVVStackAlign() const { return RVVStackAlign; } |
127 | void setRVVStackAlign(Align StackAlign) { RVVStackAlign = StackAlign; } |
128 | |
129 | uint64_t getRVVPadding() const { return RVVPadding; } |
130 | void setRVVPadding(uint64_t Padding) { RVVPadding = Padding; } |
131 | |
132 | unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; } |
133 | void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; } |
134 | |
135 | bool isPushable(const MachineFunction &MF) const { |
136 | // We cannot use fixed locations for the callee saved spill slots if the |
137 | // function uses a varargs save area. |
138 | // TODO: Use a separate placement for vararg registers to enable Zcmp. |
139 | return MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() && |
140 | !MF.getTarget().Options.DisableFramePointerElim(MF) && |
141 | VarArgsSaveSize == 0; |
142 | } |
143 | |
144 | int getRVPushRlist() const { return RVPushRlist; } |
145 | void setRVPushRlist(int Rlist) { RVPushRlist = Rlist; } |
146 | |
147 | unsigned getRVPushRegs() const { return RVPushRegs; } |
148 | void setRVPushRegs(unsigned Regs) { RVPushRegs = Regs; } |
149 | |
150 | unsigned getRVPushStackSize() const { return RVPushStackSize; } |
151 | void setRVPushStackSize(unsigned Size) { RVPushStackSize = Size; } |
152 | |
153 | void initializeBaseYamlFields(const yaml::RISCVMachineFunctionInfo &YamlMFI); |
154 | |
155 | void addSExt32Register(Register Reg); |
156 | bool isSExt32Register(Register Reg) const; |
157 | |
158 | bool isVectorCall() const { return IsVectorCall; } |
159 | void setIsVectorCall() { IsVectorCall = true; } |
160 | }; |
161 | |
162 | } // end namespace llvm |
163 | |
164 | #endif // LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H |
165 | |