]> git.lizzy.rs Git - rust.git/commitdiff
msvc: Enable landing pads by default
authorAlex Crichton <alex@alexcrichton.com>
Mon, 29 Jun 2015 23:07:45 +0000 (16:07 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 1 Jul 2015 16:35:54 +0000 (09:35 -0700)
This commit turns on landing pads for MSVC by default, which means that we'll
now be running cleanups for values on the stack when an exception is thrown.
This commit "fixes" the previously seen LLVM abort by attaching the `noinline`
attribute to all generated drop glue to prevent landing pads from being inlined
into other landing pads.

The performance of MSVC is highly likely to decrease from this commit, but there
are various routes we can taken in the future if this ends up staying for quite
a while, such as generating a shim function only called from landing pads which
calls the actual drop glue, and this shim is marked noinline.

For now, however, this patch enables MSVC to successfully bootstrap itself!

src/librustc_trans/trans/base.rs
src/librustc_trans/trans/glue.rs

index 0cd6bbad03aa9206dfbc3789c62f0f15277e89ac..b829a9c6ec449c56d67913fadf6712d32c7b5762 100644 (file)
@@ -751,12 +751,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 }
 
 pub fn need_invoke(bcx: Block) -> bool {
-    // FIXME(#25869) currently unwinding is not implemented for MSVC and our
-    //               normal unwinding infrastructure ends up just causing linker
-    //               errors with the current LLVM implementation, so landing
-    //               pads are disabled entirely for MSVC targets
-    if bcx.sess().no_landing_pads() ||
-       bcx.sess().target.target.options.is_like_msvc {
+    if bcx.sess().no_landing_pads() {
         return false;
     }
 
index 3bcdcd89c47f5d152a30aa51380dae329b6da515..be8510c8e968b5a0f830c7136ae26eeafdfc5c44 100644 (file)
@@ -22,8 +22,9 @@
 use middle::subst;
 use middle::subst::{Subst, Substs};
 use middle::ty::{self, Ty};
-use trans::adt;
 use trans::adt::GetDtorType; // for tcx.dtor_type()
+use trans::adt;
+use trans::attributes;
 use trans::base::*;
 use trans::build::*;
 use trans::callee;
@@ -43,6 +44,7 @@
 use arena::TypedArena;
 use libc::c_uint;
 use syntax::ast;
+use syntax::attr::InlineAttr;
 
 pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                            v: ValueRef,
@@ -250,6 +252,25 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     update_linkage(ccx, llfn, None, OriginalTranslation);
 
+    // FIXME: Currently LLVM has a bug where if an SSA value is created in one
+    //        landing pad and then used in another it will abort during
+    //        compilation. The compiler never actually generates nested landing
+    //        pads, but this often arises when destructors are inlined into
+    //        other functions. To prevent this inlining from happening (and thus
+    //        preventing the LLVM abort) we mark all drop glue as inline(never)
+    //        on MSVC.
+    //
+    //        For more information about the bug, see:
+    //
+    //            https://llvm.org/bugs/show_bug.cgi?id=23884
+    //
+    //        This is clearly not the ideal solution to the problem (due to the
+    //        perf hits), so this should be removed once the upstream bug is
+    //        fixed.
+    if ccx.sess().target.target.options.is_like_msvc {
+        attributes::inline(llfn, InlineAttr::Never);
+    }
+
     ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1);
     // All glue functions take values passed *by alias*; this is a
     // requirement since in many contexts glue is invoked indirectly and