Skip to content

Commit

Permalink
Increase vtable layout size
Browse files Browse the repository at this point in the history
This improves LLVM's codegen by allowing vtable loads to be hoisted out
of loops (as just one example).
  • Loading branch information
Mark-Simulacrum committed Apr 6, 2024
1 parent 01f7f3a commit 12d2363
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,11 +771,25 @@ where
});
}

let mk_dyn_vtable = || {
let mk_dyn_vtable = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| {
let min_count = TyCtxt::COMMON_VTABLE_ENTRIES.len()
// As the comment below notes, it's hard to get access to supertraits
// here. Supertraits currently are determined by resolving predicates.
// It's not clear that it's easy to do that here. So, for now, we're
// just increasing the vtable size by the local, direct vtable entries.
// We know that *at least* that many pointers will be needed,
// which is already a win for some cases. As an example, this lets LLVM
// better hoist vtable loads out of loops for calls to `&mut dyn FnMut`
// function arguments.
+ principal
.map(|principal| {
tcx.own_existential_vtable_entries(principal.def_id()).len()
})
.unwrap_or(0);
Ty::new_imm_ref(
tcx,
tcx.lifetimes.re_static,
Ty::new_array(tcx, tcx.types.usize, 3),
Ty::new_array(tcx, tcx.types.usize, min_count.try_into().unwrap()),
)
/* FIXME: use actual fn pointers
Warning: naively computing the number of entries in the
Expand Down Expand Up @@ -808,16 +822,16 @@ where
// `std::mem::uninitialized::<&dyn Trait>()`, for example.
if let ty::Adt(def, args) = metadata.kind()
&& Some(def.did()) == tcx.lang_items().dyn_metadata()
&& args.type_at(0).is_trait()
&& let ty::Dynamic(data, _, ty::Dyn) = args.type_at(0).kind()
{
mk_dyn_vtable()
mk_dyn_vtable(data.principal())
} else {
metadata
}
} else {
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
ty::Slice(_) | ty::Str => tcx.types.usize,
ty::Dynamic(_, _, ty::Dyn) => mk_dyn_vtable(),
ty::Dynamic(data, _, ty::Dyn) => mk_dyn_vtable(data.principal()),
_ => bug!("TyAndLayout::field({:?}): not applicable", this),
}
};
Expand Down

0 comments on commit 12d2363

Please sign in to comment.