From d3903d5f9c4e58cc3fa256ec5be52717b84e6308 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Sat, 19 Jan 2019 21:59:34 +0100 Subject: Create `nvptx64-nvidia-cuda` target specification --- src/librustc_codegen_utils/lib.rs | 1 + src/librustc_codegen_utils/symbol_names.rs | 57 ++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 15 deletions(-) (limited to 'src/librustc_codegen_utils') diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 1f590d46ed8..8e96f985401 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -12,6 +12,7 @@ #![feature(nll)] #![allow(unused_attributes)] #![feature(rustc_diagnostic_macros)] +#![feature(in_band_lifetimes)] #![recursion_limit="256"] diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 9267f14f242..f2014f74212 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -103,7 +103,7 @@ use rustc_mir::monomorphize::Instance; use syntax_pos::symbol::Symbol; -use std::fmt::Write; +use std::fmt::{self, Write}; use std::mem::discriminant; pub fn provide(providers: &mut Providers) { @@ -221,7 +221,7 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - let mut buffer = SymbolPathBuffer::new(); + let mut buffer = SymbolPathBuffer::new(tcx); item_path::with_forced_absolute_paths(|| { tcx.push_item_path(&mut buffer, def_id, false); }); @@ -317,7 +317,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs); - let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id)); + let mut buf = SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id), tcx); if instance.is_vtable_shim() { buf.push("{{vtable-shim}}"); @@ -339,26 +339,28 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance // // To be able to work on all platforms and get *some* reasonable output, we // use C++ name-mangling. -#[derive(Debug)] -struct SymbolPathBuffer { +struct SymbolPathBuffer<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, result: String, temp_buf: String, } -impl SymbolPathBuffer { - fn new() -> Self { +impl SymbolPathBuffer<'a, 'tcx> { + fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), + tcx, }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } - fn from_interned(symbol: ty::SymbolName) -> Self { + fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), + tcx, }; result.result.push_str(&symbol.as_str()); result @@ -377,7 +379,7 @@ impl SymbolPathBuffer { } } -impl ItemPathBuffer for SymbolPathBuffer { +impl ItemPathBuffer for SymbolPathBuffer<'a, 'tcx> { fn root_mode(&self) -> &RootMode { const ABSOLUTE: &RootMode = &RootMode::Absolute; ABSOLUTE @@ -385,7 +387,7 @@ impl ItemPathBuffer for SymbolPathBuffer { fn push(&mut self, text: &str) { self.temp_buf.clear(); - let need_underscore = sanitize(&mut self.temp_buf, text); + let need_underscore = sanitize(&mut self.temp_buf, text, self.tcx); let _ = write!( self.result, "{}", @@ -398,12 +400,24 @@ impl ItemPathBuffer for SymbolPathBuffer { } } +// Manual Debug implementation to omit non-Debug `tcx` field. +impl fmt::Debug for SymbolPathBuffer<'_, '_> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("SymbolPathBuffer") + .field("result", &self.result) + .field("temp_buf", &self.temp_buf) + .finish() + } +} + // Name sanitation. LLVM will happily accept identifiers with weird names, but // gas doesn't! // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ +// NVPTX assembly has more strict naming rules than gas, so additionally, dots +// are replaced with '$' there. // // returns true if an underscore must be added at the start -pub fn sanitize(result: &mut String, s: &str) -> bool { +pub fn sanitize(result: &mut String, s: &str, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { for c in s.chars() { match c { // Escape these with $ sequences @@ -416,12 +430,25 @@ pub fn sanitize(result: &mut String, s: &str) -> bool { ')' => result.push_str("$RP$"), ',' => result.push_str("$C$"), - // '.' doesn't occur in types and functions, so reuse it - // for ':' and '-' - '-' | ':' => result.push('.'), + '-' | ':' => if tcx.has_strict_asm_symbol_naming() { + // NVPTX doesn't support these characters in symbol names. + result.push('$') + } + else { + // '.' doesn't occur in types and functions, so reuse it + // for ':' and '-' + result.push('.') + }, + + '.' => if tcx.has_strict_asm_symbol_naming() { + result.push('$') + } + else { + result.push('.') + }, // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => result.push(c), + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => result.push(c), _ => { result.push('$'); -- cgit 1.4.1-3-g733a5 From 8d53c9247c23e36219102be68f887b0a39085a32 Mon Sep 17 00:00:00 2001 From: Denys Zariaiev Date: Mon, 28 Jan 2019 01:16:59 +0100 Subject: SymbolPathBuffer shallow refactoring --- src/librustc_codegen_utils/symbol_names.rs | 156 ++++++++++++++--------------- 1 file changed, 76 insertions(+), 80 deletions(-) (limited to 'src/librustc_codegen_utils') diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index f2014f74212..3238a0b10bf 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -103,7 +103,7 @@ use rustc_mir::monomorphize::Instance; use syntax_pos::symbol::Symbol; -use std::fmt::{self, Write}; +use std::fmt::Write; use std::mem::discriminant; pub fn provide(providers: &mut Providers) { @@ -339,28 +339,29 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance // // To be able to work on all platforms and get *some* reasonable output, we // use C++ name-mangling. -struct SymbolPathBuffer<'a, 'tcx> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, +#[derive(Debug)] +struct SymbolPathBuffer { result: String, temp_buf: String, + strict_naming: bool, } -impl SymbolPathBuffer<'a, 'tcx> { - fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { +impl SymbolPathBuffer { + fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - tcx, + strict_naming: tcx.has_strict_asm_symbol_naming(), }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } - fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { + fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self { let mut result = SymbolPathBuffer { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - tcx, + strict_naming: tcx.has_strict_asm_symbol_naming(), }; result.result.push_str(&symbol.as_str()); result @@ -377,93 +378,88 @@ impl SymbolPathBuffer<'a, 'tcx> { let _ = write!(self.result, "17h{:016x}E", hash); self.result } -} -impl ItemPathBuffer for SymbolPathBuffer<'a, 'tcx> { - fn root_mode(&self) -> &RootMode { - const ABSOLUTE: &RootMode = &RootMode::Absolute; - ABSOLUTE - } - - fn push(&mut self, text: &str) { + // Name sanitation. LLVM will happily accept identifiers with weird names, but + // gas doesn't! + // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ + // NVPTX assembly has more strict naming rules than gas, so additionally, dots + // are replaced with '$' there. + fn sanitize_and_append(&mut self, s: &str) { self.temp_buf.clear(); - let need_underscore = sanitize(&mut self.temp_buf, text, self.tcx); + + for c in s.chars() { + match c { + // Escape these with $ sequences + '@' => self.temp_buf.push_str("$SP$"), + '*' => self.temp_buf.push_str("$BP$"), + '&' => self.temp_buf.push_str("$RF$"), + '<' => self.temp_buf.push_str("$LT$"), + '>' => self.temp_buf.push_str("$GT$"), + '(' => self.temp_buf.push_str("$LP$"), + ')' => self.temp_buf.push_str("$RP$"), + ',' => self.temp_buf.push_str("$C$"), + + '-' | ':' => if self.strict_naming { + // NVPTX doesn't support these characters in symbol names. + self.temp_buf.push('$') + } + else { + // '.' doesn't occur in types and functions, so reuse it + // for ':' and '-' + self.temp_buf.push('.') + }, + + '.' => if self.strict_naming { + self.temp_buf.push('$') + } + else { + self.temp_buf.push('.') + }, + + // These are legal symbols + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => self.temp_buf.push(c), + + _ => { + self.temp_buf.push('$'); + for c in c.escape_unicode().skip(1) { + match c { + '{' => {} + '}' => self.temp_buf.push('$'), + c => self.temp_buf.push(c), + } + } + } + } + } + + let need_underscore = { + // Underscore-qualify anything that didn't start as an ident. + !self.temp_buf.is_empty() + && self.temp_buf.as_bytes()[0] != '_' as u8 + && !(self.temp_buf.as_bytes()[0] as char).is_xid_start() + }; + let _ = write!( self.result, "{}", self.temp_buf.len() + (need_underscore as usize) ); + if need_underscore { self.result.push('_'); } + self.result.push_str(&self.temp_buf); } } -// Manual Debug implementation to omit non-Debug `tcx` field. -impl fmt::Debug for SymbolPathBuffer<'_, '_> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("SymbolPathBuffer") - .field("result", &self.result) - .field("temp_buf", &self.temp_buf) - .finish() +impl ItemPathBuffer for SymbolPathBuffer { + fn root_mode(&self) -> &RootMode { + const ABSOLUTE: &RootMode = &RootMode::Absolute; + ABSOLUTE } -} - -// Name sanitation. LLVM will happily accept identifiers with weird names, but -// gas doesn't! -// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $ -// NVPTX assembly has more strict naming rules than gas, so additionally, dots -// are replaced with '$' there. -// -// returns true if an underscore must be added at the start -pub fn sanitize(result: &mut String, s: &str, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { - for c in s.chars() { - match c { - // Escape these with $ sequences - '@' => result.push_str("$SP$"), - '*' => result.push_str("$BP$"), - '&' => result.push_str("$RF$"), - '<' => result.push_str("$LT$"), - '>' => result.push_str("$GT$"), - '(' => result.push_str("$LP$"), - ')' => result.push_str("$RP$"), - ',' => result.push_str("$C$"), - - '-' | ':' => if tcx.has_strict_asm_symbol_naming() { - // NVPTX doesn't support these characters in symbol names. - result.push('$') - } - else { - // '.' doesn't occur in types and functions, so reuse it - // for ':' and '-' - result.push('.') - }, - - '.' => if tcx.has_strict_asm_symbol_naming() { - result.push('$') - } - else { - result.push('.') - }, - - // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '$' => result.push(c), - _ => { - result.push('$'); - for c in c.escape_unicode().skip(1) { - match c { - '{' => {} - '}' => result.push('$'), - c => result.push(c), - } - } - } - } + fn push(&mut self, text: &str) { + self.sanitize_and_append(text); } - - // Underscore-qualify anything that didn't start as an ident. - !result.is_empty() && result.as_bytes()[0] != '_' as u8 - && !(result.as_bytes()[0] as char).is_xid_start() } -- cgit 1.4.1-3-g733a5