Skip to content

Commit 12d2363

Browse files
Increase vtable layout size
This improves LLVM's codegen by allowing vtable loads to be hoisted out of loops (as just one example).
1 parent 01f7f3a commit 12d2363

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

compiler/rustc_middle/src/ty/layout.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -771,11 +771,25 @@ where
771771
});
772772
}
773773

774-
let mk_dyn_vtable = || {
774+
let mk_dyn_vtable = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| {
775+
let min_count = TyCtxt::COMMON_VTABLE_ENTRIES.len()
776+
// As the comment below notes, it's hard to get access to supertraits
777+
// here. Supertraits currently are determined by resolving predicates.
778+
// It's not clear that it's easy to do that here. So, for now, we're
779+
// just increasing the vtable size by the local, direct vtable entries.
780+
// We know that *at least* that many pointers will be needed,
781+
// which is already a win for some cases. As an example, this lets LLVM
782+
// better hoist vtable loads out of loops for calls to `&mut dyn FnMut`
783+
// function arguments.
784+
+ principal
785+
.map(|principal| {
786+
tcx.own_existential_vtable_entries(principal.def_id()).len()
787+
})
788+
.unwrap_or(0);
775789
Ty::new_imm_ref(
776790
tcx,
777791
tcx.lifetimes.re_static,
778-
Ty::new_array(tcx, tcx.types.usize, 3),
792+
Ty::new_array(tcx, tcx.types.usize, min_count.try_into().unwrap()),
779793
)
780794
/* FIXME: use actual fn pointers
781795
Warning: naively computing the number of entries in the
@@ -808,16 +822,16 @@ where
808822
// `std::mem::uninitialized::<&dyn Trait>()`, for example.
809823
if let ty::Adt(def, args) = metadata.kind()
810824
&& Some(def.did()) == tcx.lang_items().dyn_metadata()
811-
&& args.type_at(0).is_trait()
825+
&& let ty::Dynamic(data, _, ty::Dyn) = args.type_at(0).kind()
812826
{
813-
mk_dyn_vtable()
827+
mk_dyn_vtable(data.principal())
814828
} else {
815829
metadata
816830
}
817831
} else {
818832
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
819833
ty::Slice(_) | ty::Str => tcx.types.usize,
820-
ty::Dynamic(_, _, ty::Dyn) => mk_dyn_vtable(),
834+
ty::Dynamic(data, _, ty::Dyn) => mk_dyn_vtable(data.principal()),
821835
_ => bug!("TyAndLayout::field({:?}): not applicable", this),
822836
}
823837
};

0 commit comments

Comments
 (0)