Skip to content

Commit a7000b6

Browse files
committed
optimization: do not add non-local reachable-non-generic items to mentioned_items
1 parent 11eaebb commit a7000b6

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

compiler/rustc_mir_transform/src/mentioned_items.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_hir::def_id::DefId;
12
use rustc_middle::mir::visit::Visitor;
23
use rustc_middle::mir::{self, ConstOperand, Location, MentionedItem, MirPass};
34
use rustc_middle::ty::{self, adjustment::PointerCoercion, TyCtxt};
@@ -34,10 +35,12 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
3435
let const_ = constant.const_;
3536
// This is how function items get referenced: via constants of `FnDef` type. This handles
3637
// both functions that are called and those that are just turned to function pointers.
37-
if let ty::FnDef(def_id, args) = const_.ty().kind() {
38+
if let ty::FnDef(def_id, args) = *const_.ty().kind()
39+
&& may_codegen_locally(self.tcx, def_id)
40+
{
3841
debug!("adding to required_items: {def_id:?}");
3942
self.mentioned_items
40-
.push(Spanned { node: MentionedItem::Fn(*def_id, args), span: constant.span });
43+
.push(Spanned { node: MentionedItem::Fn(def_id, args), span: constant.span });
4144
}
4245
}
4346

@@ -95,3 +98,29 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
9598
}
9699
}
97100
}
101+
102+
/// Returns `true` if we should codegen an item in the local crate, or returns `false` if we
103+
/// can just link to the upstream crate and therefore don't need a mono item.
104+
///
105+
/// This is an approximation of the collector's `should_codegen_locally`, in the sense that this
106+
/// here may return `true` even if `should_codegen_locally` says `false`. The point is to let us
107+
/// filter out items that definitely will not be considered by the collector.
108+
fn may_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
109+
if tcx.is_foreign_item(def_id) {
110+
// Foreign items are always linked against, there's no way of instantiating them.
111+
return false;
112+
}
113+
114+
if def_id.is_local() {
115+
// Local items cannot be referred to locally without monomorphizing them locally.
116+
return true;
117+
}
118+
119+
if tcx.is_reachable_non_generic(def_id) {
120+
// We can link to the item in question, no instance needed in this crate.
121+
return false;
122+
}
123+
124+
// Conservative fall-back.
125+
true
126+
}

0 commit comments

Comments
 (0)