Skip to content

Commit df701a2

Browse files
committed
Querify global_backend_features
At the very least this serves to deduplicate the diagnostics that are output about unknown target features provided via CLI.
1 parent c97c216 commit df701a2

File tree

10 files changed

+58
-48
lines changed

10 files changed

+58
-48
lines changed

Diff for: compiler/rustc_codegen_gcc/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
132132
base::compile_codegen_unit(tcx, cgu_name)
133133
}
134134

135-
fn target_machine_factory(&self, _sess: &Session, _opt_level: OptLevel) -> TargetMachineFactoryFn<Self> {
135+
fn target_machine_factory(&self, _sess: &Session, _opt_level: OptLevel, _features: &[String]) -> TargetMachineFactoryFn<Self> {
136136
// TODO(antoyo): set opt level.
137137
Arc::new(|_| {
138138
Ok(())

Diff for: compiler/rustc_codegen_llvm/src/attributes.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,11 @@ pub fn sanitize_attrs<'ll>(
7979
}
8080
if enabled.contains(SanitizerSet::MEMTAG) {
8181
// Check to make sure the mte target feature is actually enabled.
82-
let sess = cx.tcx.sess;
83-
let features = llvm_util::llvm_global_features(sess).join(",");
84-
let mte_feature_enabled = features.rfind("+mte");
85-
let mte_feature_disabled = features.rfind("-mte");
86-
87-
if mte_feature_enabled.is_none() || (mte_feature_disabled > mte_feature_enabled) {
88-
sess.err("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`");
82+
let features = cx.tcx.global_backend_features(());
83+
let mte_feature =
84+
features.iter().map(|s| &s[..]).rfind(|n| ["+mte", "-mte"].contains(&&n[..]));
85+
if let None | Some("-mte") = mte_feature {
86+
cx.tcx.sess.err("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`");
8987
}
9088

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

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

Diff for: compiler/rustc_codegen_llvm/src/back/write.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ pub fn write_output_file<'ll>(
100100

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

@@ -115,8 +118,12 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut ll
115118
None
116119
};
117120
let config = TargetMachineFactoryConfig { split_dwarf_file };
118-
target_machine_factory(tcx.sess, tcx.backend_optimization_level(()))(config)
119-
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
121+
target_machine_factory(
122+
&tcx.sess,
123+
tcx.backend_optimization_level(()),
124+
tcx.global_backend_features(()),
125+
)(config)
126+
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
120127
}
121128

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

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

196204
let triple = SmallCStr::new(&sess.target.llvm_target);
197205
let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
198-
let features = llvm_util::llvm_global_features(sess).join(",");
199-
let features = CString::new(features).unwrap();
206+
let features = CString::new(target_features.join(",")).unwrap();
200207
let abi = SmallCStr::new(&sess.target.llvm_abiname);
201208
let trap_unreachable =
202209
sess.opts.debugging_opts.trap_unreachable.unwrap_or(sess.target.trap_unreachable);

Diff for: compiler/rustc_codegen_llvm/src/lib.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![feature(extern_types)]
1212
#![feature(once_cell)]
1313
#![feature(nll)]
14+
#![feature(iter_intersperse)]
1415
#![recursion_limit = "256"]
1516
#![allow(rustc::potential_query_instability)]
1617

@@ -32,6 +33,7 @@ use rustc_data_structures::fx::FxHashMap;
3233
use rustc_errors::{ErrorReported, FatalError, Handler};
3334
use rustc_metadata::EncodedMetadata;
3435
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
36+
use rustc_middle::ty::query::Providers;
3537
use rustc_middle::ty::TyCtxt;
3638
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
3739
use rustc_session::Session;
@@ -126,8 +128,9 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
126128
&self,
127129
sess: &Session,
128130
optlvl: OptLevel,
131+
target_features: &[String],
129132
) -> TargetMachineFactoryFn<Self> {
130-
back::write::target_machine_factory(sess, optlvl)
133+
back::write::target_machine_factory(sess, optlvl, target_features)
131134
}
132135
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str {
133136
llvm_util::target_cpu(sess)
@@ -251,6 +254,11 @@ impl CodegenBackend for LlvmCodegenBackend {
251254
llvm_util::init(sess); // Make sure llvm is inited
252255
}
253256

257+
fn provide(&self, providers: &mut Providers) {
258+
providers.global_backend_features =
259+
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
260+
}
261+
254262
fn print(&self, req: PrintRequest, sess: &Session) {
255263
match req {
256264
PrintRequest::RelocationModels => {

Diff for: compiler/rustc_codegen_ssa/src/back/write.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
10331033
} else {
10341034
tcx.backend_optimization_level(())
10351035
};
1036+
let backend_features = tcx.global_backend_features(());
10361037
let cgcx = CodegenContext::<B> {
10371038
backend: backend.clone(),
10381039
crate_types: sess.crate_types().to_vec(),
@@ -1054,7 +1055,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
10541055
regular_module_config: regular_config,
10551056
metadata_module_config: metadata_config,
10561057
allocator_module_config: allocator_config,
1057-
tm_factory: backend.target_machine_factory(tcx.sess, ol),
1058+
tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features),
10581059
total_cgus,
10591060
msvc_imps_needed: msvc_imps_needed(tcx),
10601061
is_pe_coff: tcx.sess.target.is_like_windows,

Diff for: compiler/rustc_codegen_ssa/src/traits/backend.rs

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
134134
&self,
135135
sess: &Session,
136136
opt_level: config::OptLevel,
137+
target_features: &[String],
137138
) -> TargetMachineFactoryFn<Self>;
138139
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
139140
fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str>;

Diff for: compiler/rustc_data_structures/src/small_c_str.rs

+12
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,15 @@ impl Deref for SmallCStr {
6666
self.as_c_str()
6767
}
6868
}
69+
70+
impl<'a> FromIterator<&'a str> for SmallCStr {
71+
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
72+
let mut data =
73+
iter.into_iter().flat_map(|s| s.as_bytes()).copied().collect::<SmallVec<_>>();
74+
data.push(0);
75+
if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) {
76+
panic!("The iterator {:?} cannot be converted into a CStr: {}", data, e);
77+
}
78+
Self { data }
79+
}
80+
}

Diff for: compiler/rustc_middle/src/query/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1944,4 +1944,13 @@ rustc_queries! {
19441944
no_hash
19451945
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
19461946
}
1947+
1948+
1949+
/// The list of backend features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
1950+
/// `--target` and similar).
1951+
query global_backend_features(_: ()) -> Vec<String> {
1952+
storage(ArenaCacheSelector<'tcx>)
1953+
eval_always
1954+
desc { "computing the backend features for CLI flags" }
1955+
}
19471956
}

Diff for: src/test/ui/target-feature/missing-plusminus.stderr

+1-13
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,5 @@ warning: unknown feature specified for `-Ctarget-feature`: `banana`
22
|
33
= note: features must begin with a `+` to enable or `-` to disable it
44

5-
warning: unknown feature specified for `-Ctarget-feature`: `banana`
6-
|
7-
= note: features must begin with a `+` to enable or `-` to disable it
8-
9-
warning: unknown feature specified for `-Ctarget-feature`: `banana`
10-
|
11-
= note: features must begin with a `+` to enable or `-` to disable it
12-
13-
warning: unknown feature specified for `-Ctarget-feature`: `banana`
14-
|
15-
= note: features must begin with a `+` to enable or `-` to disable it
16-
17-
warning: 4 warnings emitted
5+
warning: 1 warning emitted
186

Diff for: src/test/ui/target-feature/similar-feature-suggestion.stderr

+1-16
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,5 @@ warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
33
= note: it is still passed through to the codegen backend
44
= help: you might have meant: `rdrand`
55

6-
warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
7-
|
8-
= note: it is still passed through to the codegen backend
9-
= help: did you mean: `rdrand`
10-
11-
warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
12-
|
13-
= note: it is still passed through to the codegen backend
14-
= help: did you mean: `rdrand`
15-
16-
warning: unknown feature specified for `-Ctarget-feature`: `rdrnd`
17-
|
18-
= note: it is still passed through to the codegen backend
19-
= help: did you mean: `rdrand`
20-
21-
warning: 4 warnings emitted
6+
warning: 1 warning emitted
227

0 commit comments

Comments
 (0)