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:
commit
31719b59c8
4 changed files with 95 additions and 110 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue