diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 5ccdb4be62461..f5f00c9343561 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -194,7 +194,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_index::bit_set::GrowableBitSet; - +use smallvec::SmallVec; use std::iter; #[derive(PartialEq)] @@ -227,12 +227,7 @@ impl<'tcx> InliningMap<'tcx> { } } - fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: I) - where - I: Iterator, bool)> + ExactSizeIterator, - { - assert!(!self.index.contains_key(&source)); - + fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: &[(MonoItem<'tcx>, bool)]) { let start_index = self.targets.len(); let new_items_count = new_targets.len(); let new_items_count_total = new_items_count + self.targets.len(); @@ -240,15 +235,15 @@ impl<'tcx> InliningMap<'tcx> { self.targets.reserve(new_items_count); self.inlines.ensure(new_items_count_total); - for (i, (target, inline)) in new_targets.enumerate() { - self.targets.push(target); - if inline { + for (i, (target, inline)) in new_targets.iter().enumerate() { + self.targets.push(*target); + if *inline { self.inlines.insert(i + start_index); } } let end_index = self.targets.len(); - self.index.insert(source, (start_index, end_index)); + assert!(self.index.insert(source, (start_index, end_index)).is_none()); } // Internally iterate over all items referenced by `source` which will be @@ -403,10 +398,15 @@ fn record_accesses<'tcx>( mono_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy }; - let accesses = - callees.into_iter().map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))); + // We collect this into a `SmallVec` to avoid calling `is_inlining_candidate` in the lock. + // FIXME: Call `is_inlining_candidate` when pushing to `neighbors` in `collect_items_rec` + // instead to avoid creating this `SmallVec`. + let accesses: SmallVec<[_; 128]> = callees + .into_iter() + .map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))) + .collect(); - inlining_map.lock_mut().record_accesses(caller, accesses); + inlining_map.lock_mut().record_accesses(caller, &accesses); } fn check_recursion_limit<'tcx>( diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 8fa41cab19076..0def51a6a33e5 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -104,6 +104,7 @@ use rustc::ty::print::characteristic_def_id_of_type; use rustc::ty::query::Providers; use rustc::ty::{self, DefIdTree, InstanceDef, TyCtxt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::sync; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_span::symbol::Symbol; @@ -796,6 +797,8 @@ where I: Iterator>, 'tcx: 'a, { + let _prof_timer = tcx.prof.generic_activity("assert_symbols_are_distinct"); + let mut symbols: Vec<_> = mono_items.map(|mono_item| (mono_item, mono_item.symbol_name(tcx))).collect(); @@ -869,18 +872,23 @@ fn collect_and_partition_mono_items( tcx.sess.abort_if_errors(); - assert_symbols_are_distinct(tcx, items.iter()); - - let strategy = if tcx.sess.opts.incremental.is_some() { - PartitioningStrategy::PerModule - } else { - PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units()) - }; - - let codegen_units = partition(tcx, items.iter().cloned(), strategy, &inlining_map) - .into_iter() - .map(Arc::new) - .collect::>(); + let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || { + sync::join( + || { + let strategy = if tcx.sess.opts.incremental.is_some() { + PartitioningStrategy::PerModule + } else { + PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units()) + }; + + partition(tcx, items.iter().cloned(), strategy, &inlining_map) + .into_iter() + .map(Arc::new) + .collect::>() + }, + || assert_symbols_are_distinct(tcx, items.iter()), + ) + }); let mono_items: DefIdSet = items .iter()