Skip to content

Commit 368b5d2

Browse files
committed
move -Ctarget-feature handling into shared code
1 parent 75d8b1e commit 368b5d2

File tree

17 files changed

+326
-454
lines changed

17 files changed

+326
-454
lines changed
Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
codegen_gcc_unknown_ctarget_feature_prefix =
2-
unknown feature specified for `-Ctarget-feature`: `{$feature}`
3-
.note = features must begin with a `+` to enable or `-` to disable it
4-
51
codegen_gcc_unwinding_inline_asm =
62
GCC backend does not support unwinding from inline asm
73
@@ -16,15 +12,3 @@ codegen_gcc_lto_disallowed = lto can only be run for executables, cdylibs and st
1612
codegen_gcc_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdylib-lto`
1713
1814
codegen_gcc_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$gcc_err})
19-
20-
codegen_gcc_unknown_ctarget_feature =
21-
unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`
22-
.note = it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future
23-
.possible_feature = you might have meant: `{$rust_feature}`
24-
.consider_filing_feature_request = consider filing a feature request
25-
26-
codegen_gcc_missing_features =
27-
add the missing features in a `target_feature` attribute
28-
29-
codegen_gcc_target_feature_disable_or_enable =
30-
the target features {$features} must all be either enabled or disabled together

compiler/rustc_codegen_gcc/src/errors.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,6 @@
1-
use rustc_macros::{Diagnostic, Subdiagnostic};
1+
use rustc_macros::Diagnostic;
22
use rustc_span::Span;
33

4-
#[derive(Diagnostic)]
5-
#[diag(codegen_gcc_unknown_ctarget_feature_prefix)]
6-
#[note]
7-
pub(crate) struct UnknownCTargetFeaturePrefix<'a> {
8-
pub feature: &'a str,
9-
}
10-
11-
#[derive(Diagnostic)]
12-
#[diag(codegen_gcc_unknown_ctarget_feature)]
13-
#[note]
14-
pub(crate) struct UnknownCTargetFeature<'a> {
15-
pub feature: &'a str,
16-
#[subdiagnostic]
17-
pub rust_feature: PossibleFeature<'a>,
18-
}
19-
20-
#[derive(Subdiagnostic)]
21-
pub(crate) enum PossibleFeature<'a> {
22-
#[help(codegen_gcc_possible_feature)]
23-
Some { rust_feature: &'a str },
24-
#[help(codegen_gcc_consider_filing_feature_request)]
25-
None,
26-
}
27-
284
#[derive(Diagnostic)]
295
#[diag(codegen_gcc_unwinding_inline_asm)]
306
pub(crate) struct UnwindingInlineAsm {

compiler/rustc_codegen_gcc/src/gcc_util.rs

Lines changed: 24 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
#[cfg(feature = "master")]
22
use gccjit::Context;
3-
use rustc_codegen_ssa::codegen_attrs::check_tied_features;
4-
use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable;
5-
use rustc_data_structures::fx::FxHashMap;
6-
use rustc_data_structures::unord::UnordSet;
3+
use rustc_codegen_ssa::target_features;
74
use rustc_session::Session;
8-
use rustc_session::features::{StabilityExt, retpoline_features_by_flags};
9-
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
105
use smallvec::{SmallVec, smallvec};
116

12-
use crate::errors::{PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix};
13-
14-
fn gcc_features_by_flags(sess: &Session) -> Vec<&str> {
15-
let mut features: Vec<&str> = Vec::new();
16-
retpoline_features_by_flags(sess, &mut features);
17-
features
7+
fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
8+
target_features::retpoline_features_by_flags(sess, features);
189
}
1910

2011
/// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
@@ -44,98 +35,31 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
4435
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
4536

4637
// -Ctarget-features
47-
let known_features = sess.target.rust_target_features();
48-
let mut featsmap = FxHashMap::default();
49-
50-
// Compute implied features
51-
let mut all_rust_features = vec![];
52-
for feature in sess.opts.cg.target_feature.split(',').chain(gcc_features_by_flags(sess)) {
53-
if let Some(feature) = feature.strip_prefix('+') {
54-
all_rust_features.extend(
55-
UnordSet::from(sess.target.implied_target_features(feature))
56-
.to_sorted_stable_ord()
57-
.iter()
58-
.map(|&&s| (true, s)),
59-
)
60-
} else if let Some(feature) = feature.strip_prefix('-') {
61-
// FIXME: Why do we not remove implied features on "-" here?
62-
// We do the equivalent above in `target_config`.
63-
// See <https://github.com/rust-lang/rust/issues/134792>.
64-
all_rust_features.push((false, feature));
65-
} else if !feature.is_empty() && diagnostics {
66-
sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature });
67-
}
68-
}
69-
// Remove features that are meant for rustc, not codegen.
70-
all_rust_features.retain(|&(_, feature)| {
71-
// Retain if it is not a rustc feature
72-
!RUSTC_SPECIFIC_FEATURES.contains(&feature)
73-
});
74-
75-
// Check feature validity.
76-
if diagnostics {
77-
for &(enable, feature) in &all_rust_features {
78-
let feature_state = known_features.iter().find(|&&(v, _, _)| v == feature);
79-
match feature_state {
80-
None => {
81-
let rust_feature = known_features.iter().find_map(|&(rust_feature, _, _)| {
82-
let gcc_features = to_gcc_features(sess, rust_feature);
83-
if gcc_features.contains(&feature) && !gcc_features.contains(&rust_feature)
84-
{
85-
Some(rust_feature)
86-
} else {
87-
None
88-
}
89-
});
90-
let unknown_feature = if let Some(rust_feature) = rust_feature {
91-
UnknownCTargetFeature {
92-
feature,
93-
rust_feature: PossibleFeature::Some { rust_feature },
94-
}
95-
} else {
96-
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
97-
};
98-
sess.dcx().emit_warn(unknown_feature);
99-
}
100-
Some(&(_, stability, _)) => {
101-
stability.verify_feature_enabled_by_flag(sess, enable, feature);
102-
}
103-
}
104-
105-
// FIXME(nagisa): figure out how to not allocate a full hashset here.
106-
featsmap.insert(feature, enable);
107-
}
108-
}
109-
110-
// Translate this into GCC features.
111-
let feats =
112-
all_rust_features.iter().flat_map(|&(enable, feature)| {
113-
let enable_disable = if enable { '+' } else { '-' };
38+
target_features::flag_to_backend_features(
39+
sess,
40+
diagnostics,
41+
|feature| to_gcc_features(sess, feature),
42+
|feature, enable| {
11443
// We run through `to_gcc_features` when
11544
// passing requests down to GCC. This means that all in-language
11645
// features also work on the command line instead of having two
11746
// different names when the GCC name and the Rust name differ.
118-
to_gcc_features(sess, feature)
119-
.iter()
120-
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
121-
.map(|feature| {
122-
if enable_disable == '-' {
123-
format!("-{}", feature)
124-
} else {
125-
feature.to_string()
126-
}
127-
})
128-
.collect::<Vec<_>>()
129-
});
130-
features.extend(feats);
131-
132-
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
133-
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
134-
features: f,
135-
span: None,
136-
missing_features: None,
137-
});
138-
}
47+
features.extend(
48+
to_gcc_features(sess, feature)
49+
.iter()
50+
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
51+
.map(
52+
|feature| {
53+
if !enable { format!("-{}", feature) } else { feature.to_string() }
54+
},
55+
),
56+
);
57+
},
58+
);
59+
60+
gcc_features_by_flags(sess, &mut features);
61+
62+
// FIXME: LLVM also sets +reserve-x18 here under some conditions.
13963

