Skip to content

Commit b01cc1c

Browse files
committed
Auto merge of #148516 - bjorn3:target_feature_parsing_improvements, r=WaffleLapkin
Move warning reporting from flag_to_backend_features to cfg_target_feature This way warnings are emitted even in a check build.
2 parents 1ef7943 + 1d34478 commit b01cc1c

30 files changed

+448
-417
lines changed

compiler/rustc_codegen_gcc/src/gcc_util.rs

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
1212

1313
/// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
1414
/// `--target` and similar).
15-
pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<String> {
15+
pub(crate) fn global_gcc_features(sess: &Session) -> Vec<String> {
1616
// Features that come earlier are overridden by conflicting features later in the string.
1717
// Typically we'll want more explicit settings to override the implicit ones, so:
1818
//
@@ -37,27 +37,18 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
3737
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
3838

3939
// -Ctarget-features
40-
target_features::flag_to_backend_features(
41-
sess,
42-
diagnostics,
43-
|feature| to_gcc_features(sess, feature),
44-
|feature, enable| {
45-
// We run through `to_gcc_features` when
46-
// passing requests down to GCC. This means that all in-language
47-
// features also work on the command line instead of having two
48-
// different names when the GCC name and the Rust name differ.
49-
features.extend(
50-
to_gcc_features(sess, feature)
51-
.iter()
52-
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
53-
.map(
54-
|feature| {
55-
if !enable { format!("-{}", feature) } else { feature.to_string() }
56-
},
57-
),
58-
);
59-
},
60-
);
40+
target_features::flag_to_backend_features(sess, |feature, enable| {
41+
// We run through `to_gcc_features` when
42+
// passing requests down to GCC. This means that all in-language
43+
// features also work on the command line instead of having two
44+
// different names when the GCC name and the Rust name differ.
45+
features.extend(
46+
to_gcc_features(sess, feature)
47+
.iter()
48+
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
49+
.map(|feature| if !enable { format!("-{}", feature) } else { feature.to_string() }),
50+
);
51+
});
6152

6253
gcc_features_by_flags(sess, &mut features);
6354

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ use rustc_target::spec::{Arch, RelocModel};
107107
use tempfile::TempDir;
108108

109109
use crate::back::lto::ModuleBuffer;
110-
use crate::gcc_util::target_cpu;
110+
use crate::gcc_util::{target_cpu, to_gcc_features};
111111

112112
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
113113

@@ -220,7 +220,7 @@ impl CodegenBackend for GccCodegenBackend {
220220
}
221221

222222
fn provide(&self, providers: &mut Providers) {
223-
providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess, true)
223+
providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess)
224224
}
225225

