Skip to content

Commit 2ca5753

Browse files
authored
Rollup merge of rust-lang#130308 - davidtwco:tied-target-consolidation, r=wesleywiser
codegen_ssa: consolidate tied target checks Fixes rust-lang#105110. Fixes rust-lang#105111. `rustc_codegen_llvm` and `rustc_codegen_gcc` duplicated logic for checking if tied target features were partially enabled. This PR consolidates these checks into `rustc_codegen_ssa` in the `codegen_fn_attrs` query, which also is run pre-monomorphisation for each function, which ensures that this check is run for unused functions, as would be expected. Also adds a test confirming that enabling one tied feature doesn't imply another - the appropriate error for this was already being emitted. I did a bisect and narrowed it down to two patches it was likely to be - something in rust-lang#128796, probably rust-lang#128221 or rust-lang#128679.
2 parents e0bb417 + 73c192b commit 2ca5753

File tree

4 files changed

+5
-80
lines changed

4 files changed

+5
-80
lines changed

messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ codegen_gcc_invalid_minimum_alignment =
88
codegen_gcc_lto_not_supported =
99
LTO is not supported. You may get a linker error.
1010
11-
codegen_gcc_tied_target_features = the target features {$features} must all be either enabled or disabled together
12-
.help = add the missing features in a `target_feature` attribute
13-
1411
codegen_gcc_unwinding_inline_asm =
1512
GCC backend does not support unwinding from inline asm
1613

src/attributes.rs

+2-20
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ use rustc_attr::InstructionSetAttr;
77
#[cfg(feature = "master")]
88
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
99
use rustc_middle::ty;
10-
use rustc_span::symbol::sym;
1110

1211
use crate::context::CodegenCx;
13-
use crate::errors::TiedTargetFeatures;
14-
use crate::gcc_util::{check_tied_features, to_gcc_features};
12+
use crate::gcc_util::to_gcc_features;
1513

1614
/// Get GCC attribute for the provided inline heuristic.
1715
#[cfg(feature = "master")]
@@ -72,26 +70,10 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
7270
}
7371
}
7472

75-
let function_features = codegen_fn_attrs
73+
let mut function_features = codegen_fn_attrs
7674
.target_features
7775
.iter()
7876
.map(|features| features.name.as_str())
79-
.collect::<Vec<&str>>();
80-
81-
if let Some(features) = check_tied_features(
82-
cx.tcx.sess,
83-
&function_features.iter().map(|features| (*features, true)).collect(),
84-
) {
85-
let span = cx
86-
.tcx
87-
.get_attr(instance.def_id(), sym::target_feature)
88-
.map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
89-
cx.tcx.dcx().create_err(TiedTargetFeatures { features: features.join(", "), span }).emit();
90-
return;
91-
}
92-
93-
let mut function_features = function_features
94-
.iter()
9577
.flat_map(|feat| to_gcc_features(cx.tcx.sess, feat).into_iter())
9678
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match *x {
9779
InstructionSetAttr::ArmA32 => "-thumb-mode", // TODO(antoyo): support removing feature.

src/errors.rs

-36
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
21
use rustc_macros::{Diagnostic, Subdiagnostic};
32
use rustc_span::Span;
43

5-
use crate::fluent_generated as fluent;
6-
74
#[derive(Diagnostic)]
85
#[diag(codegen_gcc_unknown_ctarget_feature_prefix)]
96
#[note]
@@ -45,15 +42,6 @@ pub(crate) struct InvalidMinimumAlignment {
4542
pub err: String,
4643
}
4744

48-
#[derive(Diagnostic)]
49-
#[diag(codegen_gcc_tied_target_features)]
50-
#[help]
51-
pub(crate) struct TiedTargetFeatures {
52-
#[primary_span]
53-
pub span: Span,
54-
pub features: String,
55-
}
56-
5745
#[derive(Diagnostic)]
5846
#[diag(codegen_gcc_copy_bitcode)]
5947
pub(crate) struct CopyBitcode {
@@ -78,27 +66,3 @@ pub(crate) struct LtoDylib;
7866
pub(crate) struct LtoBitcodeFromRlib {
7967
pub gcc_err: String,
8068
}
81-
82-
pub(crate) struct TargetFeatureDisableOrEnable<'a> {
83-
pub features: &'a [&'a str],
84-
pub span: Option<Span>,
85-
pub missing_features: Option<MissingFeatures>,
86-
}
87-
88-
#[derive(Subdiagnostic)]
89-
#[help(codegen_gcc_missing_features)]
90-
pub(crate) struct MissingFeatures;
91-
92-
impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> {
93-
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
94-
let mut diag = Diag::new(dcx, level, fluent::codegen_gcc_target_feature_disable_or_enable);
95-
if let Some(span) = self.span {
96-
diag.span(span);
97-
};
98-
if let Some(missing_features) = self.missing_features {
99-
diag.subdiagnostic(missing_features);
100-
}
101-
diag.arg("features", self.features.join(", "));
102-
diag
103-
}
104-
}

src/gcc_util.rs

+3-21
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
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;
35
use rustc_data_structures::fx::FxHashMap;
46
use rustc_middle::bug;
57
use rustc_session::Session;
68
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
79
use smallvec::{SmallVec, smallvec};
810

9-
use crate::errors::{
10-
PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature,
11-
UnknownCTargetFeaturePrefix,
12-
};
11+
use crate::errors::{PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix};
1312

1413
/// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
1514
/// `--target` and similar).
@@ -185,23 +184,6 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
185184
}
186185
}
187186

188-
// Given a map from target_features to whether they are enabled or disabled,
189-
// ensure only valid combinations are allowed.
190-
pub fn check_tied_features(
191-
sess: &Session,
192-
features: &FxHashMap<&str, bool>,
193-
) -> Option<&'static [&'static str]> {
194-
for tied in sess.target.tied_target_features() {
195-
// Tied features must be set to the same value, or not set at all
196-
let mut tied_iter = tied.iter();
197-
let enabled = features.get(tied_iter.next().unwrap());
198-
if tied_iter.any(|feature| enabled != features.get(feature)) {
199-
return Some(tied);
200-
}
201-
}
202-
None
203-
}
204-
205187
fn arch_to_gcc(name: &str) -> &str {
206188
match name {
207189
"M68020" => "68020",

0 commit comments

Comments
 (0)