diff options
| -rw-r--r-- | compiler/rustc_codegen_gcc/src/lib.rs | 39 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm_util.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/target_features.rs | 13 |
3 files changed, 37 insertions, 47 deletions
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index f5ad28681c7..a912678ef2a 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -102,10 +102,9 @@ use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::codegen_crate; +use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; -use rustc_codegen_ssa::{ - CodegenResults, CompiledModule, ModuleCodegen, TargetConfig, target_features, -}; +use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_errors::DiagCtxtHandle; @@ -478,25 +477,21 @@ fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel { /// Returns the features that should be set in `cfg(target_feature)`. fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig { - let (unstable_target_features, target_features) = target_features::cfg_target_feature( - sess, - /* FIXME: we ignore `-Ctarget-feature` */ "", - |feature| { - // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. - if feature == "neon" { - return false; - } - target_info.cpu_supports(feature) - // cSpell:disable - /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, - avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, - bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves - */ - // cSpell:enable - }, - ); + let (unstable_target_features, target_features) = cfg_target_feature(sess, |feature| { + // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. + if feature == "neon" { + return false; + } + target_info.cpu_supports(feature) + // cSpell:disable + /* + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves + */ + // cSpell:enable + }); let has_reliable_f16 = target_info.supports_target_dependent_type(CType::Float16); let has_reliable_f128 = target_info.supports_target_dependent_type(CType::Float128); diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index ee78c310b0d..bc2165fa829 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -7,6 +7,7 @@ use std::{ptr, slice, str}; use libc::c_int; use rustc_codegen_ssa::base::wants_wasm_eh; +use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::{TargetConfig, target_features}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::small_c_str::SmallCStr; @@ -331,24 +332,23 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig { // by LLVM. let target_machine = create_informational_target_machine(sess, true); - let (unstable_target_features, target_features) = - target_features::cfg_target_feature(sess, &sess.opts.cg.target_feature, |feature| { - if let Some(feat) = to_llvm_features(sess, feature) { - // All the LLVM features this expands to must be enabled. - for llvm_feature in feat { - let cstr = SmallCStr::new(llvm_feature); - // `LLVMRustHasFeature` is moderately expensive. On targets with many - // features (e.g. x86) these calls take a non-trivial fraction of runtime - // when compiling very small programs. - if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } { - return false; - } + let (unstable_target_features, target_features) = cfg_target_feature(sess, |feature| { + if let Some(feat) = to_llvm_features(sess, feature) { + // All the LLVM features this expands to must be enabled. + for llvm_feature in feat { + let cstr = SmallCStr::new(llvm_feature); + // `LLVMRustHasFeature` is moderately expensive. On targets with many + // features (e.g. x86) these calls take a non-trivial fraction of runtime + // when compiling very small programs. + if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) } { + return false; } - true - } else { - false } - }); + true + } else { + false + } + }); let mut cfg = TargetConfig { target_features, diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 41d8b8d8cbf..e29cdbb968e 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -163,8 +163,7 @@ pub(crate) fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, /// and call the closure for each (expanded) Rust feature. If the list contains /// a syntactically invalid item (not starting with `+`/`-`), the error callback is invoked. fn parse_rust_feature_flag<'a>( - sess: &Session, - target_feature_flag: &'a str, + sess: &'a Session, err_callback: impl Fn(&'a str), mut callback: impl FnMut( /* base_feature */ &'a str, @@ -175,7 +174,7 @@ fn parse_rust_feature_flag<'a>( // A cache for the backwards implication map. let mut inverse_implied_features: Option<FxHashMap<&str, FxHashSet<&str>>> = None; - for feature in target_feature_flag.split(',') { + for feature in sess.opts.cg.target_feature.split(',') { if let Some(base_feature) = feature.strip_prefix('+') { callback(base_feature, sess.target.implied_target_features(base_feature), true) } else if let Some(base_feature) = feature.strip_prefix('-') { @@ -215,15 +214,13 @@ fn parse_rust_feature_flag<'a>( /// to populate `sess.unstable_target_features` and `sess.target_features` (these are the first and /// 2nd component of the return value, respectively). /// -/// `target_feature_flag` is the value of `-Ctarget-feature` (giving the caller a chance to override it). /// `target_base_has_feature` should check whether the given feature (a Rust feature name!) is enabled /// in the "base" target machine, i.e., without applying `-Ctarget-feature`. /// /// We do not have to worry about RUSTC_SPECIFIC_FEATURES here, those are handled elsewhere. pub fn cfg_target_feature( sess: &Session, - target_feature_flag: &str, - mut is_feature_enabled: impl FnMut(&str) -> bool, + mut target_base_has_feature: impl FnMut(&str) -> bool, ) -> (Vec<Symbol>, Vec<Symbol>) { // Compute which of the known target features are enabled in the 'base' target machine. We only // consider "supported" features; "forbidden" features are not reflected in `cfg` as of now. @@ -236,7 +233,7 @@ pub fn cfg_target_feature( if RUSTC_SPECIAL_FEATURES.contains(feature) { return true; } - is_feature_enabled(feature) + target_base_has_feature(feature) }) .map(|(feature, _, _)| Symbol::intern(feature)) .collect(); @@ -244,7 +241,6 @@ pub fn cfg_target_feature( // Add enabled and remove disabled features. parse_rust_feature_flag( sess, - target_feature_flag, /* err_callback */ |_| {}, |_base_feature, new_features, enabled| { // Iteration order is irrelevant since this only influences an `UnordSet`. @@ -323,7 +319,6 @@ pub fn flag_to_backend_features<'a, const N: usize>( let mut rust_features = vec![]; parse_rust_feature_flag( sess, - &sess.opts.cg.target_feature, /* err_callback */ |feature| { if diagnostics { |
