Skip to content

Commit 6774cb4

Browse files
committed
avoid processing mentioned items that are also still used
1 parent 423afd4 commit 6774cb4

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ impl<'tcx> CoroutineInfo<'tcx> {
314314
}
315315

316316
/// Some item that needs to monomorphize successfully for a MIR body to be considered well-formed.
317-
#[derive(Copy, Clone, PartialEq, Debug, HashStable, TyEncodable, TyDecodable)]
317+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable, TyEncodable, TyDecodable)]
318318
#[derive(TypeFoldable, TypeVisitable)]
319319
pub enum MentionedItem<'tcx> {
320320
Fn(DefId, GenericArgsRef<'tcx>),

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,8 @@ struct MirUsedCollector<'a, 'tcx> {
720720
tcx: TyCtxt<'tcx>,
721721
body: &'a mir::Body<'tcx>,
722722
used_items: &'a mut MonoItems<'tcx>,
723+
/// See the comment in `collect_items_of_instance` for the purpose of this set.
724+
used_mentioned_items: &'a mut FxHashSet<MentionedItem<'tcx>>,
723725
instance: Instance<'tcx>,
724726
/// Spans for move size lints already emitted. Helps avoid duplicate lints.
725727
move_size_spans: Vec<Span>,
@@ -990,6 +992,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
990992
match terminator.kind {
991993
mir::TerminatorKind::Call { ref func, ref args, ref fn_span, .. } => {
992994
let callee_ty = func.ty(self.body, tcx);
995+
// *Before* monomorphizing, record that we already handled this mention.
996+
if let ty::FnDef(def_id, args) = callee_ty.kind() {
997+
self.used_mentioned_items.insert(MentionedItem::Fn(*def_id, args));
998+
}
993999
let callee_ty = self.monomorphize(callee_ty);
9941000
self.check_fn_args_move_size(callee_ty, args, *fn_span, location);
9951001
visit_fn_use(self.tcx, callee_ty, true, source, &mut self.used_items)
@@ -1635,10 +1641,22 @@ fn collect_items_of_instance<'tcx>(
16351641
mode: CollectionMode,
16361642
) {
16371643
let body = tcx.instance_mir(instance.def);
1644+
// Naively, in "used" collection mode, all functions get added to *both* `used_items` and
1645+
// `mentioned_items`. Mentioned items processing will then notice that they have already been
1646+
// visited, but at that point each mentioned item has been monomorphized, added to the
1647+
// `mentioned_items` worklist, and checked in the global set of visited items. To removes that
1648+
// overhead, we have a special optimization that avoids adding items to `mentioned_items` when
1649+
// they are already added in `used_items`. We could just scan `used_items`, but that's a linear
1650+
// scan and not very efficient. Furthermore we can only do that *after* monomorphizing the
1651+
// mentioned item. So instead we collect all pre-monomorphized `MentionedItem` that were already
1652+
// added to `used_items` in a hash set, which can efficiently query in the
1653+
// `body.mentioned_items` loop below.
1654+
let mut used_mentioned_items = FxHashSet::<MentionedItem<'tcx>>::default();
16381655
let mut collector = MirUsedCollector {
16391656
tcx,
16401657
body,
16411658
used_items,
1659+
used_mentioned_items: &mut used_mentioned_items,
16421660
instance,
16431661
move_size_spans: vec![],
16441662
visiting_call_terminator: false,
@@ -1658,10 +1676,13 @@ fn collect_items_of_instance<'tcx>(
16581676
}
16591677
}
16601678

1661-
// Always gather mentioned items.
1679+
// Always gather mentioned items. We try to avoid processing items that we have already added to
1680+
// `used_items` above.
16621681
for item in &body.mentioned_items {
1663-
let item_mono = collector.monomorphize(item.node);
1664-
visit_mentioned_item(tcx, &item_mono, item.span, mentioned_items);
1682+
if !collector.used_mentioned_items.contains(&item.node) {
1683+
let item_mono = collector.monomorphize(item.node);
1684+
visit_mentioned_item(tcx, &item_mono, item.span, mentioned_items);
1685+
}
16651686
}
16661687
}
16671688

0 commit comments

Comments
 (0)