Skip to content

Commit d3903d5

Browse files
committed
Create nvptx64-nvidia-cuda target specification
1 parent 01af120 commit d3903d5

File tree

16 files changed

+433
-17
lines changed

16 files changed

+433
-17
lines changed

src/bootstrap/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ impl Build {
831831
!target.contains("msvc") &&
832832
!target.contains("emscripten") &&
833833
!target.contains("wasm32") &&
834+
!target.contains("nvptx") &&
834835
!target.contains("fuchsia") {
835836
Some(self.cc(target))
836837
} else {

src/bootstrap/sanity.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub fn check(build: &mut Build) {
156156
panic!("the iOS target is only supported on macOS");
157157
}
158158

159-
if target.contains("-none-") {
159+
if target.contains("-none-") || target.contains("nvptx") {
160160
if build.no_std(*target).is_none() {
161161
let target = build.config.target_config.entry(target.clone())
162162
.or_default();
@@ -165,7 +165,7 @@ pub fn check(build: &mut Build) {
165165
}
166166

167167
if build.no_std(*target) == Some(false) {
168-
panic!("All the *-none-* targets are no-std targets")
168+
panic!("All the *-none-* and nvptx* targets are no-std targets")
169169
}
170170
}
171171

src/librustc/ty/context.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
16751675
}
16761676
false
16771677
}
1678+
1679+
/// Determine whether identifiers in the assembly have strict naming rules.
1680+
/// Currently, only NVPTX* targets need it.
1681+
pub fn has_strict_asm_symbol_naming(&self) -> bool {
1682+
self.gcx.sess.target.target.arch.contains("nvptx")
1683+
}
16781684
}
16791685

16801686
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {

src/librustc_codegen_ssa/back/link.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
149149
LinkerFlavor::Ld => "ld",
150150
LinkerFlavor::Msvc => "link.exe",
151151
LinkerFlavor::Lld(_) => "lld",
152+
LinkerFlavor::PtxLinker => "rust-ptx-linker",
152153
}), flavor)),
153154
(Some(linker), None) => {
154155
let stem = if linker.extension().and_then(|ext| ext.to_str()) == Some("exe") {

src/librustc_codegen_ssa/back/linker.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ impl LinkerInfo {
8383
LinkerFlavor::Lld(LldFlavor::Wasm) => {
8484
Box::new(WasmLd::new(cmd, sess, self)) as Box<dyn Linker>
8585
}
86+
87+
LinkerFlavor::PtxLinker => {
88+
Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>
89+
}
8690
}
8791
}
8892
}
@@ -1080,3 +1084,124 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
10801084

