aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp4
-rw-r--r--llvm/lib/IR/AsmWriter.cpp3
-rw-r--r--llvm/lib/Target/RISCV/RISCVCallingConv.td13
-rw-r--r--llvm/lib/Target/RISCV/RISCVFrameLowering.cpp97
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp1
-rw-r--r--llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp15
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;
}
}