1
Fork 0

Rollup merge of #136439 - yotamofek:pr/codegen-ssa-no-indexing, r=Noratrieb

Misc. `rustc_codegen_ssa` cleanups 🧹

Just a bunch of stuff I found while reading the crate's code.
Each commit can stand on its own.
Maybe r? `@Noratrieb` because I saw you did some similar cleanups on these files a while ago? (feel free to re-assign, I'm just guessing)
This commit is contained in:
Trevor Gross 2025-02-23 14:30:24 -05:00 committed by GitHub
commit 31719b59c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 95 additions and 110 deletions

View file

@ -244,22 +244,17 @@ pub fn each_linked_rlib(
fmts fmts
} else { } else {
for combination in info.dependency_formats.iter().combinations(2) { let mut dep_formats = info.dependency_formats.iter();
let (ty1, list1) = &combination[0]; let (ty1, list1) = dep_formats.next().ok_or(errors::LinkRlibError::MissingFormat)?;
let (ty2, list2) = &combination[1]; if let Some((ty2, list2)) = dep_formats.find(|(_, list2)| list1 != *list2) {
if list1 != list2 { return Err(errors::LinkRlibError::IncompatibleDependencyFormats {
return Err(errors::LinkRlibError::IncompatibleDependencyFormats { ty1: format!("{ty1:?}"),
ty1: format!("{ty1:?}"), ty2: format!("{ty2:?}"),
ty2: format!("{ty2:?}"), list1: format!("{list1:?}"),
list1: format!("{list1:?}"), list2: format!("{list2:?}"),
list2: format!("{list2:?}"), });
});
}
} }
if info.dependency_formats.is_empty() { list1
return Err(errors::LinkRlibError::MissingFormat);
}
info.dependency_formats.first().unwrap().1
}; };
let used_dep_crates = info.used_crates.iter(); let used_dep_crates = info.used_crates.iter();
@ -626,10 +621,9 @@ fn link_staticlib(
let mut all_rust_dylibs = vec![]; let mut all_rust_dylibs = vec![];
for &cnum in crates { for &cnum in crates {
match fmts.get(cnum) { let Some(Linkage::Dynamic) = fmts.get(cnum) else {
Some(&Linkage::Dynamic) => {} continue;
_ => continue, };
}
let crate_name = codegen_results.crate_info.crate_name[&cnum]; let crate_name = codegen_results.crate_info.crate_name[&cnum];
let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
if let Some((path, _)) = &used_crate_source.dylib { if let Some((path, _)) = &used_crate_source.dylib {

View file

@ -573,10 +573,10 @@ fn produce_final_output_artifacts(
}; };
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
if compiled_modules.modules.len() == 1 { if let [module] = &compiled_modules.modules[..] {
// 1) Only one codegen unit. In this case it's no difficulty // 1) Only one codegen unit. In this case it's no difficulty
// to copy `foo.0.x` to `foo.x`. // to copy `foo.0.x` to `foo.x`.
let module_name = Some(&compiled_modules.modules[0].name[..]); let module_name = Some(&module.name[..]);
let path = crate_output.temp_path(output_type, module_name); let path = crate_output.temp_path(output_type, module_name);
let output = crate_output.path(output_type); let output = crate_output.path(output_type);
if !output_type.is_text_output() && output.is_tty() { if !output_type.is_text_output() && output.is_tty() {
@ -708,8 +708,8 @@ fn produce_final_output_artifacts(
} }
if sess.opts.json_artifact_notifications { if sess.opts.json_artifact_notifications {
if compiled_modules.modules.len() == 1 { if let [module] = &compiled_modules.modules[..] {
compiled_modules.modules[0].for_each_output(|_path, ty| { module.for_each_output(|_path, ty| {
if sess.opts.output_types.contains_key(&ty) { if sess.opts.output_types.contains_key(&ty) {
let descr = ty.shorthand(); let descr = ty.shorthand();
// for single cgu file is renamed to drop cgu specific suffix // for single cgu file is renamed to drop cgu specific suffix
@ -865,7 +865,7 @@ pub(crate) fn compute_per_cgu_lto_type(
// require LTO so the request for LTO is always unconditionally // require LTO so the request for LTO is always unconditionally
// passed down to the backend, but we don't actually want to do // passed down to the backend, but we don't actually want to do
// anything about it yet until we've got a final product. // anything about it yet until we've got a final product.
let is_rlib = sess_crate_types.len() == 1 && sess_crate_types[0] == CrateType::Rlib; let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]);
match sess_lto { match sess_lto {
Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin, Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin,
@ -1538,8 +1538,9 @@ fn start_executing_work<B: ExtraBackendMethods>(
// Spin up what work we can, only doing this while we've got available // Spin up what work we can, only doing this while we've got available
// parallelism slots and work left to spawn. // parallelism slots and work left to spawn.
if codegen_state != Aborted { if codegen_state != Aborted {
while !work_items.is_empty() && running_with_own_token < tokens.len() { while running_with_own_token < tokens.len()
let (item, _) = work_items.pop().unwrap(); && let Some((item, _)) = work_items.pop()
{
spawn_work( spawn_work(
&cgcx, &cgcx,
&mut llvm_start_time, &mut llvm_start_time,

View file

@ -1,7 +1,6 @@
use std::str::FromStr; use std::str::FromStr;
use rustc_abi::ExternAbi; use rustc_abi::ExternAbi;
use rustc_ast::attr::list_contains_name;
use rustc_ast::expand::autodiff_attrs::{ use rustc_ast::expand::autodiff_attrs::{
AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity,
}; };
@ -377,24 +376,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
let segments = let segments =
set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>(); set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>();
match segments.as_slice() { match segments.as_slice() {
[sym::arm, sym::a32] | [sym::arm, sym::t32] => { [sym::arm, sym::a32 | sym::t32]
if !tcx.sess.target.has_thumb_interworking { if !tcx.sess.target.has_thumb_interworking =>
struct_span_code_err!( {
tcx.dcx(), struct_span_code_err!(
attr.span, tcx.dcx(),
E0779, attr.span,
"target does not support `#[instruction_set]`" E0779,
) "target does not support `#[instruction_set]`"
.emit(); )
None .emit();
} else if segments[1] == sym::a32 { None
Some(InstructionSetAttr::ArmA32)
} else if segments[1] == sym::t32 {
Some(InstructionSetAttr::ArmT32)
} else {
unreachable!()
}
} }
[sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32),
[sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32),
_ => { _ => {
struct_span_code_err!( struct_span_code_err!(
tcx.dcx(), tcx.dcx(),
@ -435,7 +430,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
&& let Some((sym::align, literal)) = item.singleton_lit_list() && let Some((sym::align, literal)) = item.singleton_lit_list()
{ {
rustc_attr_parsing::parse_alignment(&literal.kind) rustc_attr_parsing::parse_alignment(&literal.kind)
.map_err(|msg| { .inspect_err(|msg| {
struct_span_code_err!( struct_span_code_err!(
tcx.dcx(), tcx.dcx(),
literal.span, literal.span,
@ -536,25 +531,27 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
} }
if attr.is_word() { if attr.is_word() {
InlineAttr::Hint return InlineAttr::Hint;
} else if let Some(ref items) = attr.meta_item_list() { }
inline_span = Some(attr.span); let Some(ref items) = attr.meta_item_list() else {
if items.len() != 1 { return ia;
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit(); };
InlineAttr::None
} else if list_contains_name(items, sym::always) {
InlineAttr::Always
} else if list_contains_name(items, sym::never) {
InlineAttr::Never
} else {
struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
.with_help("valid inline arguments are `always` and `never`")
.emit();
InlineAttr::None inline_span = Some(attr.span);
} let [item] = &items[..] else {
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit();
return InlineAttr::None;
};
if item.has_name(sym::always) {
InlineAttr::Always
} else if item.has_name(sym::never) {
InlineAttr::Never
} else { } else {
ia struct_span_code_err!(tcx.dcx(), item.span(), E0535, "invalid argument")
.with_help("valid inline arguments are `always` and `never`")
.emit();
InlineAttr::None
} }
}); });
codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| { codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| {
@ -586,23 +583,25 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit();
if attr.is_word() { if attr.is_word() {
err(attr.span, "expected one argument"); err(attr.span, "expected one argument");
ia return ia;
} else if let Some(ref items) = attr.meta_item_list() { }
inline_span = Some(attr.span); let Some(ref items) = attr.meta_item_list() else {
if items.len() != 1 { return OptimizeAttr::Default;
err(attr.span, "expected one argument"); };
OptimizeAttr::Default
} else if list_contains_name(items, sym::size) { inline_span = Some(attr.span);
OptimizeAttr::Size let [item] = &items[..] else {
} else if list_contains_name(items, sym::speed) { err(attr.span, "expected one argument");
OptimizeAttr::Speed return OptimizeAttr::Default;
} else if list_contains_name(items, sym::none) { };
OptimizeAttr::DoNotOptimize if item.has_name(sym::size) {
} else { OptimizeAttr::Size
err(items[0].span(), "invalid argument"); } else if item.has_name(sym::speed) {
OptimizeAttr::Default OptimizeAttr::Speed
} } else if item.has_name(sym::none) {
OptimizeAttr::DoNotOptimize
} else { } else {
err(item.span(), "invalid argument");
OptimizeAttr::Default OptimizeAttr::Default
} }
}); });
@ -644,25 +643,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// llvm/llvm-project#70563). // llvm/llvm-project#70563).
if !codegen_fn_attrs.target_features.is_empty() if !codegen_fn_attrs.target_features.is_empty()
&& matches!(codegen_fn_attrs.inline, InlineAttr::Always) && matches!(codegen_fn_attrs.inline, InlineAttr::Always)
&& let Some(span) = inline_span
{ {
if let Some(span) = inline_span { tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`");
tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`");
}
} }
if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline.always() { if !codegen_fn_attrs.no_sanitize.is_empty()
if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) { && codegen_fn_attrs.inline.always()
let hir_id = tcx.local_def_id_to_hir_id(did); && let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span)
tcx.node_span_lint( {
lint::builtin::INLINE_NO_SANITIZE, let hir_id = tcx.local_def_id_to_hir_id(did);
hir_id, tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| {
no_sanitize_span, lint.primary_message("`no_sanitize` will have no effect after inlining");
|lint| { lint.span_note(inline_span, "inlining requested here");
lint.primary_message("`no_sanitize` will have no effect after inlining"); })
lint.span_note(inline_span, "inlining requested here");
},
)
}
} }
// Weak lang items have the same semantics as "std internal" symbols in the // Weak lang items have the same semantics as "std internal" symbols in the
@ -692,10 +686,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// Any linkage to LLVM intrinsics for now forcibly marks them all as never // Any linkage to LLVM intrinsics for now forcibly marks them all as never
// unwinds since LLVM sometimes can't handle codegen which `invoke`s // unwinds since LLVM sometimes can't handle codegen which `invoke`s
// intrinsic functions. // intrinsic functions.
if let Some(name) = &codegen_fn_attrs.link_name { if let Some(name) = &codegen_fn_attrs.link_name
if name.as_str().starts_with("llvm.") { && name.as_str().starts_with("llvm.")
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; {
} codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
} }
if let Some(features) = check_tied_features( if let Some(features) = check_tied_features(
@ -756,18 +750,13 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> { fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
use rustc_ast::{LitIntType, LitKind, MetaItemLit}; use rustc_ast::{LitIntType, LitKind, MetaItemLit};
let meta_item_list = attr.meta_item_list(); let meta_item_list = attr.meta_item_list()?;
let meta_item_list = meta_item_list.as_deref(); let [sole_meta_list] = &meta_item_list[..] else {
let sole_meta_list = match meta_item_list { tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span });
Some([item]) => item.lit(), return None;
Some(_) => {
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span });
return None;
}
_ => None,
}; };
if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
sole_meta_list sole_meta_list.lit()
{ {
// According to the table at // According to the table at
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the

View file

@ -1003,8 +1003,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let destination = target.map(|target| (return_dest, target)); let destination = target.map(|target| (return_dest, target));
// Split the rust-call tupled arguments off. // Split the rust-call tupled arguments off.
let (first_args, untuple) = if abi == ExternAbi::RustCall && !args.is_empty() { let (first_args, untuple) = if abi == ExternAbi::RustCall
let (tup, args) = args.split_last().unwrap(); && let Some((tup, args)) = args.split_last()
{
(args, Some(tup)) (args, Some(tup))
} else { } else {
(args, None) (args, None)