diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index 8456abc8d269..d107aa36d86e 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -38,12 +38,10 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut any_replacement = false; // Locals that participate in copy propagation either as a source or a destination. let mut unified = DenseBitSet::new_empty(body.local_decls.len()); - let mut storage_to_remove = DenseBitSet::new_empty(body.local_decls.len()); for (local, &head) in ssa.copy_classes().iter_enumerated() { if local != head { any_replacement = true; - storage_to_remove.insert(head); unified.insert(head); unified.insert(local); } @@ -58,7 +56,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // only if the head might be uninitialized at that point, or if the local is borrowed // (since we cannot easily determine when it's used). let storage_to_remove = if tcx.sess.emit_lifetime_markers() { - storage_to_remove.clear(); + let mut storage_to_remove = DenseBitSet::new_empty(body.local_decls.len()); // If the local is borrowed, we cannot easily determine if it is used, so we have to remove the storage statements. let borrowed_locals = ssa.borrowed_locals(); @@ -83,15 +81,16 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { storage_checker.visit_basic_block_data(bb, data); } - storage_checker.storage_to_remove + Some(storage_checker.storage_to_remove) } else { - // Remove the storage statements of all the head locals. - storage_to_remove + None }; + // If None, remove the storage statements of all the unified locals. + let storage_to_remove = storage_to_remove.as_ref().unwrap_or(&unified); debug!(?storage_to_remove); - Replacer { tcx, copy_classes: ssa.copy_classes(), unified, storage_to_remove } + Replacer { tcx, copy_classes: ssa.copy_classes(), unified: &unified, storage_to_remove } .visit_body_preserves_cfg(body); crate::simplify::remove_unused_definitions(body); @@ -106,8 +105,8 @@ fn is_required(&self) -> bool { /// all occurrences of the key get replaced by the value. struct Replacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, - unified: DenseBitSet, - storage_to_remove: DenseBitSet, + unified: &'a DenseBitSet, + storage_to_remove: &'a DenseBitSet, copy_classes: &'a IndexSlice, } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index d9f5768e6079..5324c39e9f22 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -173,15 +173,16 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { storage_checker.visit_basic_block_data(bb, data); } - storage_checker.storage_to_remove + Some(storage_checker.storage_to_remove) } else { - // Remove the storage statements of all the reused locals. - state.reused_locals.clone() + None }; + // If None, remove the storage statements of all the reused locals. + let storage_to_remove = storage_to_remove.as_ref().unwrap_or(&state.reused_locals); debug!(?storage_to_remove); - StorageRemover { tcx, reused_locals: state.reused_locals, storage_to_remove } + StorageRemover { tcx, reused_locals: &state.reused_locals, storage_to_remove } .visit_body_preserves_cfg(body); } @@ -2058,13 +2059,13 @@ fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Loca } } -struct StorageRemover<'tcx> { +struct StorageRemover<'a, 'tcx> { tcx: TyCtxt<'tcx>, - reused_locals: DenseBitSet, - storage_to_remove: DenseBitSet, + reused_locals: &'a DenseBitSet, + storage_to_remove: &'a DenseBitSet, } -impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> { +impl<'a, 'tcx> MutVisitor<'tcx> for StorageRemover<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 6f9795fb3bff..05914f4199ae 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -109,6 +109,7 @@ use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; +use rustc_middle::mir::StatementKind; use rustc_middle::mono::{ CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, MonoItem, MonoItemData, MonoItemPartitions, Visibility, @@ -1334,7 +1335,21 @@ pub(crate) fn provide(providers: &mut Providers) { | InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) => { let mir = tcx.instance_mir(instance.def); - mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum() + mir.basic_blocks + .iter() + .map(|bb| { + bb.statements + .iter() + .filter_map(|stmt| match stmt.kind { + StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => { + None + } + _ => Some(stmt), + }) + .count() + + 1 + }) + .sum() } // Other compiler-generated shims size estimate: 1 _ => 1,