10811085
symbols
10821086
}
1087+
1088+
/// Much simplified and explicit CLI for the NVPTX linker. The linker operates
1089+
/// with bitcode and uses LLVM backend to generate a PTX assembly.
1090+
pub struct PtxLinker<'a> {
1091+
cmd: Command,
1092+
sess: &'a Session,
1093+
}
1094+
1095+
impl<'a> Linker for PtxLinker<'a> {
1096+
fn link_rlib(&mut self, path: &Path) {
1097+
self.cmd.arg("--rlib").arg(path);
1098+
}
1099+
1100+
fn link_whole_rlib(&mut self, path: &Path) {
1101+
self.cmd.arg("--rlib").arg(path);
1102+
}
1103+
1104+
fn include_path(&mut self, path: &Path) {
1105+
self.cmd.arg("-L").arg(path);
1106+
}
1107+
1108+
fn debuginfo(&mut self) {
1109+
self.cmd.arg("--debug");
1110+
}
1111+
1112+
fn add_object(&mut self, path: &Path) {
1113+
self.cmd.arg("--bitcode").arg(path);
1114+
}
1115+
1116+
fn args(&mut self, args: &[String]) {
1117+
self.cmd.args(args);
1118+
}
1119+
1120+
fn optimize(&mut self) {
1121+
self.cmd.arg(match self.sess.opts.optimize {
1122+
OptLevel::No => "-O0",
1123+
OptLevel::Less => "-O1",
1124+
OptLevel::Default => "-O2",
1125+
OptLevel::Aggressive => "-O3",
1126+
OptLevel::Size => "-Os",
1127+
OptLevel::SizeMin => "-Os"
1128+
});
1129+
}
1130+
1131+
fn output_filename(&mut self, path: &Path) {
1132+
self.cmd.arg("-o").arg(path);
1133+
}
1134+
1135+
fn finalize(&mut self) -> Command {
1136+
::std::mem::replace(&mut self.cmd, Command::new(""))
1137+
}
1138+
1139+
fn link_dylib(&mut self, _lib: &str) {
1140+
panic!("external dylibs not supported")
1141+
}
1142+
1143+
fn link_rust_dylib(&mut self, _lib: &str, _path: &Path) {
1144+
panic!("external dylibs not supported")
1145+
}
1146+
1147+
fn link_staticlib(&mut self, _lib: &str) {
1148+
panic!("staticlibs not supported")
1149+
}
1150+
1151+
fn link_whole_staticlib(&mut self, _lib: &str, _search_path: &[PathBuf]) {
1152+
panic!("staticlibs not supported")
1153+
}
1154+
1155+
fn framework_path(&mut self, _path: &Path) {
1156+
panic!("frameworks not supported")
1157+
}
1158+
1159+
fn link_framework(&mut self, _framework: &str) {
1160+
panic!("frameworks not supported")
1161+
}
1162+
1163+
fn position_independent_executable(&mut self) {
1164+
}
1165+
1166+
fn full_relro(&mut self) {
1167+
}
1168+
1169+
fn partial_relro(&mut self) {
1170+
}
1171+
1172+
fn no_relro(&mut self) {
1173+
}
1174+
1175+
fn build_static_executable(&mut self) {
1176+
}
1177+
1178+
fn gc_sections(&mut self, _keep_metadata: bool) {
1179+
}
1180+
1181+
fn pgo_gen(&mut self) {
1182+
}
1183+
1184+
fn no_default_libraries(&mut self) {
1185+
}
1186+
1187+
fn build_dylib(&mut self, _out_filename: &Path) {
1188+
}
1189+
1190+
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) {
1191+
}
1192+
1193+
fn subsystem(&mut self, _subsystem: &str) {
1194+
}
1195+
1196+
fn no_position_independent_executable(&mut self) {
1197+
}
1198+
1199+
fn group_start(&mut self) {
1200+
}
1201+
1202+
fn group_end(&mut self) {
1203+
}
1204+
1205+
fn cross_lang_lto(&mut self) {
1206+
}
1207+
}

src/librustc_codegen_utils/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![feature(nll)]
1313
#![allow(unused_attributes)]
1414
#![feature(rustc_diagnostic_macros)]
15+
#![feature(in_band_lifetimes)]
1516

1617
#![recursion_limit="256"]
1718

src/librustc_codegen_utils/symbol_names.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ use rustc_mir::monomorphize::Instance;
103103

104104
use syntax_pos::symbol::Symbol;
105105

106-
use std::fmt::Write;
106+
use std::fmt::{self, Write};
107107
use std::mem::discriminant;
108108

109109
pub fn provide(providers: &mut Providers) {
@@ -221,7 +221,7 @@ fn get_symbol_hash<'a, 'tcx>(
221221
}
222222

223223
fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
224-
let mut buffer = SymbolPathBuffer::new();
224+
let mut buffer = SymbolPathBuffer::new(tcx);
225225
item_path::with_forced_absolute_paths(|| {
226226
tcx.push_item_path(&mut buffer, def_id, false);
227227
});
@@ -317,7 +317,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
317317

318318
let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs);
319319

320-
let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id));
320+
let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id), tcx);
321321

