xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //=- RISCVMachineFunctionInfo.h - RISCV machine function info -----*- C++ -*-=//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares RISCV-specific per-machine-function information.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H
150b57cec5SDimitry Andric 
165ffd83dbSDimitry Andric #include "RISCVSubtarget.h"
173a9a9c0cSDimitry Andric #include "llvm/CodeGen/MIRYamlMapping.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace llvm {
220b57cec5SDimitry Andric 
233a9a9c0cSDimitry Andric class RISCVMachineFunctionInfo;
243a9a9c0cSDimitry Andric 
253a9a9c0cSDimitry Andric namespace yaml {
263a9a9c0cSDimitry Andric struct RISCVMachineFunctionInfo final : public yaml::MachineFunctionInfo {
273a9a9c0cSDimitry Andric   int VarArgsFrameIndex;
283a9a9c0cSDimitry Andric   int VarArgsSaveSize;
293a9a9c0cSDimitry Andric 
303a9a9c0cSDimitry Andric   RISCVMachineFunctionInfo() = default;
313a9a9c0cSDimitry Andric   RISCVMachineFunctionInfo(const llvm::RISCVMachineFunctionInfo &MFI);
323a9a9c0cSDimitry Andric 
333a9a9c0cSDimitry Andric   void mappingImpl(yaml::IO &YamlIO) override;
343a9a9c0cSDimitry Andric   ~RISCVMachineFunctionInfo() = default;
353a9a9c0cSDimitry Andric };
363a9a9c0cSDimitry Andric 
373a9a9c0cSDimitry Andric template <> struct MappingTraits<RISCVMachineFunctionInfo> {
383a9a9c0cSDimitry Andric   static void mapping(IO &YamlIO, RISCVMachineFunctionInfo &MFI) {
393a9a9c0cSDimitry Andric     YamlIO.mapOptional("varArgsFrameIndex", MFI.VarArgsFrameIndex);
403a9a9c0cSDimitry Andric     YamlIO.mapOptional("varArgsSaveSize", MFI.VarArgsSaveSize);
413a9a9c0cSDimitry Andric   }
423a9a9c0cSDimitry Andric };
433a9a9c0cSDimitry Andric } // end namespace yaml
443a9a9c0cSDimitry Andric 
450b57cec5SDimitry Andric /// RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo
460b57cec5SDimitry Andric /// and contains private RISCV-specific information for each MachineFunction.
470b57cec5SDimitry Andric class RISCVMachineFunctionInfo : public MachineFunctionInfo {
480b57cec5SDimitry Andric private:
490b57cec5SDimitry Andric   /// FrameIndex for start of varargs area
500b57cec5SDimitry Andric   int VarArgsFrameIndex = 0;
510b57cec5SDimitry Andric   /// Size of the save area used for varargs
520b57cec5SDimitry Andric   int VarArgsSaveSize = 0;
530b57cec5SDimitry Andric   /// FrameIndex used for transferring values between 64-bit FPRs and a pair
540b57cec5SDimitry Andric   /// of 32-bit GPRs via the stack.
550b57cec5SDimitry Andric   int MoveF64FrameIndex = -1;
56*bdd1243dSDimitry Andric   /// FrameIndex of the spill slot for the scratch register in BranchRelaxation.
57*bdd1243dSDimitry Andric   int BranchRelaxationScratchFrameIndex = -1;
585ffd83dbSDimitry Andric   /// Size of any opaque stack adjustment due to save/restore libcalls.
595ffd83dbSDimitry Andric   unsigned LibCallStackSize = 0;
60fe6060f1SDimitry Andric   /// Size of RVV stack.
61fe6060f1SDimitry Andric   uint64_t RVVStackSize = 0;
6281ad6265SDimitry Andric   /// Alignment of RVV stack.
6381ad6265SDimitry Andric   Align RVVStackAlign;
64fe6060f1SDimitry Andric   /// Padding required to keep RVV stack aligned within the main stack.
65fe6060f1SDimitry Andric   uint64_t RVVPadding = 0;
66fe6060f1SDimitry Andric   /// Size of stack frame to save callee saved registers
67fe6060f1SDimitry Andric   unsigned CalleeSavedStackSize = 0;
68*bdd1243dSDimitry Andric   /// Is there any vector argument or return?
69*bdd1243dSDimitry Andric   bool IsVectorCall = false;
70*bdd1243dSDimitry Andric 
71*bdd1243dSDimitry Andric   /// Registers that have been sign extended from i32.
72*bdd1243dSDimitry Andric   SmallVector<Register, 8> SExt32Registers;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric public:
75*bdd1243dSDimitry Andric   RISCVMachineFunctionInfo(const Function &F, const TargetSubtargetInfo *STI) {}
760b57cec5SDimitry Andric 
7781ad6265SDimitry Andric   MachineFunctionInfo *
7881ad6265SDimitry Andric   clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
7981ad6265SDimitry Andric         const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
8081ad6265SDimitry Andric       const override;
8181ad6265SDimitry Andric 
820b57cec5SDimitry Andric   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
830b57cec5SDimitry Andric   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; }
860b57cec5SDimitry Andric   void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; }
870b57cec5SDimitry Andric 
885ffd83dbSDimitry Andric   int getMoveF64FrameIndex(MachineFunction &MF) {
890b57cec5SDimitry Andric     if (MoveF64FrameIndex == -1)
905ffd83dbSDimitry Andric       MoveF64FrameIndex =
915ffd83dbSDimitry Andric           MF.getFrameInfo().CreateStackObject(8, Align(8), false);
920b57cec5SDimitry Andric     return MoveF64FrameIndex;
930b57cec5SDimitry Andric   }
945ffd83dbSDimitry Andric 
95*bdd1243dSDimitry Andric   int getBranchRelaxationScratchFrameIndex() const {
96*bdd1243dSDimitry Andric     return BranchRelaxationScratchFrameIndex;
97*bdd1243dSDimitry Andric   }
98*bdd1243dSDimitry Andric   void setBranchRelaxationScratchFrameIndex(int Index) {
99*bdd1243dSDimitry Andric     BranchRelaxationScratchFrameIndex = Index;
100*bdd1243dSDimitry Andric   }
101*bdd1243dSDimitry Andric 
1025ffd83dbSDimitry Andric   unsigned getLibCallStackSize() const { return LibCallStackSize; }
1035ffd83dbSDimitry Andric   void setLibCallStackSize(unsigned Size) { LibCallStackSize = Size; }
1045ffd83dbSDimitry Andric 
1055ffd83dbSDimitry Andric   bool useSaveRestoreLibCalls(const MachineFunction &MF) const {
1065ffd83dbSDimitry Andric     // We cannot use fixed locations for the callee saved spill slots if the
107fe6060f1SDimitry Andric     // function uses a varargs save area, or is an interrupt handler.
1085ffd83dbSDimitry Andric     return MF.getSubtarget<RISCVSubtarget>().enableSaveRestore() &&
109fe6060f1SDimitry Andric            VarArgsSaveSize == 0 && !MF.getFrameInfo().hasTailCall() &&
110fe6060f1SDimitry Andric            !MF.getFunction().hasFnAttribute("interrupt");
1115ffd83dbSDimitry Andric   }
112fe6060f1SDimitry Andric 
113fe6060f1SDimitry Andric   uint64_t getRVVStackSize() const { return RVVStackSize; }
114fe6060f1SDimitry Andric   void setRVVStackSize(uint64_t Size) { RVVStackSize = Size; }
115fe6060f1SDimitry Andric 
11681ad6265SDimitry Andric   Align getRVVStackAlign() const { return RVVStackAlign; }
11781ad6265SDimitry Andric   void setRVVStackAlign(Align StackAlign) { RVVStackAlign = StackAlign; }
11881ad6265SDimitry Andric 
119fe6060f1SDimitry Andric   uint64_t getRVVPadding() const { return RVVPadding; }
120fe6060f1SDimitry Andric   void setRVVPadding(uint64_t Padding) { RVVPadding = Padding; }
121fe6060f1SDimitry Andric 
122fe6060f1SDimitry Andric   unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; }
123fe6060f1SDimitry Andric   void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; }
1243a9a9c0cSDimitry Andric 
1253a9a9c0cSDimitry Andric   void initializeBaseYamlFields(const yaml::RISCVMachineFunctionInfo &YamlMFI);
126*bdd1243dSDimitry Andric 
127*bdd1243dSDimitry Andric   void addSExt32Register(Register Reg);
128*bdd1243dSDimitry Andric   bool isSExt32Register(Register Reg) const;
129*bdd1243dSDimitry Andric 
130*bdd1243dSDimitry Andric   bool isVectorCall() const { return IsVectorCall; }
131*bdd1243dSDimitry Andric   void setIsVectorCall() { IsVectorCall = true; }
1320b57cec5SDimitry Andric };
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric } // end namespace llvm
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H
137