diff options
| author | bors <bors@rust-lang.org> | 2024-08-07 09:26:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-08-07 09:26:42 +0000 |
| commit | 384f8586cb7d3770b2572e9a998a33706f0983ac (patch) | |
| tree | ef23cabaebea1904b592c6c16b23d00ebe32d964 /compiler/rustc_codegen_ssa/src | |
| parent | c755314d780b0ac0e712efc258533bbd8431d1f0 (diff) | |
| parent | 630ad887720e8c1357e0196021e2246de3b96fdd (diff) | |
| download | rust-384f8586cb7d3770b2572e9a998a33706f0983ac.tar.gz rust-384f8586cb7d3770b2572e9a998a33706f0983ac.zip | |
Auto merge of #3793 - rust-lang:rustup-2024-08-07, r=RalfJung
Automatic Rustup
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/target_features.rs | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 127244a34f8..24b2c9c51c6 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -1,7 +1,7 @@ use rustc_ast::ast; use rustc_attr::InstructionSetAttr; -use rustc_data_structures::fx::FxIndexSet; -use rustc_data_structures::unord::UnordMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet}; use rustc_errors::Applicability; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; @@ -30,6 +30,7 @@ pub fn from_target_feature( .emit(); }; let rust_features = tcx.features(); + let mut added_target_features = Vec::new(); for item in list { // Only `enable = ...` is accepted in the meta-item list. if !item.has_name(sym::enable) { @@ -44,7 +45,7 @@ pub fn from_target_feature( }; // We allow comma separation to enable multiple features. - target_features.extend(value.as_str().split(',').filter_map(|feature| { + added_target_features.extend(value.as_str().split(',').filter_map(|feature| { let Some(feature_gate) = supported_target_features.get(feature) else { let msg = format!("the feature named `{feature}` is not valid for this target"); let mut err = tcx.dcx().struct_span_err(item.span(), msg); @@ -98,13 +99,14 @@ pub fn from_target_feature( })); } - for (feature, requires) in tcx.sess.target.implicit_target_features() { - if target_features.iter().any(|f| f.as_str() == *feature) - && !target_features.iter().any(|f| f.as_str() == *requires) - { - target_features.push(Symbol::intern(requires)); - } + // Add both explicit and implied target features, using a set to deduplicate + let mut target_features_set = UnordSet::new(); + for feature in added_target_features.iter() { + target_features_set + .extend_unord(tcx.implied_target_features(*feature).clone().into_items()); } + target_features_set.extend(added_target_features); + target_features.extend(target_features_set.into_sorted_stable_ord()) } /// Computes the set of target features used in a function for the purposes of @@ -162,6 +164,28 @@ pub(crate) fn provide(providers: &mut Providers) { .collect() } }, + implied_target_features: |tcx, feature| { + let implied_features = tcx + .sess + .target + .implied_target_features() + .iter() + .map(|(f, i)| (Symbol::intern(f), i)) + .collect::<FxHashMap<_, _>>(); + + // implied target features have their own implied target features, so we traverse the + // map until there are no more features to add + let mut features = UnordSet::new(); + let mut new_features = vec![feature]; + while let Some(new_feature) = new_features.pop() { + if features.insert(new_feature) { + if let Some(implied_features) = implied_features.get(&new_feature) { + new_features.extend(implied_features.iter().copied().map(Symbol::intern)) + } + } + } + features + }, asm_target_features, ..*providers } |