322322
if instance.is_vtable_shim() {
323323
buf.push("{{vtable-shim}}");
@@ -339,26 +339,28 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
339339
//
340340
// To be able to work on all platforms and get *some* reasonable output, we
341341
// use C++ name-mangling.
342-
#[derive(Debug)]
343-
struct SymbolPathBuffer {
342+
struct SymbolPathBuffer<'a, 'tcx> {
343+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
344344
result: String,
345345
temp_buf: String,
346346
}
347347

348-
impl SymbolPathBuffer {
349-
fn new() -> Self {
348+
impl SymbolPathBuffer<'a, 'tcx> {
349+
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
350350
let mut result = SymbolPathBuffer {
351351
result: String::with_capacity(64),
352352
temp_buf: String::with_capacity(16),
353+
tcx,
353354
};
354355
result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested
355356
result
356357
}
357358

358-
fn from_interned(symbol: ty::SymbolName) -> Self {
359+
fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
359360
let mut result = SymbolPathBuffer {
360361
result: String::with_capacity(64),
361362
temp_buf: String::with_capacity(16),
363+
tcx,
362364
};
363365
result.result.push_str(&symbol.as_str());
364366
result
@@ -377,15 +379,15 @@ impl SymbolPathBuffer {
377379
}
378380
}
379381

380-
impl ItemPathBuffer for SymbolPathBuffer {
382+
impl ItemPathBuffer for SymbolPathBuffer<'a, 'tcx> {
381383
fn root_mode(&self) -> &RootMode {
382384
const ABSOLUTE: &RootMode = &RootMode::Absolute;
383385
ABSOLUTE
384386
}
385387

386388
fn push(&mut self, text: &str) {
387389
self.temp_buf.clear();
388-
let need_underscore = sanitize(&mut self.temp_buf, text);
390+
let need_underscore = sanitize(&mut self.temp_buf, text, self.tcx);
389391
let _ = write!(
390392
self.result,
391393
"{}",
@@ -398,12 +400,24 @@ impl ItemPathBuffer for SymbolPathBuffer {
398400
}
399401
}
400402

403+
// Manual Debug implementation to omit non-Debug `tcx` field.
404+
impl fmt::Debug for SymbolPathBuffer<'_, '_> {
405+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
406+
fmt.debug_struct("SymbolPathBuffer")
407+
.field("result", &self.result)
408+
.field("temp_buf", &self.temp_buf)
409+
.finish()
410+
}
411+
}
412+
401413
// Name sanitation. LLVM will happily accept identifiers with weird names, but
402414
// gas doesn't!
403415
// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
416+
// NVPTX assembly has more strict naming rules than gas, so additionally, dots
417+
// are replaced with '$' there.
404418
//
405419
// returns true if an underscore must be added at the start
406-
pub fn sanitize(result: &mut String, s: &str) -> bool {
420+
pub fn sanitize(result: &mut String, s: &str, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
407421
for c in s.chars() {
408422
match c {
409423
// Escape these with $ sequences
@@ -416,12 +430,25 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
416430
')' => result.push_str("$RP$"),
417431
',' => result.push_str("$C$"),
418432

419-
// '.' doesn't occur in types and functions, so reuse it
420-
// for ':' and '-'
421-
'-' | ':' => result.push('.'),
433+
'-' | ':' => if tcx.has_strict_asm_symbol_naming() {
434+
// NVPTX doesn't support these characters in symbol names.
435+
result.push('$')
436+
}
437+
else {
438+
// '.' doesn't occur in types and functions, so reuse it
439+
// for ':' and '-'
440+
result.push('.')
441+
},
442+
443+
'.' => if tcx.has_strict_asm_symbol_naming() {
444+
result.push('$')
445+
}
446+
else {
447+
result.push('.')
448+
},
422449

423450
// These are legal symbols
424-
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => result.push(c),
451+
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => result.push(c),
425452

426453
_ => {
427454
result.push('$');

src/librustc_target/spec/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub enum LinkerFlavor {
7575
Ld,
7676
Msvc,
7777
Lld(LldFlavor),
78+
PtxLinker,
7879
}
7980

8081
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash,
@@ -143,6 +144,7 @@ flavor_mappings! {
143144
((LinkerFlavor::Gcc), "gcc"),
144145
((LinkerFlavor::Ld), "ld"),
145146
((LinkerFlavor::Msvc), "msvc"),
147+
((LinkerFlavor::PtxLinker), "ptx-linker"),
146148
((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"),
147149
((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"),
148150
((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"),
@@ -455,6 +457,8 @@ supported_targets! {
455457
("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),
456458

457459
("x86_64-unknown-uefi", x86_64_unknown_uefi),
460+
461+
("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),
458462
}
459463

460464
/// Everything `rustc` knows about how to compile for a specific target.

0 commit comments

Comments
 (0)