Skip to content

Add gpu-kernel calling convention #135047

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 22 additions & 13 deletions compiler/rustc_abi/src/extern_abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ pub enum ExternAbi {
PtxKernel,
Msp430Interrupt,
X86Interrupt,
/// An entry-point function called by the GPU's host
// FIXME: should not be callable from Rust on GPU targets, is for host's use only
GpuKernel,
EfiApi,
AvrInterrupt,
AvrNonBlockingInterrupt,
Expand Down Expand Up @@ -122,6 +125,7 @@ const AbiDatas: &[AbiData] = &[
AbiData { abi: Abi::PtxKernel, name: "ptx-kernel" },
AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt" },
AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt" },
AbiData { abi: Abi::GpuKernel, name: "gpu-kernel" },
AbiData { abi: Abi::EfiApi, name: "efiapi" },
AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt" },
AbiData { abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt" },
Expand Down Expand Up @@ -235,6 +239,10 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
feature: sym::abi_x86_interrupt,
explain: "x86-interrupt ABI is experimental and subject to change",
}),
"gpu-kernel" => Err(AbiDisabled::Unstable {
feature: sym::abi_gpu_kernel,
explain: "gpu-kernel ABI is experimental and subject to change",
}),
"avr-interrupt" | "avr-non-blocking-interrupt" => Err(AbiDisabled::Unstable {
feature: sym::abi_avr_interrupt,
explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
Expand Down Expand Up @@ -289,20 +297,21 @@ impl Abi {
PtxKernel => 19,
Msp430Interrupt => 20,
X86Interrupt => 21,
EfiApi => 22,
AvrInterrupt => 23,
AvrNonBlockingInterrupt => 24,
CCmseNonSecureCall => 25,
CCmseNonSecureEntry => 26,
GpuKernel => 22,
EfiApi => 23,
AvrInterrupt => 24,
AvrNonBlockingInterrupt => 25,
CCmseNonSecureCall => 26,
CCmseNonSecureEntry => 27,
// Cross-platform ABIs
System { unwind: false } => 27,
System { unwind: true } => 28,
RustIntrinsic => 29,
RustCall => 30,
Unadjusted => 31,
RustCold => 32,
RiscvInterruptM => 33,
RiscvInterruptS => 34,
System { unwind: false } => 28,
System { unwind: true } => 29,
RustIntrinsic => 30,
RustCall => 31,
Unadjusted => 32,
RustCold => 33,
RiscvInterruptM => 34,
RiscvInterruptS => 35,
};
debug_assert!(
AbiDatas
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call
sess.dcx().fatal("C-cmse-nonsecure-entry call conv is not yet implemented");
}

Conv::Msp430Intr | Conv::PtxKernel | Conv::AvrInterrupt | Conv::AvrNonBlockingInterrupt => {
Conv::Msp430Intr
| Conv::PtxKernel
| Conv::GpuKernel
| Conv::AvrInterrupt
| Conv::AvrNonBlockingInterrupt => {
unreachable!("tried to use {c:?} call conv which only exists on an unsupported target");
}
}
Expand Down
22 changes: 16 additions & 6 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Borrow;
use std::cmp;

use libc::c_uint;
Expand Down Expand Up @@ -312,7 +313,7 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> {
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
fn llvm_cconv(&self) -> llvm::CallConv;
fn llvm_cconv(&self, cx: &CodegenCx<'ll, 'tcx>) -> llvm::CallConv;

/// Apply attributes to a function declaration/definition.
fn apply_attrs_llfn(
Expand Down Expand Up @@ -404,8 +405,8 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
cx.type_ptr_ext(cx.data_layout().instruction_address_space)
}

fn llvm_cconv(&self) -> llvm::CallConv {
self.conv.into()
fn llvm_cconv(&self, cx: &CodegenCx<'ll, 'tcx>) -> llvm::CallConv {
llvm::CallConv::from_conv(self.conv, cx.tcx.sess.target.arch.borrow())
}

fn apply_attrs_llfn(
Expand Down Expand Up @@ -617,7 +618,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}
}

let cconv = self.llvm_cconv();
let cconv = self.llvm_cconv(&bx.cx);
if cconv != llvm::CCallConv {
llvm::SetInstructionCallConv(callsite, cconv);
}
Expand Down Expand Up @@ -655,8 +656,8 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
}
}

impl From<Conv> for llvm::CallConv {
fn from(conv: Conv) -> Self {
impl llvm::CallConv {
pub fn from_conv(conv: Conv, arch: &str) -> Self {
match conv {
Conv::C
| Conv::Rust
Expand All @@ -666,6 +667,15 @@ impl From<Conv> for llvm::CallConv {
Conv::Cold => llvm::ColdCallConv,
Conv::PreserveMost => llvm::PreserveMost,
Conv::PreserveAll => llvm::PreserveAll,
Conv::GpuKernel => {
if arch == "amdgpu" {
llvm::AmdgpuKernel
} else if arch == "nvptx64" {
llvm::PtxKernel
} else {
panic!("Architecture {arch} does not support GpuKernel calling convention");
}
}
Conv::AvrInterrupt => llvm::AvrInterrupt,
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
Conv::ArmAapcs => llvm::ArmAapcsCallConv,
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,10 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
if self.get_declared_value(entry_name).is_none() {
Some(self.declare_entry_fn(
entry_name,
self.sess().target.entry_abi.into(),
llvm::CallConv::from_conv(
self.sess().target.entry_abi,
self.sess().target.arch.borrow(),
),
llvm::UnnamedAddr::Global,
fn_type,
))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
let llfn = declare_raw_fn(
self,
name,
fn_abi.llvm_cconv(),
fn_abi.llvm_cconv(self),
llvm::UnnamedAddr::Global,
llvm::Visibility::Default,
fn_abi.llvm_type(self),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub enum CallConv {
X86_Intr = 83,
AvrNonBlockingInterrupt = 84,
AvrInterrupt = 85,
AmdgpuKernel = 91,
}

/// Must match the layout of `LLVMLinkage`.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ declare_features! (
(unstable, abi_avr_interrupt, "1.45.0", Some(69664)),
/// Allows `extern "C-cmse-nonsecure-call" fn()`.
(unstable, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391)),
/// Allows `extern "gpu-kernel" fn()`.
(unstable, abi_gpu_kernel, "CURRENT_RUSTC_VERSION", Some(135467)),
/// Allows `extern "msp430-interrupt" fn()`.
(unstable, abi_msp430_interrupt, "1.16.0", Some(38487)),
/// Allows `extern "ptx-*" fn()`.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
PtxKernel
| Msp430Interrupt
| X86Interrupt
| GpuKernel
| EfiApi
| AvrInterrupt
| AvrNonBlockingInterrupt
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_smir/src/rustc_internal/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ impl RustcInternal for Abi {
Abi::PtxKernel => rustc_abi::ExternAbi::PtxKernel,
Abi::Msp430Interrupt => rustc_abi::ExternAbi::Msp430Interrupt,
Abi::X86Interrupt => rustc_abi::ExternAbi::X86Interrupt,
Abi::GpuKernel => rustc_abi::ExternAbi::GpuKernel,
Abi::EfiApi => rustc_abi::ExternAbi::EfiApi,
Abi::AvrInterrupt => rustc_abi::ExternAbi::AvrInterrupt,
Abi::AvrNonBlockingInterrupt => rustc_abi::ExternAbi::AvrNonBlockingInterrupt,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_smir/src/rustc_smir/convert/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl<'tcx> Stable<'tcx> for callconv::Conv {
Conv::X86VectorCall => CallConvention::X86VectorCall,
Conv::X86_64SysV => CallConvention::X86_64SysV,
Conv::X86_64Win64 => CallConvention::X86_64Win64,
Conv::GpuKernel => CallConvention::GpuKernel,
Conv::AvrInterrupt => CallConvention::AvrInterrupt,
Conv::AvrNonBlockingInterrupt => CallConvention::AvrNonBlockingInterrupt,
Conv::RiscvInterrupt { .. } => CallConvention::RiscvInterrupt,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_smir/src/rustc_smir/convert/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
ExternAbi::Win64 { unwind } => Abi::Win64 { unwind },
ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
ExternAbi::PtxKernel => Abi::PtxKernel,
ExternAbi::GpuKernel => Abi::GpuKernel,
ExternAbi::Msp430Interrupt => Abi::Msp430Interrupt,
ExternAbi::X86Interrupt => Abi::X86Interrupt,
ExternAbi::EfiApi => Abi::EfiApi,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ symbols! {
abi_avr_interrupt,
abi_c_cmse_nonsecure_call,
abi_efiapi,
abi_gpu_kernel,
abi_msp430_interrupt,
abi_ptx,
abi_riscv_interrupt,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,8 @@ pub enum Conv {

PtxKernel,

GpuKernel,

X86Fastcall,
X86Intr,
X86Stdcall,
Expand Down Expand Up @@ -866,6 +868,7 @@ impl FromStr for Conv {
"X86VectorCall" => Ok(Conv::X86VectorCall),
"X86_64SysV" => Ok(Conv::X86_64SysV),
"X86_64Win64" => Ok(Conv::X86_64Win64),
"GpuKernel" => Ok(Conv::GpuKernel),
"AvrInterrupt" => Ok(Conv::AvrInterrupt),
"AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
"RiscvInterrupt(machine)" => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl ToJson for crate::abi::call::Conv {
Self::X86VectorCall => "X86VectorCall",
Self::X86_64SysV => "X86_64SysV",
Self::X86_64Win64 => "X86_64Win64",
Self::GpuKernel => "GpuKernel",
Self::AvrInterrupt => "AvrInterrupt",
Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
Self::RiscvInterrupt { kind } => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2854,6 +2854,7 @@ impl Target {
}
Win64 { .. } | SysV64 { .. } => self.arch == "x86_64",
PtxKernel => self.arch == "nvptx64",
GpuKernel => ["amdgpu", "nvptx64"].contains(&&self.arch[..]),
Msp430Interrupt => self.arch == "msp430",
RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]),
AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ty_utils/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv
PtxKernel => Conv::PtxKernel,
Msp430Interrupt => Conv::Msp430Intr,
X86Interrupt => Conv::X86Intr,
GpuKernel => Conv::GpuKernel,
AvrInterrupt => Conv::AvrInterrupt,
AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine },
Expand Down
2 changes: 2 additions & 0 deletions compiler/stable_mir/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,8 @@ pub enum CallConvention {

PtxKernel,

GpuKernel,

X86Fastcall,
X86Intr,
X86Stdcall,
Expand Down
1 change: 1 addition & 0 deletions compiler/stable_mir/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@ pub enum Abi {
PtxKernel,
Msp430Interrupt,
X86Interrupt,
GpuKernel,
EfiApi,
AvrInterrupt,
AvrNonBlockingInterrupt,
Expand Down
18 changes: 18 additions & 0 deletions tests/codegen/gpu-kernel-abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Checks that the gpu-kernel calling convention correctly translates to LLVM calling conventions.

//@ revisions: nvptx
//@ [nvptx] compile-flags: --crate-type=rlib --target=nvptx64-nvidia-cuda
//@ [nvptx] needs-llvm-components: nvptx
#![feature(no_core, lang_items, abi_gpu_kernel)]
#![no_core]

#[lang = "sized"]
trait Sized {}
#[lang = "freeze"]
trait Freeze {}
#[lang = "copy"]
trait Copy {}

// nvptx: define ptx_kernel void @fun(i32
#[no_mangle]
pub extern "gpu-kernel" fn fun(_: i32) {}
Loading
Loading