about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2024-07-26 00:05:20 -0400
committerCaleb Zulawski <caleb.zulawski@gmail.com>2024-08-07 00:41:48 -0400
commit74653b61a67ae7db9f77ea1e09e65e40686c9058 (patch)
treec589eeb5a45e37481ce4a98efd90b0b09654ebe3 /compiler/rustc_codegen_ssa/src
parent6696447f784a888446d13bb400a8d507a68331c9 (diff)
downloadrust-74653b61a67ae7db9f77ea1e09e65e40686c9058.tar.gz
rust-74653b61a67ae7db9f77ea1e09e65e40686c9058.zip
Add implied target features to target_feature attribute
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs40
1 files changed, 31 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..1bf842b53a3 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::{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,12 @@ 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 implied features
+    for feature in added_target_features.iter() {
+        target_features
+            .extend(tcx.implied_target_features(*feature).clone().into_sorted_stable_ord());
     }
+    target_features.extend(added_target_features)
 }
 
 /// Computes the set of target features used in a function for the purposes of
@@ -162,6 +162,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
     }