Skip to content

Commit

Permalink
Querify global_backend_features
Browse files Browse the repository at this point in the history
At the very least this serves to deduplicate the diagnostics that are
output about unknown target features provided via CLI.
  • Loading branch information
nagisa committed Feb 28, 2022
1 parent c97c216 commit df701a2
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 48 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/lib.rs
Expand Up @@ -132,7 +132,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
base::compile_codegen_unit(tcx, cgu_name)
}

fn target_machine_factory(&self, _sess: &Session, _opt_level: OptLevel) -> TargetMachineFactoryFn<Self> {
fn target_machine_factory(&self, _sess: &Session, _opt_level: OptLevel, _features: &[String]) -> TargetMachineFactoryFn<Self> {
// TODO(antoyo): set opt level.
Arc::new(|_| {
Ok(())
Expand Down
21 changes: 10 additions & 11 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Expand Up @@ -79,13 +79,11 @@ pub fn sanitize_attrs<'ll>(
}
if enabled.contains(SanitizerSet::MEMTAG) {
// Check to make sure the mte target feature is actually enabled.
let sess = cx.tcx.sess;
let features = llvm_util::llvm_global_features(sess).join(",");
let mte_feature_enabled = features.rfind("+mte");
let mte_feature_disabled = features.rfind("-mte");

if mte_feature_enabled.is_none() || (mte_feature_disabled > mte_feature_enabled) {
sess.err("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`");
let features = cx.tcx.global_backend_features(());
let mte_feature =
features.iter().map(|s| &s[..]).rfind(|n| ["+mte", "-mte"].contains(&&n[..]));
if let None | Some("-mte") = mte_feature {
cx.tcx.sess.err("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`");
}

attrs.push(llvm::AttributeKind::SanitizeMemTag.create_attr(cx.llcx));
Expand Down Expand Up @@ -415,10 +413,11 @@ pub fn from_fn_attrs<'ll, 'tcx>(
}

if !function_features.is_empty() {
let mut global_features = llvm_util::llvm_global_features(cx.tcx.sess);
global_features.extend(function_features.into_iter());
let features = global_features.join(",");
let val = CString::new(features).unwrap();
let global_features = cx.tcx.global_backend_features(()).iter().map(|s| &s[..]);
let val = global_features
.chain(function_features.iter().map(|s| &s[..]))
.intersperse(",")
.collect::<SmallCStr>();
to_add.push(llvm::CreateAttrStringValue(cx.llcx, cstr!("target-features"), &val));
}

Expand Down
17 changes: 12 additions & 5 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Expand Up @@ -100,7 +100,10 @@ pub fn write_output_file<'ll>(

pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm::TargetMachine {
let config = TargetMachineFactoryConfig { split_dwarf_file: None };
target_machine_factory(sess, config::OptLevel::No)(config)
// Can't use query system here quite yet because this function is invoked before the query
// system/tcx is set up.
let features = llvm_util::global_llvm_features(sess, false);
target_machine_factory(sess, config::OptLevel::No, &features)(config)
.unwrap_or_else(|err| llvm_err(sess.diagnostic(), &err).raise())
}

Expand All @@ -115,8 +118,12 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut ll
None
};
let config = TargetMachineFactoryConfig { split_dwarf_file };
target_machine_factory(tcx.sess, tcx.backend_optimization_level(()))(config)
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
target_machine_factory(
&tcx.sess,
tcx.backend_optimization_level(()),
tcx.global_backend_features(()),
)(config)
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
}

pub fn to_llvm_opt_settings(
Expand Down Expand Up @@ -171,6 +178,7 @@ pub(crate) fn to_llvm_code_model(code_model: Option<CodeModel>) -> llvm::CodeMod
pub fn target_machine_factory(
sess: &Session,
optlvl: config::OptLevel,
target_features: &[String],
) -> TargetMachineFactoryFn<LlvmCodegenBackend> {
let reloc_model = to_llvm_relocation_model(sess.relocation_model());

Expand All @@ -195,8 +203,7 @@ pub fn target_machine_factory(

let triple = SmallCStr::new(&sess.target.llvm_target);
let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
let features = llvm_util::llvm_global_features(sess).join(",");
let features = CString::new(features).unwrap();
let features = CString::new(target_features.join(",")).unwrap();
let abi = SmallCStr::new(&sess.target.llvm_abiname);
let trap_unreachable =
sess.opts.debugging_opts.trap_unreachable.unwrap_or(sess.target.trap_unreachable);
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_codegen_llvm/src/lib.rs
Expand Up @@ -11,6 +11,7 @@
#![feature(extern_types)]
#![feature(once_cell)]
#![feature(nll)]
#![feature(iter_intersperse)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

Expand All @@ -32,6 +33,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{ErrorReported, FatalError, Handler};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
use rustc_session::Session;
Expand Down Expand Up @@ -126,8 +128,9 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
&self,
sess: &Session,
optlvl: OptLevel,
target_features: &[String],
) -> TargetMachineFactoryFn<Self> {
back::write::target_machine_factory(sess, optlvl)
back::write::target_machine_factory(sess, optlvl, target_features)
}
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str {
llvm_util::target_cpu(sess)
Expand Down Expand Up @@ -251,6 +254,11 @@ impl CodegenBackend for LlvmCodegenBackend {
llvm_util::init(sess); // Make sure llvm is inited
}

fn provide(&self, providers: &mut Providers) {
providers.global_backend_features =
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
}

fn print(&self, req: PrintRequest, sess: &Session) {
match req {
PrintRequest::RelocationModels => {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/write.rs
Expand Up @@ -1033,6 +1033,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
} else {
tcx.backend_optimization_level(())
};
let backend_features = tcx.global_backend_features(());
let cgcx = CodegenContext::<B> {
backend: backend.clone(),
crate_types: sess.crate_types().to_vec(),
Expand All @@ -1054,7 +1055,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
regular_module_config: regular_config,
metadata_module_config: metadata_config,
allocator_module_config: allocator_config,
tm_factory: backend.target_machine_factory(tcx.sess, ol),
tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features),
total_cgus,
msvc_imps_needed: msvc_imps_needed(tcx),
is_pe_coff: tcx.sess.target.is_like_windows,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Expand Up @@ -134,6 +134,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
&self,
sess: &Session,
opt_level: config::OptLevel,
target_features: &[String],
) -> TargetMachineFactoryFn<Self>;
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str>;
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_data_structures/src/small_c_str.rs
Expand Up @@ -66,3 +66,15 @@ impl Deref for SmallCStr {
self.as_c_str()
}
}

impl<'a> FromIterator<&'a str> for SmallCStr {
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
let mut data =
iter.into_iter().flat_map(|s| s.as_bytes()).copied().collect::<SmallVec<_>>();
data.push(0);
if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) {
panic!("The iterator {:?} cannot be converted into a CStr: {}", data, e);
}
Self { data }
}
}
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Expand Up @@ -1944,4 +1944,13 @@ rustc_queries! {
no_hash
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
}


/// The list of backend features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
/// `--target` and similar).
query global_backend_features(_: ()) -> Vec<String> {
storage(ArenaCacheSelector<'tcx>)
eval_always
desc { "computing the backend features for CLI flags" }
}
}
14 changes: 1 addition & 13 deletions src/test/ui/target-feature/missing-plusminus.stderr
Expand Up @@ -2,17 +2,5 @@ warning: unknown feature specified for `-Ctarget-feature`: `banana`
|
= note: features must begin with a `+` to enable or `-` to disable it

warning: unknown feature specified for `-Ctarget-feature`: `banana`
|
= note: features must begin with a `+` to enable or `-` to disable it

warning: unknown feature specified for `-Ctarget-feature`: `banana`
|
= note: features must begin with a `+` to enable or `-` to disable it

warning: unknown feature specified for `-Ctarget-feature`: `banana`
|
= note: features must begin with a `+` to enable or `-` to disable it

warning: 4 warnings emitted
warning: 1 warning emitted

17 changes: 1 addition & 16 deletions src/test/ui/target-feature/similar-feature-suggestion.stderr
Expand Up @@ -3,20 +3,5 @@ warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
= note: it is still passed through to the codegen backend
= help: you might have meant: `rdrand`

warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
|
= note: it is still passed through to the codegen backend
= help: did you mean: `rdrand`

warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
|
= note: it is still passed through to the codegen backend
= help: did you mean: `rdrand`

warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
|
= note: it is still passed through to the codegen backend
= help: did you mean: `rdrand`

warning: 4 warnings emitted
warning: 1 warning emitted

0 comments on commit df701a2

Please sign in to comment.