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