msvc: Enable landing pads by default

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!
This commit is contained in:
Alex Crichton 2015-06-29 16:07:45 -07:00
parent d4fe2a0027
commit f9de964ccf
2 changed files with 23 additions and 7 deletions

View 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;
}

View file

@ -22,8 +22,9 @@ use middle::lang_items::ExchangeFreeFnLangItem;
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 trans::type_::Type;
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