@@ -6,9 +6,9 @@ use std::sync::Once;
66use std:: { ptr, slice, str} ;
77
88use libc:: c_int;
9- use rustc_codegen_ssa:: TargetConfig ;
109use rustc_codegen_ssa:: base:: wants_wasm_eh;
1110use rustc_codegen_ssa:: codegen_attrs:: check_tied_features;
11+ use rustc_codegen_ssa:: { TargetConfig , target_features} ;
1212use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1313use rustc_data_structures:: small_c_str:: SmallCStr ;
1414use rustc_data_structures:: unord:: UnordSet ;
@@ -17,9 +17,8 @@ use rustc_middle::bug;
1717use rustc_session:: Session ;
1818use rustc_session:: config:: { PrintKind , PrintRequest } ;
1919use rustc_session:: features:: { StabilityExt , retpoline_features_by_flags} ;
20- use rustc_span:: Symbol ;
2120use rustc_target:: spec:: { MergeFunctions , PanicStrategy , SmallDataThresholdSupport } ;
22- use rustc_target:: target_features:: { RUSTC_SPECIAL_FEATURES , RUSTC_SPECIFIC_FEATURES } ;
21+ use rustc_target:: target_features:: RUSTC_SPECIFIC_FEATURES ;
2322use smallvec:: { SmallVec , smallvec} ;
2423
2524use crate :: back:: write:: create_informational_target_machine;
@@ -343,18 +342,11 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
343342 // the target CPU, that is still expanded to target features (with all their implied features)
344343 // by LLVM.
345344 let target_machine = create_informational_target_machine ( sess, true ) ;
346- // Compute which of the known target features are enabled in the 'base' target machine. We only
347- // consider "supported" features; "forbidden" features are not reflected in `cfg` as of now.
348- let mut features: FxHashSet < Symbol > = sess
349- . target
350- . rust_target_features ( )
351- . iter ( )
352- . filter ( |( feature, _, _) | {
353- // skip checking special features, as LLVM may not understand them
354- if RUSTC_SPECIAL_FEATURES . contains ( feature) {
355- return true ;
356- }
345+
346+ let ( unstable_target_features, target_features) =
347+ target_features:: cfg_target_feature ( sess, & sess. opts . cg . target_feature , |feature| {
357348 if let Some ( feat) = to_llvm_features ( sess, feature) {
349+ // All the LLVM features this expands to must be enabled.
358350 for llvm_feature in feat {
359351 let cstr = SmallCStr :: new ( llvm_feature) ;
360352 // `LLVMRustHasFeature` is moderately expensive. On targets with many
@@ -368,73 +360,8 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
368360 } else {
369361 false
370362 }
371- } )
372- . map ( |( feature, _, _) | Symbol :: intern ( feature) )
373- . collect ( ) ;
374-
375- // Add enabled and remove disabled features.
376- for ( enabled, feature) in
377- sess. opts . cg . target_feature . split ( ',' ) . filter_map ( |s| match s. chars ( ) . next ( ) {
378- Some ( '+' ) => Some ( ( true , Symbol :: intern ( & s[ 1 ..] ) ) ) ,
379- Some ( '-' ) => Some ( ( false , Symbol :: intern ( & s[ 1 ..] ) ) ) ,
380- _ => None ,
381- } )
382- {
383- if enabled {
384- // Also add all transitively implied features.
385-
386- // We don't care about the order in `features` since the only thing we use it for is the
387- // `features.contains` below.
388- #[ allow( rustc:: potential_query_instability) ]
389- features. extend (
390- sess. target
391- . implied_target_features ( feature. as_str ( ) )
392- . iter ( )
393- . map ( |s| Symbol :: intern ( s) ) ,
394- ) ;
395- } else {
396- // Remove transitively reverse-implied features.
397-
398- // We don't care about the order in `features` since the only thing we use it for is the
399- // `features.contains` below.
400- #[ allow( rustc:: potential_query_instability) ]
401- features. retain ( |f| {
402- if sess. target . implied_target_features ( f. as_str ( ) ) . contains ( & feature. as_str ( ) ) {
403- // If `f` if implies `feature`, then `!feature` implies `!f`, so we have to
404- // remove `f`. (This is the standard logical contraposition principle.)
405- false
406- } else {
407- // We can keep `f`.
408- true
409- }
410- } ) ;
411- }
412- }
413-
414- // Filter enabled features based on feature gates.
415- let f = |allow_unstable| {
416- sess. target
417- . rust_target_features ( )
418- . iter ( )
419- . filter_map ( |( feature, gate, _) | {
420- // The `allow_unstable` set is used by rustc internally to determined which target
421- // features are truly available, so we want to return even perma-unstable
422- // "forbidden" features.
423- if allow_unstable
424- || ( gate. in_cfg ( )
425- && ( sess. is_nightly_build ( ) || gate. requires_nightly ( ) . is_none ( ) ) )
426- {
427- Some ( Symbol :: intern ( feature) )
428- } else {
429- None
430- }
431- } )
432- . filter ( |feature| features. contains ( & feature) )
433- . collect ( )
434- } ;
363+ } ) ;
435364
436- let target_features = f ( false ) ;
437- let unstable_target_features = f ( true ) ;
438365 let mut cfg = TargetConfig {
439366 target_features,
440367 unstable_target_features,
0 commit comments