-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Excessive drop glue duplication in vtables can blow up compile times #88438
Comments
Further investigation shows that the trait objects are an accidental detail here. I've put a repro for the problem here: It contains three crates.
#![no_std]
use core::fmt;
pub struct MyArc<T> {
_value: T,
}
impl<T> Drop for MyArc<T> {
fn drop(&mut self) {
self.drop_slow()
}
}
impl<T> MyArc<T> {
#[inline(never)]
fn drop_slow(&mut self) {
unsafe {
print(format_args!("dropping {:?}", core::any::type_name::<T>()));
}
}
}
#[allow(improper_ctypes)]
extern "C" {
fn print(_: fmt::Arguments);
}
#![no_std]
pub struct S {
_inner: a::MyArc<i32>,
}
#![no_std]
pub extern "Rust" fn f(_: b::S) {
} If I compile the crates as #!/bin/sh
rustc -C opt-level=3 --crate-type rlib a.rs
rustc -C opt-level=3 --crate-type rlib --extern a=liba.rlib b.rs
rustc -C opt-level=3 --crate-type rlib --extern b=libb.rlib -L dependency=. \
-Zsymbol-mangling-version=v0 --emit=llvm-ir -Cno-prepopulate-passes -Cpasses=name-anon-globals \
c.rs I will see that llvm IR for I can get the desired behavior by using Jonas' Gambit in crate use core::mem::ManuallyDrop;
pub struct S {
inner: ManuallyDrop<a::MyArc<i32>>,
}
impl Drop for S {
fn drop(&mut self) {
unsafe {
ManuallyDrop::drop(&mut self.inner)
}
}
} $ exa -l *.ll
.rw-r--r-- 1.5k matklad 30 Aug 13:13 c.ll.after
.rw-r--r-- 14k matklad 30 Aug 13:14 c.ll.before An important detail here is that there maybe many downstream To come back to the original issue, this hits us hard in rust-analyzer in two ways. First, we have this Second, we use chalk, which contains a lot of very generic and very recursive data structures. We wrap all this into a non-generic |
Seems duplicate of #84175 I forced the drop glue generated locally in #89660 as @Kobzol suggested, then "re-bench" on @matklad 's repros with #!/bin/sh
rustc +dev -C opt-level=3 --crate-type rlib a.rs -Zshare-generics
rustc +dev -C opt-level=3 --crate-type rlib --extern a=liba.rlib b.rs -Zshare-generics
rustc +dev -C opt-level=3 --crate-type rlib --extern b=libb.rlib -L dependency=. \
-Zsymbol-mangling-version=v0 -Zshare-generics --emit=llvm-ir -Cno-prepopulate-passes -Cpasses=name-anon-globals \
c.rs ( -rw-r--r-- 1 mac staff 1999 Oct 9 13:01 c.ll.drop_glue_locally
-rw-r--r-- 1 mac staff 16279 Oct 9 12:59 c.ll.drop_glue_no_locally We got the nearly same result as |
#64140 is related (maybe exactly the same issue) |
Currently, it seems like every CGU that contains a
&ConcreteType -> &dyn Trait
cast will instantiate the corresponding vtable and drop glue ofConcreteType
. This can result in massive LLVM IR bloat that then slows down compile times.We have observed this in rust-analyzer (rust-lang/rust-analyzer#10065, also Zulip discussion here), where the drop glue of a single type
RootDatabase
is responsible for over 40% of LLVM IR in some downstream crates.The text was updated successfully, but these errors were encountered: