From 0b937989599392d42de0a792a91fa7bc0bc53f92 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 20 Jun 2017 15:07:47 +0300 Subject: [PATCH] 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. --- src/librustc_trans/mir/block.rs | 7 +++++++ src/test/run-pass/issue-41696.rs | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 4926485a12125..8863c7ffae6f4 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -146,6 +146,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } else { let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle); 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 { let op = OperandRef { diff --git a/src/test/run-pass/issue-41696.rs b/src/test/run-pass/issue-41696.rs index 40fbf5ba75c8d..1888be58c57d0 100644 --- a/src/test/run-pass/issue-41696.rs +++ b/src/test/run-pass/issue-41696.rs @@ -9,8 +9,6 @@ // except according to those terms. // this used to cause exponential code-size blowup during LLVM passes. -// ignore-test FIXME #41696 -// min-llvm-version 3.9 #![feature(test)]