diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
commit | 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch) | |
tree | 3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_monomorphize | |
parent | Releasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_monomorphize')
-rw-r--r-- | compiler/rustc_monomorphize/messages.ftl (renamed from compiler/rustc_monomorphize/locales/en-US.ftl) | 0 | ||||
-rw-r--r-- | compiler/rustc_monomorphize/src/collector.rs | 98 | ||||
-rw-r--r-- | compiler/rustc_monomorphize/src/lib.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_monomorphize/src/partitioning/default.rs | 48 | ||||
-rw-r--r-- | compiler/rustc_monomorphize/src/partitioning/merging.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_monomorphize/src/partitioning/mod.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_monomorphize/src/polymorphize.rs | 9 |
7 files changed, 106 insertions, 57 deletions
diff --git a/compiler/rustc_monomorphize/locales/en-US.ftl b/compiler/rustc_monomorphize/messages.ftl index 6cea6a603..6cea6a603 100644 --- a/compiler/rustc_monomorphize/locales/en-US.ftl +++ b/compiler/rustc_monomorphize/messages.ftl diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 45e659eab..7bcff7e07 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -174,7 +174,7 @@ //! regardless of whether it is actually needed or not. use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::{par_for_each_in, MTLock, MTRef}; +use rustc_data_structures::sync::{par_for_each_in, MTLock, MTLockRef}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; @@ -190,7 +190,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{ - self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, VtblEntry, + self, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, + VtblEntry, }; use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; use rustc_session::config::EntryFnType; @@ -340,8 +341,8 @@ pub fn collect_crate_mono_items( let recursion_limit = tcx.recursion_limit(); { - let visited: MTRef<'_, _> = &mut visited; - let inlining_map: MTRef<'_, _> = &mut inlining_map; + let visited: MTLockRef<'_, _> = &mut visited; + let inlining_map: MTLockRef<'_, _> = &mut inlining_map; tcx.sess.time("monomorphization_collector_graph_walk", || { par_for_each_in(roots, |root| { @@ -406,10 +407,10 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem< fn collect_items_rec<'tcx>( tcx: TyCtxt<'tcx>, starting_point: Spanned<MonoItem<'tcx>>, - visited: MTRef<'_, MTLock<FxHashSet<MonoItem<'tcx>>>>, + visited: MTLockRef<'_, FxHashSet<MonoItem<'tcx>>>, recursion_depths: &mut DefIdMap<usize>, recursion_limit: Limit, - inlining_map: MTRef<'_, MTLock<InliningMap<'tcx>>>, + inlining_map: MTLockRef<'_, InliningMap<'tcx>>, ) { if !visited.lock_mut().insert(starting_point.node) { // We've been here already, no need to search again. @@ -462,6 +463,16 @@ fn collect_items_rec<'tcx>( collect_miri(tcx, id, &mut neighbors); } } + + if tcx.needs_thread_local_shim(def_id) { + neighbors.push(respan( + starting_point.span, + MonoItem::Fn(Instance { + def: InstanceDef::ThreadLocalShim(def_id), + substs: InternalSubsts::empty(), + }), + )); + } } MonoItem::Fn(instance) => { // Sanity check whether this ended up being collected accidentally @@ -640,8 +651,8 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); let span = tcx.def_span(instance.def_id()); let mut path = PathBuf::new(); - let was_written = if written_to_path.is_some() { - path = written_to_path.unwrap(); + let was_written = if let Some(path2) = written_to_path { + path = path2; Some(()) } else { None @@ -808,8 +819,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { let callee_ty = self.monomorphize(callee_ty); visit_fn_use(self.tcx, callee_ty, true, source, &mut self.output) } - mir::TerminatorKind::Drop { ref place, .. } - | mir::TerminatorKind::DropAndReplace { ref place, .. } => { + mir::TerminatorKind::Drop { ref place, .. } => { let ty = place.ty(self.body, self.tcx).ty; let ty = self.monomorphize(ty); visit_drop_use(self.tcx, ty, true, source, self.output); @@ -842,7 +852,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.output.push(create_fn_mono_item(tcx, instance, source)); } } - mir::TerminatorKind::Abort { .. } => { + mir::TerminatorKind::Terminate { .. } => { let instance = Instance::mono( tcx, tcx.require_lang_item(LangItem::PanicCannotUnwind, Some(source)), @@ -862,6 +872,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { | mir::TerminatorKind::FalseUnwind { .. } => bug!(), } + if let Some(mir::UnwindAction::Terminate) = terminator.unwind() { + let instance = Instance::mono( + tcx, + tcx.require_lang_item(LangItem::PanicCannotUnwind, Some(source)), + ); + if should_codegen_locally(tcx, &instance) { + self.output.push(create_fn_mono_item(tcx, instance, source)); + } + } + self.super_terminator(terminator, location); } @@ -963,6 +983,9 @@ fn visit_instance_use<'tcx>( bug!("{:?} being reified", instance); } } + ty::InstanceDef::ThreadLocalShim(..) => { + bug!("{:?} being reified", instance); + } ty::InstanceDef::DropGlue(_, None) => { // Don't need to emit noop drop glue if we are calling directly. if !is_direct_call { @@ -975,7 +998,8 @@ fn visit_instance_use<'tcx>( | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Item(..) | ty::InstanceDef::FnPtrShim(..) - | ty::InstanceDef::CloneShim(..) => { + | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::FnPtrAddrShim(..) => { output.push(create_fn_mono_item(tcx, instance, source)); } } @@ -1105,7 +1129,8 @@ fn find_vtable_types_for_unsizing<'tcx>( let target_fields = &target_adt_def.non_enum_variant().fields; assert!( - coerce_index < source_fields.len() && source_fields.len() == target_fields.len() + coerce_index.index() < source_fields.len() + && source_fields.len() == target_fields.len() ); find_vtable_types_for_unsizing( @@ -1210,11 +1235,9 @@ impl<'v> RootCollector<'_, 'v> { self.output.push(dummy_spanned(MonoItem::GlobalAsm(id))); } DefKind::Static(..) => { - debug!( - "RootCollector: ItemKind::Static({})", - self.tcx.def_path_str(id.owner_id.to_def_id()) - ); - self.output.push(dummy_spanned(MonoItem::Static(id.owner_id.to_def_id()))); + let def_id = id.owner_id.to_def_id(); + debug!("RootCollector: ItemKind::Static({})", self.tcx.def_path_str(def_id)); + self.output.push(dummy_spanned(MonoItem::Static(def_id))); } DefKind::Const => { // const items only generate mono items if they are @@ -1331,7 +1354,35 @@ fn create_mono_items_for_default_impls<'tcx>( return; }; - let trait_ref = trait_ref.subst_identity(); + // Lifetimes never affect trait selection, so we are allowed to eagerly + // instantiate an instance of an impl method if the impl (and method, + // which we check below) is only parameterized over lifetime. In that case, + // we use the ReErased, which has no lifetime information associated with + // it, to validate whether or not the impl is legal to instantiate at all. + let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind { + GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { + unreachable!( + "`own_requires_monomorphization` check means that \ + we should have no type/const params" + ) + } + }; + let impl_substs = InternalSubsts::for_item(tcx, item.owner_id.to_def_id(), only_region_params); + let trait_ref = trait_ref.subst(tcx, impl_substs); + + // Unlike 'lazy' monomorphization that begins by collecting items transitively + // called by `main` or other global items, when eagerly monomorphizing impl + // items, we never actually check that the predicates of this impl are satisfied + // in a empty reveal-all param env (i.e. with no assumptions). + // + // Even though this impl has no type or const substitutions, because we don't + // consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to + // be trivially false. We must now check that the impl has no impossible-to-satisfy + // predicates. + if tcx.subst_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_substs)) { + return; + } let param_env = ty::ParamEnv::reveal_all(); let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); @@ -1345,12 +1396,9 @@ fn create_mono_items_for_default_impls<'tcx>( continue; } - let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { - trait_ref.substs[param.index as usize] - } - }); + // As mentioned above, the method is legal to eagerly instantiate if it + // only has lifetime substitutions. This is validated by + let substs = trait_ref.substs.extend_to(tcx, method.def_id, only_region_params); let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, substs); let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index f6b791f29..5000fb719 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -23,7 +23,7 @@ mod partitioning; mod polymorphize; mod util; -fluent_messages! { "../locales/en-US.ftl" } +fluent_messages! { "../messages.ftl" } fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxtAt<'tcx>, diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 2c56edd89..482b78d42 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -9,7 +9,7 @@ use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::ty::print::characteristic_def_id_of_type; -use rustc_middle::ty::{self, visit::TypeVisitableExt, DefIdTree, InstanceDef, TyCtxt}; +use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt}; use rustc_span::symbol::Symbol; use super::PartitioningCx; @@ -89,10 +89,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { } PreInliningPartitioning { - codegen_units: codegen_units - .into_iter() - .map(|(_, codegen_unit)| codegen_unit) - .collect(), + codegen_units: codegen_units.into_values().map(|codegen_unit| codegen_unit).collect(), roots, internalization_candidates, } @@ -278,7 +275,9 @@ fn characteristic_def_id_of_mono_item<'tcx>( | ty::InstanceDef::Intrinsic(..) | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::Virtual(..) - | ty::InstanceDef::CloneShim(..) => return None, + | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::ThreadLocalShim(..) + | ty::InstanceDef::FnPtrAddrShim(..) => return None, }; // If this is a method, we want to put it into the same module as @@ -391,6 +390,19 @@ fn mono_item_linkage_and_visibility<'tcx>( type CguNameCache = FxHashMap<(DefId, bool), Symbol>; +fn static_visibility<'tcx>( + tcx: TyCtxt<'tcx>, + can_be_internalized: &mut bool, + def_id: DefId, +) -> Visibility { + if tcx.is_reachable_non_generic(def_id) { + *can_be_internalized = false; + default_visibility(tcx, def_id, false) + } else { + Visibility::Hidden + } +} + fn mono_item_visibility<'tcx>( tcx: TyCtxt<'tcx>, mono_item: &MonoItem<'tcx>, @@ -402,21 +414,9 @@ fn mono_item_visibility<'tcx>( MonoItem::Fn(instance) => instance, // Misc handling for generics and such, but otherwise: - MonoItem::Static(def_id) => { - return if tcx.is_reachable_non_generic(*def_id) { - *can_be_internalized = false; - default_visibility(tcx, *def_id, false) - } else { - Visibility::Hidden - }; - } + MonoItem::Static(def_id) => return static_visibility(tcx, can_be_internalized, *def_id), MonoItem::GlobalAsm(item_id) => { - return if tcx.is_reachable_non_generic(item_id.owner_id) { - *can_be_internalized = false; - default_visibility(tcx, item_id.owner_id.to_def_id(), false) - } else { - Visibility::Hidden - }; + return static_visibility(tcx, can_be_internalized, item_id.owner_id.to_def_id()); } }; @@ -424,6 +424,11 @@ fn mono_item_visibility<'tcx>( InstanceDef::Item(def) => def.did, InstanceDef::DropGlue(def_id, Some(_)) => def_id, + // We match the visiblity of statics here + InstanceDef::ThreadLocalShim(def_id) => { + return static_visibility(tcx, can_be_internalized, def_id); + } + // These are all compiler glue and such, never exported, always hidden. InstanceDef::VTableShim(..) | InstanceDef::ReifyShim(..) @@ -432,7 +437,8 @@ fn mono_item_visibility<'tcx>( | InstanceDef::Intrinsic(..) | InstanceDef::ClosureOnceShim { .. } | InstanceDef::DropGlue(..) - | InstanceDef::CloneShim(..) => return Visibility::Hidden, + | InstanceDef::CloneShim(..) + | InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden, }; // The `start_fn` lang item is actually a monomorphized instance of a diff --git a/compiler/rustc_monomorphize/src/partitioning/merging.rs b/compiler/rustc_monomorphize/src/partitioning/merging.rs index 02bb8dea0..5c524a184 100644 --- a/compiler/rustc_monomorphize/src/partitioning/merging.rs +++ b/compiler/rustc_monomorphize/src/partitioning/merging.rs @@ -24,7 +24,7 @@ pub fn merge_codegen_units<'tcx>( // smallest into each other) we're sure to start off with a deterministic // order (sorted by name). This'll mean that if two cgus have the same size // the stable sort below will keep everything nice and deterministic. - codegen_units.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap()); + codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str())); // This map keeps track of what got merged into what. let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> = diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 524c51d88..18aa0742c 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -252,7 +252,7 @@ pub fn partition<'tcx>( internalization_candidates: _, } = post_inlining; - result.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap()); + result.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str())); result } @@ -474,7 +474,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co (tcx.arena.alloc(mono_items), codegen_units) } -/// Outputs stats about instantation counts and estimated size, per `MonoItem`'s +/// Outputs stats about instantiation counts and estimated size, per `MonoItem`'s /// def, to a file in the given output directory. fn dump_mono_items_stats<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index b7c3dbcc0..63263a642 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -36,6 +36,8 @@ fn unused_generic_params<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>, ) -> UnusedGenericParams { + assert!(instance.def_id().is_local()); + if !tcx.sess.opts.unstable_opts.polymorphize { // If polymorphization disabled, then all parameters are used. return UnusedGenericParams::new_all_used(); @@ -100,13 +102,6 @@ fn should_polymorphize<'tcx>( return false; } - // Polymorphization results are stored in cross-crate metadata only when there are unused - // parameters, so assume that non-local items must have only used parameters (else this query - // would not be invoked, and the cross-crate metadata used instead). - if !def_id.is_local() { - return false; - } - // Foreign items have no bodies to analyze. if tcx.is_foreign_item(def_id) { return false; |