-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Long compilation time due to LLVM creating excessive landing pads #41696
Comments
|
@kennytm versions I tried: 2017-03-28, 2017-04-22 and 2017-04-30.
Also tried on different linux boxes - same problem. |
@not-fl3 Could you specifically test with 2017-03-18 and 2017-03-19? You may install it from rustup using
|
@kennytm just tried continuously:
And first broken version is 2017-03-21.
|
@kennytm hmm it seems that on that 03-21 it hangs forever. It works for 20+ minutes and keep working slowly increasing consumed ram. |
The commit for 2017-03-21 is 1.17.0-nightly (134c4a0 2017-03-20) PRs between the two are
|
Could only reproduce with
The cause, is of course, the incremental compilation. |
@kennytm https://gist.github.com/not-fl3/832b85ec9ff08537e479bb42ed4e2402 |
@kennytm checked your log from debian and found that in original post I used RUST_INCREMENTAL instead of CARGO_INCREMENTAL=1. |
Reduced test case: // rustc -Copt-level=2 -Zincremental=. main.rs
struct DS<U> {
name: String,
next: U,
}
fn add<U>(ds: DS<U>, name: String) -> DS<DS<U>> {
DS {
name: "?".to_owned(),
next: ds,
}
}
fn main() {
let deserializers = DS { name: "?".to_owned(), next: () };
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned()); // 0.7s
let deserializers = add(deserializers, "?".to_owned()); // 1.3s
let deserializers = add(deserializers, "?".to_owned()); // 2.4s
let deserializers = add(deserializers, "?".to_owned()); // 6.7s
// let deserializers = add(deserializers, "?".to_owned()); // 26.0s
// let deserializers = add(deserializers, "?".to_owned()); // 114.0s
} Looks like some exponential blow-up. In the 26s case, most time (51%) is spent on the RegisterCoalescer pass. |
Looks like the same problem: fn main() {
let t: std::result::Result<(), ()> = Ok(());
let f = t
.into_future()
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(())) // 0.69 secs
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(())) // 1.94 secs
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(()))
.and_then(|_| future::ok(())) // 20.68 secs
.and_then(|_| future::ok(())) // 40.58 secs
.and_then(|_| future::ok(())) // 80.70 secs
.and_then(|_| future::ok(())) // 160.59 secs
.and_then(|_| future::ok(())) // 321.88 secs
.and_then(|_| future::ok(())); // 642.42 secs
f.wait();
} run:
|
@kgv Not really the same issue. OP's code is slow to compile due to an LLVM pass, your code is slow to compile due to MIR optimization (specifically the "translation item collection" pass). |
Adding |
Presumably this problem could also be triggered by using a larger number of codegen-units (instead of incremental), right? |
I don't quite understand how incremental compilation or the number of codegen units could interact with landing pad generation. |
Yeah |
No codegen-units needed: // rustc -Copt-level=2 main.rs
extern "C" {
static MAYBE: bool;
}
struct MayUnwind;
impl Drop for MayUnwind {
fn drop(&mut self) {
if unsafe { MAYBE } {
panic!()
}
}
}
struct DS<U> {
may_unwind: MayUnwind,
name: String,
next: U,
}
fn add<U>(ds: DS<U>, name: String) -> DS<DS<U>> {
DS {
may_unwind: MayUnwind,
name: "?".to_owned(),
next: ds,
}
}
fn main() {
let deserializers = DS { may_unwind: MayUnwind, name: "?".to_owned(), next: () };
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned());
let deserializers = add(deserializers, "?".to_owned()); // 0.7s
let deserializers = add(deserializers, "?".to_owned()); // 1.3s
let deserializers = add(deserializers, "?".to_owned()); // 2.4s
let deserializers = add(deserializers, "?".to_owned()); // 6.7s
// let deserializers = add(deserializers, "?".to_owned()); // 26.0s
// let deserializers = add(deserializers, "?".to_owned()); // 114.0s
} |
Apparently LLVM has exponential code growth while inlining landing pads if that attribute is present. Fixes rust-lang#41696.
remove the #[inline] attribute from drop_in_place Apparently LLVM has exponential code growth while inlining landing pads if that attribute is present. Fixes rust-lang#41696. beta-nominating because regression. r? @eddyb
remove the #[inline] attribute from drop_in_place Apparently LLVM has exponential code growth while inlining landing pads if that attribute is present. Fixes rust-lang#41696. beta-nominating because regression. r? @eddyb
remove the #[inline] attribute from drop_in_place Apparently LLVM has exponential code growth while inlining landing pads if that attribute is present. Fixes rust-lang#41696. beta-nominating because regression. r? @eddyb
Compilation of tests is *really* slow, most likely due to rust-lang/rust#41696 or rust-lang/rust#38528
@brson I don't think this is resolved. Take jonhoo/fantoccini@79e1683 for example. On current nightly ( |
The unwind path is always cold, so that should not have bad performance implications. This avoids catastrophic exponential inlining, and also decreases the size of librustc.so by 1.5% (OTOH, the size of `libstd.so` increased by 0.5% for some reason). Fixes rust-lang#41696.
mark calls in the unwind path as !noinline The unwind path is always cold, so that should not have bad performance implications. This avoids catastrophic exponential inlining, and also decreases the size of librustc.so by 1.5% (OTOH, the size of `libstd.so` increased by 0.5% for some reason). Fixes #41696. r? @nagisa
@arielb1 #42771 still doesn't seem to solve this for me. EDIT: in fact, compile time seems to have gone up if anything. Used to be ~750s, now 925s... |
Going to tentatively reopen for now based on @jonhoo's report. |
Can you give me the output of compiling your program with |
|
is pretty curious. the extra time is spent between when |
@arielb1: just checking that you saw my follow-up? |
I was a bit busy lately, but:
This bug causes excessive time in LLVM passes, not in translation, so I'm pretty sure it's a different bug. Please open a separate issue. |
Compilation of tests is *really* slow, most likely due to rust-lang/rust#41696 or rust-lang/rust#38528
Mark drop calls in landing pads `cold` instead of `noinline` Now that deferred inlining has been disabled in LLVM (rust-lang#92110), this shouldn't cause catastrophic size blowup. I confirmed that the test cases from rust-lang#41696 (comment) still compile quickly (<1s) after this change. ~Although note that I wasn't able to reproduce the original issue using a recent rustc/llvm with deferred inlining enabled, so those tests may no longer be representative. I was also unable to create a modified test case that reproduced the original issue.~ (edit: I reproduced it on CI by accident--the first commit timed out on the LLVM 12 builder, because I forgot to make it conditional on LLVM version) r? `@nagisa` cc `@arielb1` (this effectively reverts rust-lang#42771 "mark calls in the unwind path as !noinline") cc `@RalfJung` (fixes rust-lang#46515) edit: also fixes rust-lang#87055
Mark drop calls in landing pads `cold` instead of `noinline` Now that deferred inlining has been disabled in LLVM (#92110), this shouldn't cause catastrophic size blowup. I confirmed that the test cases from rust-lang/rust#41696 (comment) still compile quickly (<1s) after this change. ~Although note that I wasn't able to reproduce the original issue using a recent rustc/llvm with deferred inlining enabled, so those tests may no longer be representative. I was also unable to create a modified test case that reproduced the original issue.~ (edit: I reproduced it on CI by accident--the first commit timed out on the LLVM 12 builder, because I forgot to make it conditional on LLVM version) r? `@nagisa` cc `@arielb1` (this effectively reverts #42771 "mark calls in the unwind path as !noinline") cc `@RalfJung` (fixes #46515) edit: also fixes #87055
Long compilation time (almost infinity on real project) with every nightly versions after 2017-03-18.
I tried this:
I expected to see this happen:
On 2017-03-18 it compiles for less than a second (in 0.59 secs on my machine)
Instead, this happened:
With every version newer than 2017-03-18 it compiles for 389+ seconds on my machine.
Meta
rustc --version --verbose
:Also same behaviour on this versions:
nightly-2017-03-28-x86_64-unknown-linux-gnu
nightly-2017-04-22-x86_64-unknown-linux-gnu
nightly-2017-04-30-x86_64-unknown-linux-gnu
Backtrace:
log of -Z time-asses: https://gist.github.com/not-fl3/8c4ee411fe6c23d4b4abb9a3b6a263d0
The text was updated successfully, but these errors were encountered: