use crate::monomorphize;
-use rustc::hir;
-use rustc::hir::def_id::{DefId, DefIdMap, LOCAL_CRATE};
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
use rustc::mir::interpret::{AllocId, ConstValue};
use rustc::ty::print::obsolete::DefPathBasedNames;
use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable};
-use rustc::util::common::time;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
+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)]
}
}
- fn record_accesses<I>(&mut self, source: MonoItem<'tcx>, new_targets: I)
- where
- I: Iterator<Item = (MonoItem<'tcx>, 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();
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
) -> (FxHashSet<MonoItem<'_>>, InliningMap<'_>) {
let _prof_timer = tcx.prof.generic_activity("monomorphization_collector");
- let roots = time(tcx.sess, "collecting roots", || {
- let _prof_timer = tcx.prof.generic_activity("monomorphization_collector_root_collections");
- collect_roots(tcx, mode)
- });
+ let roots =
+ tcx.sess.time("monomorphization_collector_root_collections", || collect_roots(tcx, mode));
debug!("building mono item graph, beginning at roots");
let mut inlining_map = MTLock::new(InliningMap::new());
{
- let _prof_timer = tcx.prof.generic_activity("monomorphization_collector_graph_walk");
-
let visited: MTRef<'_, _> = &mut visited;
let inlining_map: MTRef<'_, _> = &mut inlining_map;
- time(tcx.sess, "collecting mono items", || {
+ tcx.sess.time("monomorphization_collector_graph_walk", || {
par_iter(roots).for_each(|root| {
let mut recursion_depths = DefIdMap::default();
collect_items_rec(tcx, root, visited, &mut recursion_depths, inlining_map);
// Sanity check whether this ended up being collected accidentally
debug_assert!(should_monomorphize_locally(tcx, &instance));
- let ty = instance.ty(tcx);
+ let ty = instance.monomorphic_ty(tcx);
visit_drop_use(tcx, ty, true, &mut neighbors);
recursion_depth_reset = None;
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>(
def_id_to_string(self.tcx, def_id)
);
- let ty = Instance::new(def_id, InternalSubsts::empty()).ty(self.tcx);
+ let ty =
+ Instance::new(def_id, InternalSubsts::empty()).monomorphic_ty(self.tcx);
visit_drop_use(self.tcx, ty, true, self.output);
}
}