14064
features
14165
}

compiler/rustc_codegen_llvm/messages.ftl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,6 @@ codegen_llvm_symbol_already_defined =
5959
codegen_llvm_target_machine = could not create LLVM TargetMachine for triple: {$triple}
6060
codegen_llvm_target_machine_with_llvm_err = could not create LLVM TargetMachine for triple: {$triple}: {$llvm_err}
6161
62-
codegen_llvm_unknown_ctarget_feature =
63-
unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`
64-
.note = it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future
65-
.possible_feature = you might have meant: `{$rust_feature}`
66-
.consider_filing_feature_request = consider filing a feature request
67-
68-
codegen_llvm_unknown_ctarget_feature_prefix =
69-
unknown feature specified for `-Ctarget-feature`: `{$feature}`
70-
.note = features must begin with a `+` to enable or `-` to disable it
71-
7262
codegen_llvm_unknown_debuginfo_compression = unknown debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo
7363
7464
codegen_llvm_write_bytecode = failed to write bytecode to {$path}: {$err}

compiler/rustc_codegen_llvm/src/errors.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,11 @@ use std::path::Path;
33

44
use rustc_data_structures::small_c_str::SmallCStr;
55
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
6-
use rustc_macros::{Diagnostic, Subdiagnostic};
6+
use rustc_macros::Diagnostic;
77
use rustc_span::Span;
88

99
use crate::fluent_generated as fluent;
1010

11-
#[derive(Diagnostic)]
12-
#[diag(codegen_llvm_unknown_ctarget_feature_prefix)]
13-
#[note]
14-
pub(crate) struct UnknownCTargetFeaturePrefix<'a> {
15-
pub feature: &'a str,
16-
}
17-
18-
#[derive(Diagnostic)]
19-
#[diag(codegen_llvm_unknown_ctarget_feature)]
20-
#[note]
21-
pub(crate) struct UnknownCTargetFeature<'a> {
22-
pub feature: &'a str,
23-
#[subdiagnostic]
24-
pub rust_feature: PossibleFeature<'a>,
25-
}
26-
27-
#[derive(Subdiagnostic)]
28-
pub(crate) enum PossibleFeature<'a> {
29-
#[help(codegen_llvm_possible_feature)]
30-
Some { rust_feature: &'a str },
31-
#[help(codegen_llvm_consider_filing_feature_request)]
32-
None,
33-
}
34-
3511
#[derive(Diagnostic)]
3612
#[diag(codegen_llvm_symbol_already_defined)]
3713
pub(crate) struct SymbolAlreadyDefined<'a> {

0 commit comments

Comments
 (0)