diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVCallingConv.td | 13 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 97 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 15 |
7 files changed, 106 insertions, 28 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 02f64fc..2301a27 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -640,6 +640,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(tailcc); KEYWORD(m68k_rtdcc); KEYWORD(graalcc); + KEYWORD(riscv_vector_cc); KEYWORD(cc); KEYWORD(c); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f0be021..41d48e5 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -2143,6 +2143,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) { /// ::= 'tailcc' /// ::= 'm68k_rtdcc' /// ::= 'graalcc' +/// ::= 'riscv_vector_cc' /// ::= 'cc' UINT /// bool LLParser::parseOptionalCallingConv(unsigned &CC) { @@ -2213,6 +2214,9 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) { case lltok::kw_tailcc: CC = CallingConv::Tail; break; case lltok::kw_m68k_rtdcc: CC = CallingConv::M68k_RTD; break; case lltok::kw_graalcc: CC = CallingConv::GRAAL; break; + case lltok::kw_riscv_vector_cc: + CC = CallingConv::RISCV_VectorCall; + break; case lltok::kw_cc: { Lex.Lex(); return parseUInt32(CC); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 38c191a..84690f0 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -363,6 +363,9 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break; case CallingConv::AMDGPU_Gfx: Out << "amdgpu_gfx"; break; case CallingConv::M68k_RTD: Out << "m68k_rtdcc"; break; + case CallingConv::RISCV_VectorCall: + Out << "riscv_vector_cc"; + break; } } diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.td b/llvm/lib/Target/RISCV/RISCVCallingConv.td index 11b716f..ad06f47 100644 --- a/llvm/lib/Target/RISCV/RISCVCallingConv.td +++ b/llvm/lib/Target/RISCV/RISCVCallingConv.td @@ -26,6 +26,19 @@ def CSR_ILP32D_LP64D : CalleeSavedRegs<(add CSR_ILP32_LP64, F8_D, F9_D, (sequence "F%u_D", 18, 27))>; +defvar CSR_V = (add (sequence "V%u", 1, 7), (sequence "V%u", 24, 31), + V2M2, V4M2, V6M2, V24M2, V26M2, V28M2, V30M2, + V4M4, V24M4, V28M4, V24M8); + +def CSR_ILP32_LP64_V + : CalleeSavedRegs<(add CSR_ILP32_LP64, CSR_V)>; + +def CSR_ILP32F_LP64F_V + : CalleeSavedRegs<(add CSR_ILP32F_LP64F, CSR_V)>; + +def CSR_ILP32D_LP64D_V + : CalleeSavedRegs<(add CSR_ILP32D_LP64D, CSR_V)>; + // Needed for implementation of RISCVRegisterInfo::getNoPreservedMask() def CSR_NoRegs : CalleeSavedRegs<(add)>; diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 39f2b3f..39075c81 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -388,6 +388,21 @@ getUnmanagedCSI(const MachineFunction &MF, return NonLibcallCSI; } +static SmallVector<CalleeSavedInfo, 8> +getRVVCalleeSavedInfo(const MachineFunction &MF, + const std::vector<CalleeSavedInfo> &CSI) { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + SmallVector<CalleeSavedInfo, 8> RVVCSI; + + for (auto &CS : CSI) { + int FI = CS.getFrameIdx(); + if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) + RVVCSI.push_back(CS); + } + + return RVVCSI; +} + void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, @@ -590,6 +605,10 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // directives. for (const auto &Entry : CSI) { int FrameIdx = Entry.getFrameIdx(); + if (FrameIdx >= 0 && + MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector) + continue; + int64_t Offset = MFI.getObjectOffset(FrameIdx); Register Reg = Entry.getReg(); unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( @@ -726,7 +745,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo()); - // Skip to before the restores of callee-saved registers + // Skip to before the restores of scalar callee-saved registers // FIXME: assumes exactly one instruction is used to restore each // callee-saved register. auto LastFrameDestroy = MBBI; @@ -1029,15 +1048,24 @@ RISCVFrameLowering::assignRVVStackObjectOffsets(MachineFunction &MF) const { MachineFrameInfo &MFI = MF.getFrameInfo(); // Create a buffer of RVV objects to allocate. SmallVector<int, 8> ObjectsToAllocate; - for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) { - unsigned StackID = MFI.getStackID(I); - if (StackID != TargetStackID::ScalableVector) - continue; - if (MFI.isDeadObjectIndex(I)) - continue; + auto pushRVVObjects = [&](int FIBegin, int FIEnd) { + for (int I = FIBegin, E = FIEnd; I != E; ++I) { + unsigned StackID = MFI.getStackID(I); + if (StackID != TargetStackID::ScalableVector) + continue; + if (MFI.isDeadObjectIndex(I)) + continue; - ObjectsToAllocate.push_back(I); - } + ObjectsToAllocate.push_back(I); + } + }; + // First push RVV Callee Saved object, then push RVV stack object + std::vector<CalleeSavedInfo> &CSI = MF.getFrameInfo().getCalleeSavedInfo(); + const auto &RVVCSI = getRVVCalleeSavedInfo(MF, CSI); + if (!RVVCSI.empty()) + pushRVVObjects(RVVCSI[0].getFrameIdx(), + RVVCSI[RVVCSI.size() - 1].getFrameIdx() + 1); + pushRVVObjects(0, MFI.getObjectIndexEnd() - RVVCSI.size()); // The minimum alignment is 16 bytes. Align RVVStackAlign(16); @@ -1487,13 +1515,19 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters( // Manually spill values not spilled by libcall & Push/Pop. const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI); - for (auto &CS : UnmanagedCSI) { - // Insert the spill to the stack frame. - Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg), CS.getFrameIdx(), - RC, TRI, Register()); - } + const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI); + + auto storeRegToStackSlot = [&](decltype(UnmanagedCSI) CSInfo) { + for (auto &CS : CSInfo) { + // Insert the spill to the stack frame. + Register Reg = CS.getReg(); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg), + CS.getFrameIdx(), RC, TRI, Register()); + } + }; + storeRegToStackSlot(UnmanagedCSI); + storeRegToStackSlot(RVVCSI); return true; } @@ -1511,19 +1545,26 @@ bool RISCVFrameLowering::restoreCalleeSavedRegisters( DL = MI->getDebugLoc(); // Manually restore values not restored by libcall & Push/Pop. - // Keep the same order as in the prologue. There is no need to reverse the - // order in the epilogue. In addition, the return address will be restored - // first in the epilogue. It increases the opportunity to avoid the - // load-to-use data hazard between loading RA and return by RA. - // loadRegFromStackSlot can insert multiple instructions. + // Reverse the restore order in epilog. In addition, the return + // address will be restored first in the epilogue. It increases + // the opportunity to avoid the load-to-use data hazard between + // loading RA and return by RA. loadRegFromStackSlot can insert + // multiple instructions. const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI); - for (auto &CS : UnmanagedCSI) { - Register Reg = CS.getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI, - Register()); - assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!"); - } + const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, CSI); + + auto loadRegFromStackSlot = [&](decltype(UnmanagedCSI) CSInfo) { + for (auto &CS : CSInfo) { + Register Reg = CS.getReg(); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI, + Register()); + assert(MI != MBB.begin() && + "loadRegFromStackSlot didn't insert any code!"); + } + }; + loadRegFromStackSlot(RVVCSI); + loadRegFromStackSlot(UnmanagedCSI); RISCVMachineFunctionInfo *RVFI = MF->getInfo<RISCVMachineFunctionInfo>(); if (RVFI->isPushable(*MF)) { diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index ca78648c..564fda6 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -18724,6 +18724,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments( case CallingConv::Fast: case CallingConv::SPIR_KERNEL: case CallingConv::GRAAL: + case CallingConv::RISCV_VectorCall: break; case CallingConv::GHC: if (Subtarget.isRVE()) diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 74d6532..11c3f2d 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -71,6 +71,9 @@ RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { : CSR_Interrupt_SaveList; } + bool HasVectorCSR = + MF->getFunction().getCallingConv() == CallingConv::RISCV_VectorCall; + switch (Subtarget.getTargetABI()) { default: llvm_unreachable("Unrecognized ABI"); @@ -79,12 +82,18 @@ RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { return CSR_ILP32E_LP64E_SaveList; case RISCVABI::ABI_ILP32: case RISCVABI::ABI_LP64: + if (HasVectorCSR) + return CSR_ILP32_LP64_V_SaveList; return CSR_ILP32_LP64_SaveList; case RISCVABI::ABI_ILP32F: case RISCVABI::ABI_LP64F: + if (HasVectorCSR) + return CSR_ILP32F_LP64F_V_SaveList; return CSR_ILP32F_LP64F_SaveList; case RISCVABI::ABI_ILP32D: case RISCVABI::ABI_LP64D: + if (HasVectorCSR) + return CSR_ILP32D_LP64D_V_SaveList; return CSR_ILP32D_LP64D_SaveList; } } @@ -665,12 +674,18 @@ RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF, return CSR_ILP32E_LP64E_RegMask; case RISCVABI::ABI_ILP32: case RISCVABI::ABI_LP64: + if (CC == CallingConv::RISCV_VectorCall) + return CSR_ILP32_LP64_V_RegMask; return CSR_ILP32_LP64_RegMask; case RISCVABI::ABI_ILP32F: case RISCVABI::ABI_LP64F: + if (CC == CallingConv::RISCV_VectorCall) + return CSR_ILP32F_LP64F_V_RegMask; return CSR_ILP32F_LP64F_RegMask; case RISCVABI::ABI_ILP32D: case RISCVABI::ABI_LP64D: + if (CC == CallingConv::RISCV_VectorCall) + return CSR_ILP32D_LP64D_V_RegMask; return CSR_ILP32D_LP64D_RegMask; } } |