diff options
| author | bors <bors@rust-lang.org> | 2023-12-15 04:54:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-15 04:54:14 +0000 |
| commit | 1559dd2dbfd42e72ac05b1d23b85ce5ed63f900b (patch) | |
| tree | 1b774224078ee022c8e5197e47cee27ba6c787cd /compiler/rustc_monomorphize/src | |
| parent | 604f185fae9a4b0edf7e28f616a0f53880f8f074 (diff) | |
| parent | e559172249af514ab2c3be6340d557dcbb6347eb (diff) | |
| download | rust-1559dd2dbfd42e72ac05b1d23b85ce5ed63f900b.tar.gz rust-1559dd2dbfd42e72ac05b1d23b85ce5ed63f900b.zip | |
Auto merge of #118770 - saethlin:fix-inline-never-uses, r=nnethercote
Fix cases where std accidentally relied on inline(never) This PR increases the power of `-Zcross-crate-inline-threshold=always` so that it applies through `#[inline(never)]`. Note that though this is called "cross-crate-inlining" in this case especially it is _just_ lazy per-CGU codegen. The MIR inliner and LLVM still respect the attribute as much as they ever have. Trying to bootstrap with the new `-Zcross-crate-inline-threshold=always` change revealed two bugs: We have special intrinsics `assert_inhabited`, `assert_zero_valid`, and `assert_mem_uniniitalized_valid` which codegen backends will lower to nothing or a call to `panic_nounwind`. Since we may not have any call to `panic_nounwind` in MIR but emit one anyway, we need to specially tell `MirUsedCollector` about this situation. `#[lang = "start"]` is special-cased already so that `MirUsedCollector` will collect it, but then when we make it cross-crate-inlinable it is only assigned to a CGU based on whether `MirUsedCollector` saw a call to it, which of course we didn't. --- I started looking into this because https://github.com/rust-lang/rust/pull/118683 revealed a case where we were accidentally relying on a function being `#[inline(never)]`, and cranking up cross-crate-inlinability seems like a way to find other situations like that. r? `@nnethercote` because I don't like what I'm doing to the CGU partitioning code here but I can't come up with something much better
Diffstat (limited to 'compiler/rustc_monomorphize/src')
| -rw-r--r-- | compiler/rustc_monomorphize/src/collector.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_monomorphize/src/partitioning.rs | 12 |
2 files changed, 25 insertions, 3 deletions
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 71b3754fac8..feceff10f95 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -176,6 +176,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Location}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; +use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, AssocKind, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, @@ -923,6 +924,21 @@ fn visit_instance_use<'tcx>( return; } + // The intrinsics assert_inhabited, assert_zero_valid, and assert_mem_uninitialized_valid will + // be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any + // of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to + // codegen a call to that function without generating code for the function itself. + if let ty::InstanceDef::Intrinsic(def_id) = instance.def { + let name = tcx.item_name(def_id); + if let Some(_requirement) = ValidityRequirement::from_intrinsic(name) { + let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap(); + let panic_instance = Instance::mono(tcx, def_id); + if should_codegen_locally(tcx, &panic_instance) { + output.push(create_fn_mono_item(tcx, panic_instance, source)); + } + } + } + match instance.def { ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(_) => { if !is_direct_call { diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index e06935d4e47..d47d3e5e7d3 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -212,11 +212,17 @@ where let cgu_name_cache = &mut FxHashMap::default(); for mono_item in mono_items { - // Handle only root items directly here. Inlined items are handled at - // the bottom of the loop based on reachability. + // Handle only root (GloballyShared) items directly here. Inlined (LocalCopy) items + // are handled at the bottom of the loop based on reachability, with one exception. + // The #[lang = "start"] item is the program entrypoint, so there are no calls to it in MIR. + // So even if its mode is LocalCopy, we need to treat it like a root. match mono_item.instantiation_mode(cx.tcx) { InstantiationMode::GloballyShared { .. } => {} - InstantiationMode::LocalCopy => continue, + InstantiationMode::LocalCopy => { + if Some(mono_item.def_id()) != cx.tcx.lang_items().start_fn() { + continue; + } + } } let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item); |
