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.
This commit is contained in:
Ariel Ben-Yehuda 2017-06-20 15:07:47 +03:00
parent 1143eb26a2
commit 0b93798959
2 changed files with 7 additions and 2 deletions

View file

@ -146,6 +146,13 @@ fn trans_terminator(&mut self,
} else { } else {
let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle); let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle);
fn_ty.apply_attrs_callsite(llret); fn_ty.apply_attrs_callsite(llret);
if this.mir[bb].is_cleanup {
// Cleanup is always the cold path. Don't inline
// drop glue. Also, when there is a deeply-nested
// struct, there are "symmetry" issues that cause
// exponential inlining - see issue #41696.
llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
}
if let Some((ret_dest, ret_ty, target)) = destination { if let Some((ret_dest, ret_ty, target)) = destination {
let op = OperandRef { let op = OperandRef {

View file

@ -9,8 +9,6 @@
// except according to those terms. // except according to those terms.
// this used to cause exponential code-size blowup during LLVM passes. // this used to cause exponential code-size blowup during LLVM passes.
// ignore-test FIXME #41696
// min-llvm-version 3.9
#![feature(test)] #![feature(test)]