106c3fb27SDimitry Andric //=- RISCVMachineFunctionInfo.h - RISC-V 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; 56bdd1243dSDimitry Andric /// FrameIndex of the spill slot for the scratch register in BranchRelaxation. 57bdd1243dSDimitry 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; 68bdd1243dSDimitry Andric /// Is there any vector argument or return? 69bdd1243dSDimitry Andric bool IsVectorCall = false; 70bdd1243dSDimitry Andric 71bdd1243dSDimitry Andric /// Registers that have been sign extended from i32. 72bdd1243dSDimitry Andric SmallVector<Register, 8> SExt32Registers; 730b57cec5SDimitry Andric 7406c3fb27SDimitry Andric /// Size of stack frame for Zcmp PUSH/POP 7506c3fb27SDimitry Andric unsigned RVPushStackSize = 0; 7606c3fb27SDimitry Andric unsigned RVPushRegs = 0; 7706c3fb27SDimitry Andric int RVPushRlist = llvm::RISCVZC::RLISTENCODE::INVALID_RLIST; 7806c3fb27SDimitry Andric 790b57cec5SDimitry Andric public: 80bdd1243dSDimitry Andric RISCVMachineFunctionInfo(const Function &F, const TargetSubtargetInfo *STI) {} 810b57cec5SDimitry Andric 8281ad6265SDimitry Andric MachineFunctionInfo * 8381ad6265SDimitry Andric clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 8481ad6265SDimitry Andric const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) 8581ad6265SDimitry Andric const override; 8681ad6265SDimitry Andric 870b57cec5SDimitry Andric int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } 880b57cec5SDimitry Andric void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; } 910b57cec5SDimitry Andric void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; } 920b57cec5SDimitry Andric 935ffd83dbSDimitry Andric int getMoveF64FrameIndex(MachineFunction &MF) { 940b57cec5SDimitry Andric if (MoveF64FrameIndex == -1) 955ffd83dbSDimitry Andric MoveF64FrameIndex = 965ffd83dbSDimitry Andric MF.getFrameInfo().CreateStackObject(8, Align(8), false); 970b57cec5SDimitry Andric return MoveF64FrameIndex; 980b57cec5SDimitry Andric } 995ffd83dbSDimitry Andric 100bdd1243dSDimitry Andric int getBranchRelaxationScratchFrameIndex() const { 101bdd1243dSDimitry Andric return BranchRelaxationScratchFrameIndex; 102bdd1243dSDimitry Andric } 103bdd1243dSDimitry Andric void setBranchRelaxationScratchFrameIndex(int Index) { 104bdd1243dSDimitry Andric BranchRelaxationScratchFrameIndex = Index; 105bdd1243dSDimitry Andric } 106bdd1243dSDimitry Andric 107*5f757f3fSDimitry Andric unsigned getReservedSpillsSize() const { 108*5f757f3fSDimitry Andric return LibCallStackSize + RVPushStackSize; 109*5f757f3fSDimitry Andric } 110*5f757f3fSDimitry Andric 1115ffd83dbSDimitry Andric unsigned getLibCallStackSize() const { return LibCallStackSize; } 1125ffd83dbSDimitry Andric void setLibCallStackSize(unsigned Size) { LibCallStackSize = Size; } 1135ffd83dbSDimitry Andric 1145ffd83dbSDimitry Andric bool useSaveRestoreLibCalls(const MachineFunction &MF) const { 1155ffd83dbSDimitry Andric // We cannot use fixed locations for the callee saved spill slots if the 116fe6060f1SDimitry Andric // function uses a varargs save area, or is an interrupt handler. 117*5f757f3fSDimitry Andric return !isPushable(MF) && 118*5f757f3fSDimitry Andric MF.getSubtarget<RISCVSubtarget>().enableSaveRestore() && 119fe6060f1SDimitry Andric VarArgsSaveSize == 0 && !MF.getFrameInfo().hasTailCall() && 120fe6060f1SDimitry Andric !MF.getFunction().hasFnAttribute("interrupt"); 1215ffd83dbSDimitry Andric } 122fe6060f1SDimitry Andric 123fe6060f1SDimitry Andric uint64_t getRVVStackSize() const { return RVVStackSize; } 124fe6060f1SDimitry Andric void setRVVStackSize(uint64_t Size) { RVVStackSize = Size; } 125fe6060f1SDimitry Andric 12681ad6265SDimitry Andric Align getRVVStackAlign() const { return RVVStackAlign; } 12781ad6265SDimitry Andric void setRVVStackAlign(Align StackAlign) { RVVStackAlign = StackAlign; } 12881ad6265SDimitry Andric 129fe6060f1SDimitry Andric uint64_t getRVVPadding() const { return RVVPadding; } 130fe6060f1SDimitry Andric void setRVVPadding(uint64_t Padding) { RVVPadding = Padding; } 131fe6060f1SDimitry Andric 132fe6060f1SDimitry Andric unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; } 133fe6060f1SDimitry Andric void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; } 1343a9a9c0cSDimitry Andric 135*5f757f3fSDimitry Andric bool isPushable(const MachineFunction &MF) const { 136*5f757f3fSDimitry Andric // We cannot use fixed locations for the callee saved spill slots if the 137*5f757f3fSDimitry Andric // function uses a varargs save area. 138*5f757f3fSDimitry Andric // TODO: Use a seperate placement for vararg registers to enable Zcmp. 139*5f757f3fSDimitry Andric return MF.getSubtarget<RISCVSubtarget>().hasStdExtZcmp() && 140*5f757f3fSDimitry Andric !MF.getTarget().Options.DisableFramePointerElim(MF) && 141*5f757f3fSDimitry Andric VarArgsSaveSize == 0; 14206c3fb27SDimitry Andric } 14306c3fb27SDimitry Andric 14406c3fb27SDimitry Andric int getRVPushRlist() const { return RVPushRlist; } 14506c3fb27SDimitry Andric void setRVPushRlist(int Rlist) { RVPushRlist = Rlist; } 14606c3fb27SDimitry Andric 14706c3fb27SDimitry Andric unsigned getRVPushRegs() const { return RVPushRegs; } 14806c3fb27SDimitry Andric void setRVPushRegs(unsigned Regs) { RVPushRegs = Regs; } 14906c3fb27SDimitry Andric 15006c3fb27SDimitry Andric unsigned getRVPushStackSize() const { return RVPushStackSize; } 15106c3fb27SDimitry Andric void setRVPushStackSize(unsigned Size) { RVPushStackSize = Size; } 15206c3fb27SDimitry Andric 1533a9a9c0cSDimitry Andric void initializeBaseYamlFields(const yaml::RISCVMachineFunctionInfo &YamlMFI); 154bdd1243dSDimitry Andric 155bdd1243dSDimitry Andric void addSExt32Register(Register Reg); 156bdd1243dSDimitry Andric bool isSExt32Register(Register Reg) const; 157bdd1243dSDimitry Andric 158bdd1243dSDimitry Andric bool isVectorCall() const { return IsVectorCall; } 159bdd1243dSDimitry Andric void setIsVectorCall() { IsVectorCall = true; } 1600b57cec5SDimitry Andric }; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric } // end namespace llvm 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H 165