@@ -6,19 +6,18 @@ 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 ;
1515use rustc_fs_util:: path_to_c_string;
1616use rustc_middle:: bug;
1717use rustc_session:: Session ;
1818use rustc_session:: config:: { PrintKind , PrintRequest } ;
19- use rustc_span:: Symbol ;
2019use rustc_target:: spec:: { MergeFunctions , PanicStrategy , SmallDataThresholdSupport } ;
21- use rustc_target:: target_features:: { RUSTC_SPECIAL_FEATURES , RUSTC_SPECIFIC_FEATURES } ;
20+ use rustc_target:: target_features:: RUSTC_SPECIFIC_FEATURES ;
2221use smallvec:: { SmallVec , smallvec} ;
2322
2423use crate :: back:: write:: create_informational_target_machine;
@@ -335,18 +334,11 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
335334 // the target CPU, that is still expanded to target features (with all their implied features)
336335 // by LLVM.
337336 let target_machine = create_informational_target_machine ( sess, true ) ;
338- // Compute which of the known target features are enabled in the 'base' target machine. We only
339- // consider "supported" features; "forbidden" features are not reflected in `cfg` as of now.
340- let mut features: FxHashSet < Symbol > = sess
341- . target
342- . rust_target_features ( )
343- . iter ( )
344- . filter ( |( feature, _, _) | {
345- // skip checking special features, as LLVM may not understand them
346- if RUSTC_SPECIAL_FEATURES . contains ( feature) {
347- return true ;
348- }
337+
338+ let ( unstable_target_features, target_features) =
339+ target_features:: cfg_target_feature ( sess, & sess. opts . cg . target_feature , |feature| {
349340 if let Some ( feat) = to_llvm_features ( sess, feature) {
341+ // All the LLVM features this expands to must be enabled.
350342 for llvm_feature in feat {
351343 let cstr = SmallCStr :: new ( llvm_feature) ;
352344 // `LLVMRustHasFeature` is moderately expensive. On targets with many
@@ -360,73 +352,8 @@ pub(crate) fn target_config(sess: &Session) -> TargetConfig {
360352 } else {
361353 false
362354 }
363- } )
364- . map ( |( feature, _, _) | Symbol :: intern ( feature) )
365- . collect ( ) ;
366-
367- // Add enabled and remove disabled features.
368- for ( enabled, feature) in
369- sess. opts . cg . target_feature . split ( ',' ) . filter_map ( |s| match s. chars ( ) . next ( ) {
370- Some ( '+' ) => Some ( ( true , Symbol :: intern ( & s[ 1 ..] ) ) ) ,
371- Some ( '-' ) => Some ( ( false , Symbol :: intern ( & s[ 1 ..] ) ) ) ,
372- _ => None ,
373- } )
374- {
375- if enabled {
376- // Also add all transitively implied features.
377-
378- // We don't care about the order in `features` since the only thing we use it for is the
379- // `features.contains` below.
380- #[ allow( rustc:: potential_query_instability) ]
381- features. extend (
382- sess. target
383- . implied_target_features ( feature. as_str ( ) )
384- . iter ( )
385- . map ( |s| Symbol :: intern ( s) ) ,
386- ) ;
387- } else {
388- // Remove transitively reverse-implied features.
389-
390- // We don't care about the order in `features` since the only thing we use it for is the
391- // `features.contains` below.
392- #[ allow( rustc:: potential_query_instability) ]
393- features. retain ( |f| {
394- if sess. target . implied_target_features ( f. as_str ( ) ) . contains ( & feature. as_str ( ) ) {
395- // If `f` if implies `feature`, then `!feature` implies `!f`, so we have to
396- // remove `f`. (This is the standard logical contraposition principle.)
397- false
398- } else {
399- // We can keep `f`.
400- true
401- }
402- } ) ;
403- }
404- }
405-
406- // Filter enabled features based on feature gates.
407- let f = |allow_unstable| {
408- sess. target
409- . rust_target_features ( )
410- . iter ( )
411- . filter_map ( |( feature, gate, _) | {
412- // The `allow_unstable` set is used by rustc internally to determined which target
413- // features are truly available, so we want to return even perma-unstable
414- // "forbidden" features.
415- if allow_unstable
416- || ( gate. in_cfg ( )
417- && ( sess. is_nightly_build ( ) || gate. requires_nightly ( ) . is_none ( ) ) )
418- {
419- Some ( Symbol :: intern ( feature) )
420- } else {
421- None
422- }
423- } )
424- . filter ( |feature| features. contains ( & feature) )
425- . collect ( )
426- } ;
355+ } ) ;
427356
428- let target_features = f ( false ) ;
429- let unstable_target_features = f ( true ) ;
430357 let mut cfg = TargetConfig {
431358 target_features,
432359 unstable_target_features,
0 commit comments