Skip to content

Commit aeedc07

Browse files
ZeaveeRKSimon
authored andcommitted
[IR] Add GraalVM calling conventions
Adds GraalVM calling conventions. The only difference with the default calling conventions is that GraalVM reserves two registers for the heap base and the thread. Since the registers are then accessed by name, getRegisterByName has to be updated accordingly. This patch implements the calling conventions only for X86, AArch64 and RISC-V. For X86, the reserved registers are X14 and X15. For AArch64, they are X27 and X28. For RISC-V, they are X23 and X27. This patch has been used by the LLVM backend of GraalVM's Native Image project in production for around 4 months with no major issues. Differential Revision: https://reviews.llvm.org/D151107
1 parent 19e7458 commit aeedc07

File tree

14 files changed

+81
-8
lines changed

14 files changed

+81
-8
lines changed

llvm/include/llvm/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ enum Kind {
176176
kw_amdgpu_gfx,
177177
kw_tailcc,
178178
kw_m68k_rtdcc,
179+
kw_graalcc,
179180

180181
// Attributes:
181182
kw_attributes,

llvm/include/llvm/IR/CallingConv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ namespace CallingConv {
248248
/// Used for M68k rtd-based CC (similar to X86's stdcall).
249249
M68k_RTD = 106,
250250

251+
/// Used by GraalVM. Two additional registers are reserved.
252+
GRAAL = 107,
253+
251254
/// The highest possible ID. Must be some 2^k - 1.
252255
MaxID = 1023
253256
};

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ lltok::Kind LLLexer::LexIdentifier() {
633633
KEYWORD(amdgpu_gfx);
634634
KEYWORD(tailcc);
635635
KEYWORD(m68k_rtdcc);
636+
KEYWORD(graalcc);
636637

637638
KEYWORD(cc);
638639
KEYWORD(c);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,6 +1999,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
19991999
/// ::= 'amdgpu_kernel'
20002000
/// ::= 'tailcc'
20012001
/// ::= 'm68k_rtdcc'
2002+
/// ::= 'graalcc'
20022003
/// ::= 'cc' UINT
20032004
///
20042005
bool LLParser::parseOptionalCallingConv(unsigned &CC) {
@@ -2067,6 +2068,7 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
20672068
case lltok::kw_amdgpu_kernel: CC = CallingConv::AMDGPU_KERNEL; break;
20682069
case lltok::kw_tailcc: CC = CallingConv::Tail; break;
20692070
case lltok::kw_m68k_rtdcc: CC = CallingConv::M68k_RTD; break;
2071+
case lltok::kw_graalcc: CC = CallingConv::GRAAL; break;
20702072
case lltok::kw_cc: {
20712073
Lex.Lex();
20722074
return parseUInt32(CC);

llvm/lib/IR/AsmWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
307307
case CallingConv::CXX_FAST_TLS: Out << "cxx_fast_tlscc"; break;
308308
case CallingConv::GHC: Out << "ghccc"; break;
309309
case CallingConv::Tail: Out << "tailcc"; break;
310+
case CallingConv::GRAAL: Out << "graalcc"; break;
310311
case CallingConv::CFGuard_Check: Out << "cfguard_checkcc"; break;
311312
case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break;
312313
case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break;

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6382,6 +6382,7 @@ CCAssignFn *AArch64TargetLowering::CCAssignFnForCall(CallingConv::ID CC,
63826382
case CallingConv::Swift:
63836383
case CallingConv::SwiftTail:
63846384
case CallingConv::Tail:
6385+
case CallingConv::GRAAL:
63856386
if (Subtarget->isTargetWindows()) {
63866387
if (IsVarArg) {
63876388
if (Subtarget->isWindowsArm64EC())
@@ -9889,9 +9890,10 @@ Register AArch64TargetLowering::
98899890
getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const {
98909891
Register Reg = MatchRegisterName(RegName);
98919892
if (AArch64::X1 <= Reg && Reg <= AArch64::X28) {
9892-
const MCRegisterInfo *MRI = Subtarget->getRegisterInfo();
9893+
const AArch64RegisterInfo *MRI = Subtarget->getRegisterInfo();
98939894
unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false);
9894-
if (!Subtarget->isXRegisterReserved(DwarfRegNum))
9895+
if (!Subtarget->isXRegisterReserved(DwarfRegNum) &&
9896+
!MRI->isReservedReg(MF, Reg))
98959897
Reg = 0;
98969898
}
98979899
if (Reg)

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,13 @@ AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
442442

443443
markSuperRegs(Reserved, AArch64::FPCR);
444444

445+
if (MF.getFunction().getCallingConv() == CallingConv::GRAAL) {
446+
markSuperRegs(Reserved, AArch64::X27);
447+
markSuperRegs(Reserved, AArch64::X28);
448+
markSuperRegs(Reserved, AArch64::W27);
449+
markSuperRegs(Reserved, AArch64::W28);
450+
}
451+
445452
assert(checkAllSuperRegsMarked(Reserved));
446453
return Reserved;
447454
}

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17331,6 +17331,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
1733117331
case CallingConv::C:
1733217332
case CallingConv::Fast:
1733317333
case CallingConv::SPIR_KERNEL:
17334+
case CallingConv::GRAAL:
1733417335
break;
1733517336
case CallingConv::GHC:
1733617337
if (!Subtarget.hasStdExtFOrZfinx() || !Subtarget.hasStdExtDOrZdinx())

llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,11 @@ RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
8585
BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
8686
const RISCVFrameLowering *TFI = getFrameLowering(MF);
8787
BitVector Reserved(getNumRegs());
88+
auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
8889

8990
// Mark any registers requested to be reserved as such
9091
for (size_t Reg = 0; Reg < getNumRegs(); Reg++) {
91-
if (MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(Reg))
92+
if (Subtarget.isRegisterReservedByUser(Reg))
9293
markSuperRegs(Reserved, Reg);
9394
}
9495

@@ -119,6 +120,13 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
119120
markSuperRegs(Reserved, RISCV::FRM);
120121
markSuperRegs(Reserved, RISCV::FFLAGS);
121122

123+
if (MF.getFunction().getCallingConv() == CallingConv::GRAAL) {
124+
if (Subtarget.isRVE())
125+
report_fatal_error("Graal reserved registers do not exist in RVE");
126+
markSuperRegs(Reserved, RISCV::X23);
127+
markSuperRegs(Reserved, RISCV::X27);
128+
}
129+
122130
assert(checkAllSuperRegsMarked(Reserved));
123131
return Reserved;
124132
}

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27017,11 +27017,13 @@ Register X86TargetLowering::getRegisterByName(const char* RegName, LLT VT,
2701727017
const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
2701827018

2701927019
Register Reg = StringSwitch<unsigned>(RegName)
27020-
.Case("esp", X86::ESP)
27021-
.Case("rsp", X86::RSP)
27022-
.Case("ebp", X86::EBP)
27023-
.Case("rbp", X86::RBP)
27024-
.Default(0);
27020+
.Case("esp", X86::ESP)
27021+
.Case("rsp", X86::RSP)
27022+
.Case("ebp", X86::EBP)
27023+
.Case("rbp", X86::RBP)
27024+
.Case("r14", X86::R14)
27025+
.Case("r15", X86::R15)
27026+
.Default(0);
2702527027

2702627028
if (Reg == X86::EBP || Reg == X86::RBP) {
2702727029
if (!TFI.hasFP(MF))

llvm/lib/Target/X86/X86RegisterInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,13 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
619619
if (!Is64Bit || !MF.getSubtarget<X86Subtarget>().hasEGPR())
620620
Reserved.set(X86::R16, X86::R31WH + 1);
621621

622+
if (MF.getFunction().getCallingConv() == CallingConv::GRAAL) {
623+
for (MCRegAliasIterator AI(X86::R14, this, true); AI.isValid(); ++AI)
624+
Reserved.set(*AI);
625+
for (MCRegAliasIterator AI(X86::R15, this, true); AI.isValid(); ++AI)
626+
Reserved.set(*AI);
627+
}
628+
622629
assert(checkAllSuperRegsMarked(Reserved,
623630
{X86::SIL, X86::DIL, X86::BPL, X86::SPL,
624631
X86::SIH, X86::DIH, X86::BPH, X86::SPH}));

llvm/test/CodeGen/AArch64/graalcc.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; RUN: llc -mtriple=arm64 -o - %s | FileCheck %s
2+
3+
@var = global [30 x i64] zeroinitializer
4+
5+
define graalcc void @keep_live() {
6+
%val = load volatile [30 x i64], ptr @var
7+
store volatile [30 x i64] %val, ptr @var
8+
; CHECK-NOT: ldr x27
9+
; CHECK-NOT: ldr x28
10+
ret void
11+
}

llvm/test/CodeGen/RISCV/graalcc.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: llc -mtriple=riscv32 -o - %s | FileCheck %s
2+
; RUN: llc -mtriple=riscv64 -o - %s | FileCheck %s
3+
4+
@var = global [30 x i64] zeroinitializer
5+
6+
define graalcc void @keep_live() {
7+
%val = load volatile [30 x i64], ptr @var
8+
store volatile [30 x i64] %val, ptr @var
9+
; CHECK-NOT: lw s7,
10+
; CHECK-NOT: ld s7,
11+
; CHECK-NOT: lw s11,
12+
; CHECK-NOT: ld s11,
13+
ret void
14+
}

llvm/test/CodeGen/X86/graalcc.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llc -mtriple=x86_64 -o - %s | FileCheck %s
2+
3+
@var = global [30 x i64] zeroinitializer
4+
5+
define graalcc void @keep_live() {
6+
%val = load volatile [30 x i64], ptr @var
7+
store volatile [30 x i64] %val, ptr @var
8+
; CHECK-NOT: movq {{[0-9]+}}(%{{[a-z]+}}), %r14
9+
; CHECK-NOT: movq {{[0-9]+}}(%{{[a-z]+}}), %r15
10+
; CHECK-NOT: movq %r14,
11+
; CHECK-NOT: movq %r15,
12+
ret void
13+
}

0 commit comments

Comments
 (0)