Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e89775b

Browse files
committedJan 23, 2025··
Export kernel descriptor for amdgpu kernels
The host runtime (HIP or HSA) expects a kernel descriptor object for each kernel in the ELF file. The amdgpu LLVM backend generates the object. It is created as a symbol with the name of the kernel plus a `.kd` suffix. Add it to the exported symbols in the linker script, so that it can be found.
1 parent cd805f0 commit e89775b

File tree

2 files changed

+60
-32
lines changed

2 files changed

+60
-32
lines changed
 

‎compiler/rustc_codegen_ssa/src/back/linker.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,7 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
17761776
symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate(
17771777
tcx, symbol, cnum,
17781778
));
1779+
symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, cnum);
17791780
}
17801781
});
17811782

‎compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+59-32
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use rustc_middle::middle::exported_symbols::{
1010
ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, metadata_symbol_name,
1111
};
1212
use rustc_middle::query::LocalCrate;
13-
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, TyCtxt};
13+
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt};
1414
use rustc_middle::util::Providers;
1515
use rustc_session::config::{CrateType, OomStrategy};
16+
use rustc_target::callconv::Conv;
1617
use rustc_target::spec::{SanitizerSet, TlsModel};
1718
use tracing::debug;
1819

@@ -551,6 +552,41 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
551552
}
552553
}
553554

555+
fn calling_convention_for_symbol<'tcx>(
556+
tcx: TyCtxt<'tcx>,
557+
symbol: ExportedSymbol<'tcx>,
558+
) -> (Conv, &'tcx [rustc_target::callconv::ArgAbi<'tcx, Ty<'tcx>>]) {
559+
let instance = match symbol {
560+
ExportedSymbol::NonGeneric(def_id) | ExportedSymbol::Generic(def_id, _)
561+
if tcx.is_static(def_id) =>
562+
{
563+
None
564+
}
565+
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
566+
ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
567+
// DropGlue always use the Rust calling convention and thus follow the target's default
568+
// symbol decoration scheme.
569+
ExportedSymbol::DropGlue(..) => None,
570+
// AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
571+
// target's default symbol decoration scheme.
572+
ExportedSymbol::AsyncDropGlueCtorShim(..) => None,
573+
// NoDefId always follow the target's default symbol decoration scheme.
574+
ExportedSymbol::NoDefId(..) => None,
575+
// ThreadLocalShim always follow the target's default symbol decoration scheme.
576+
ExportedSymbol::ThreadLocalShim(..) => None,
577+
};
578+
579+
instance
580+
.map(|i| {
581+
tcx.fn_abi_of_instance(
582+
ty::TypingEnv::fully_monomorphized().as_query_input((i, ty::List::empty())),
583+
)
584+
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed"))
585+
})
586+
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
587+
.unwrap_or((Conv::Rust, &[]))
588+
}
589+
554590
/// This is the symbol name of the given instance as seen by the linker.
555591
///
556592
/// On 32-bit Windows symbols are decorated according to their calling conventions.
@@ -559,8 +595,6 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
559595
symbol: ExportedSymbol<'tcx>,
560596
instantiating_crate: CrateNum,
561597
) -> String {
562-
use rustc_target::callconv::Conv;
563-
564598
let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
565599

566600
// thread local will not be a function call,
@@ -584,35 +618,7 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
584618
_ => return undecorated,
585619
};
586620

587-
let instance = match symbol {
588-
ExportedSymbol::NonGeneric(def_id) | ExportedSymbol::Generic(def_id, _)
589-
if tcx.is_static(def_id) =>
590-
{
591-
None
592-
}
593-
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
594-
ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
595-
// DropGlue always use the Rust calling convention and thus follow the target's default
596-
// symbol decoration scheme.
597-
ExportedSymbol::DropGlue(..) => None,
598-
// AsyncDropGlueCtorShim always use the Rust calling convention and thus follow the
599-
// target's default symbol decoration scheme.
600-
ExportedSymbol::AsyncDropGlueCtorShim(..) => None,
601-
// NoDefId always follow the target's default symbol decoration scheme.
602-
ExportedSymbol::NoDefId(..) => None,
603-
// ThreadLocalShim always follow the target's default symbol decoration scheme.
604-
ExportedSymbol::ThreadLocalShim(..) => None,
605-
};
606-
607-
let (conv, args) = instance
608-
.map(|i| {
609-
tcx.fn_abi_of_instance(
610-
ty::TypingEnv::fully_monomorphized().as_query_input((i, ty::List::empty())),
611-
)
612-
.unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed"))
613-
})
614-
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
615-
.unwrap_or((Conv::Rust, &[]));
621+
let (conv, args) = calling_convention_for_symbol(tcx, symbol);
616622

617623
// Decorate symbols with prefixes, suffixes and total number of bytes of arguments.
618624
// Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
@@ -644,6 +650,27 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
644650
maybe_emutls_symbol_name(tcx, symbol, &undecorated).unwrap_or(undecorated)
645651
}
646652

653+
/// On amdhsa, `gpu-kernel` functions have an associated metadata object with a `.kd` suffix.
654+
/// Add it to the symbols list for all kernel functions, so that it is exported in the linked
655+
/// object.
656+
pub(crate) fn extend_exported_symbols<'tcx>(
657+
symbols: &mut Vec<String>,
658+
tcx: TyCtxt<'tcx>,
659+
symbol: ExportedSymbol<'tcx>,
660+
instantiating_crate: CrateNum,
661+
) {
662+
let (conv, _) = calling_convention_for_symbol(tcx, symbol);
663+
664+
if conv != Conv::GpuKernel || tcx.sess.target.os != "amdhsa" {
665+
return;
666+
}
667+
668+
let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
669+
670+
// Add the symbol for the kernel descriptor (with .kd suffix)
671+
symbols.push(format!("{undecorated}.kd"));
672+
}
673+
647674
fn maybe_emutls_symbol_name<'tcx>(
648675
tcx: TyCtxt<'tcx>,
649676
symbol: ExportedSymbol<'tcx>,

0 commit comments

Comments
 (0)
Please sign in to comment.