226226
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
@@ -446,21 +446,25 @@ fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel {
446446

447447
/// Returns the features that should be set in `cfg(target_feature)`.
448448
fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig {
449-
let (unstable_target_features, target_features) = cfg_target_feature(sess, |feature| {
450-
// TODO: we disable Neon for now since we don't support the LLVM intrinsics for it.
451-
if feature == "neon" {
452-
return false;
453-
}
454-
target_info.cpu_supports(feature)
455-
// cSpell:disable
456-
/*
457-
adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma,
458-
avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq,
459-
bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm,
460-
sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves
461-
*/
462-
// cSpell:enable
463-
});
449+
let (unstable_target_features, target_features) = cfg_target_feature(
450+
sess,
451+
|feature| to_gcc_features(sess, feature),
452+
|feature| {
453+
// TODO: we disable Neon for now since we don't support the LLVM intrinsics for it.
454+
if feature == "neon" {
455+
return false;
456+
}
457+
target_info.cpu_supports(feature)
458+
// cSpell:disable
459+
/*
460+
adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma,
461+
avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq,
462+
bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm,
463+
sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves
464+
*/
465+
// cSpell:enable
466+
},
467+
);
464468

465469
let has_reliable_f16 = target_info.supports_target_dependent_type(CType::Float16);
466470
let has_reliable_f128 = target_info.supports_target_dependent_type(CType::Float128);

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub(crate) fn create_informational_target_machine(
109109
let config = TargetMachineFactoryConfig { split_dwarf_file: None, output_obj_file: None };
110110
// Can't use query system here quite yet because this function is invoked before the query
111111
// system/tcx is set up.
112-
let features = llvm_util::global_llvm_features(sess, false, only_base_features);
112+
let features = llvm_util::global_llvm_features(sess, only_base_features);
113113
target_machine_factory(sess, config::OptLevel::No, &features)(config)
114114
.unwrap_or_else(|err| llvm_err(sess.dcx(), err))
115115
}

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl CodegenBackend for LlvmCodegenBackend {
248248

249249
fn provide(&self, providers: &mut Providers) {
250250
providers.global_backend_features =
251-
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true, false)
251+
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, false)
252252
}
253253

254254
fn print(&self, req: &PrintRequest, out: &mut String, sess: &Session) {

compiler/rustc_codegen_llvm/src/llvm_util.rs

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -306,26 +306,34 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
306306
pub(crate) fn target_config(sess: &Session) -> TargetConfig {
307307
let target_machine = create_informational_target_machine(sess, true);
308308

309-
let (unstable_target_features, target_features) = cfg_target_feature(sess, |feature| {
310-
// This closure determines whether the target CPU has the feature according to LLVM. We do
311-
// *not* consider the `-Ctarget-feature`s here, as that will be handled later in
312-
// `cfg_target_feature`.
313-
if let Some(feat) = to_llvm_features(sess, feature) {
314-
// All the LLVM features this expands to must be enabled.
315-
for llvm_feature in feat {
316-
let cstr = SmallCStr::new(llvm_feature);
317-
// `LLVMRustHasFeature` is moderately expensive. On targets with many
318-
// features (e.g. x86) these calls take a non-trivial fraction of runtime
319-
// when compiling very small programs.
320-
if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } {
321-
return false;
309+
let (unstable_target_features, target_features) = cfg_target_feature(
310+
sess,
311+
|feature| {
312+
to_llvm_features(sess, feature)
313+
.map(|f| SmallVec::<[&str; 2]>::from_iter(f.into_iter()))
314+
.unwrap_or_default()
315+
},
316+
|feature| {
317+
// This closure determines whether the target CPU has the feature according to LLVM. We do
318+
// *not* consider the `-Ctarget-feature`s here, as that will be handled later in
319+
// `cfg_target_feature`.
320+
if let Some(feat) = to_llvm_features(sess, feature) {
321+
// All the LLVM features this expands to must be enabled.
322+
for llvm_feature in feat {
323+
let cstr = SmallCStr::new(llvm_feature);
324+
// `LLVMRustHasFeature` is moderately expensive. On targets with many
325+
// features (e.g. x86) these calls take a non-trivial fraction of runtime
326+
// when compiling very small programs.
327+
if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } {
328+
return false;
329+
}
322330
}
331+
true
332+
} else {
333+
false
323334
}
324-
true
325-
} else {
326-
false
327-
}
328-
});
335+
},
336+
);
329337

330338
let mut cfg = TargetConfig {
331339
target_features,
@@ -630,11 +638,7 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec<String>) {
630638

631639
/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
632640
/// `--target` and similar).
633-
pub(crate) fn global_llvm_features(
634-
sess: &Session,
635-
diagnostics: bool,
636-
only_base_features: bool,
637-
) -> Vec<String> {
641+
pub(crate) fn global_llvm_features(sess: &Session, only_base_features: bool) -> Vec<String> {
638642
// Features that come earlier are overridden by conflicting features later in the string.
639643
// Typically we'll want more explicit settings to override the implicit ones, so:
640644
//
@@ -694,39 +698,27 @@ pub(crate) fn global_llvm_features(
694698

695699
// -Ctarget-features
696700
if !only_base_features {
697-
target_features::flag_to_backend_features(
698-
sess,
699-
diagnostics,
700-
|feature| {
701-
to_llvm_features(sess, feature)
702-
.map(|f| SmallVec::<[&str; 2]>::from_iter(f.into_iter()))
703-
.unwrap_or_default()
704-
},
705-
|feature, enable| {
706-
let enable_disable = if enable { '+' } else { '-' };
707-
// We run through `to_llvm_features` when
708-
// passing requests down to LLVM. This means that all in-language
709-
// features also work on the command line instead of having two
710-
// different names when the LLVM name and the Rust name differ.
711-
let Some(llvm_feature) = to_llvm_features(sess, feature) else { return };
712-
713-
features.extend(
714-
std::iter::once(format!(
715-
"{}{}",
716-
enable_disable, llvm_feature.llvm_feature_name
717-
))
718-
.chain(llvm_feature.dependencies.into_iter().filter_map(
719-
move |feat| match (enable, feat) {
701+
target_features::flag_to_backend_features(sess, |feature, enable| {
702+
let enable_disable = if enable { '+' } else { '-' };
703+
// We run through `to_llvm_features` when
704+
// passing requests down to LLVM. This means that all in-language
705+
// features also work on the command line instead of having two
706+
// different names when the LLVM name and the Rust name differ.
707+
let Some(llvm_feature) = to_llvm_features(sess, feature) else { return };
708+
709+
features.extend(
710+
std::iter::once(format!("{}{}", enable_disable, llvm_feature.llvm_feature_name))
711+
.chain(llvm_feature.dependencies.into_iter().filter_map(move |feat| {
712+
match (enable, feat) {
720713
(_, TargetFeatureFoldStrength::Both(f))
721714
| (true, TargetFeatureFoldStrength::EnableOnly(f)) => {
722715
Some(format!("{enable_disable}{f}"))
723716
}
724717
_ => None,
725-
},
726-
)),
727-
)
728-
},
729-
);
718+
}
719+
})),
720+
)
721+
});
730722
}
731723

732724
// We add this in the "base target" so that these show up in `sess.unstable_target_features`.

0 commit comments

Comments
 (0)