diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index d8e4d05872e..84d7b6bc7c9 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -205,7 +205,7 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, // Allocate space: let def_id = require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem); let r = Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[])).reify(bcx.ccx()); - bcx.pointercast(bcx.call(r, &[size, align], bcx.lpad().and_then(|b| b.bundle())), llty_ptr) + bcx.pointercast(bcx.call(r, &[size, align], None), llty_ptr) } @@ -451,38 +451,6 @@ fn cast_shift_rhs(op: hir::BinOp_, } } -pub fn invoke<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>, - llfn: ValueRef, - llargs: &[ValueRef]) - -> (ValueRef, BlockAndBuilder<'blk, 'tcx>) { - let _icx = push_ctxt("invoke_"); - if need_invoke(&bcx) { - debug!("invoking {:?} at {:?}", Value(llfn), bcx.llbb()); - for &llarg in llargs { - debug!("arg: {:?}", Value(llarg)); - } - let normal_bcx = bcx.fcx().new_block("normal-return"); - let landing_pad = bcx.fcx().get_landing_pad(); - - let llresult = bcx.invoke( - llfn, - &llargs[..], - normal_bcx.llbb, - landing_pad, - bcx.lpad().and_then(|b| b.bundle()) - ); - return (llresult, normal_bcx.build()); - } else { - debug!("calling {:?} at {:?}", Value(llfn), bcx.llbb()); - for &llarg in llargs { - debug!("arg: {:?}", Value(llarg)); - } - - let llresult = bcx.call(llfn, &llargs[..], bcx.lpad().and_then(|b| b.bundle())); - return (llresult, bcx); - } -} - /// Returns whether this session's target will use SEH-based unwinding. /// /// This is only true for MSVC targets, and even then the 64-bit MSVC target @@ -492,14 +460,6 @@ pub fn wants_msvc_seh(sess: &Session) -> bool { sess.target.target.options.is_like_msvc } -fn need_invoke(bcx: &BlockAndBuilder) -> bool { - if bcx.sess().no_landing_pads() || bcx.lpad().is_some() { - false - } else { - bcx.fcx().needs_invoke() - } -} - pub fn call_assume<'a, 'tcx>(b: &Builder<'a, 'tcx>, val: ValueRef) { let assume_intrinsic = b.ccx.get_intrinsic("llvm.assume"); b.call(assume_intrinsic, &[val], None); diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 6dd2c46ecec..331945a5a44 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -209,9 +209,10 @@ impl<'tcx> Callee<'tcx> { /// function. pub fn call<'a, 'blk>(self, bcx: BlockAndBuilder<'blk, 'tcx>, args: &[ValueRef], - dest: Option) + dest: Option, + lpad: Option<&'blk llvm::OperandBundleDef>) -> (BlockAndBuilder<'blk, 'tcx>, ValueRef) { - trans_call_inner(bcx, self, args, dest) + trans_call_inner(bcx, self, args, dest, lpad) } /// Turn the callee into a function pointer. @@ -411,7 +412,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( let self_scope = fcx.push_custom_cleanup_scope(); fcx.schedule_drop_mem(self_scope, llenv, closure_ty); - let bcx = callee.call(bcx, &llargs[self_idx..], dest).0; + let bcx = callee.call(bcx, &llargs[self_idx..], dest, None).0; let bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, self_scope); @@ -540,7 +541,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>( data: Fn(llfnpointer), ty: bare_fn_ty }; - let bcx = callee.call(bcx, &llargs[(self_idx + 1)..], dest).0; + let bcx = callee.call(bcx, &llargs[(self_idx + 1)..], dest, None).0; fcx.finish(&bcx); ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn); @@ -653,7 +654,8 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>, callee: Callee<'tcx>, args: &[ValueRef], - opt_llretslot: Option) + opt_llretslot: Option, + lpad: Option<&'blk llvm::OperandBundleDef>) -> (BlockAndBuilder<'blk, 'tcx>, ValueRef) { // Introduce a temporary cleanup scope that will contain cleanups // for the arguments while they are being evaluated. The purpose @@ -707,7 +709,40 @@ fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>, _ => bug!("expected fn pointer callee, found {:?}", callee) }; - let (llret, bcx) = base::invoke(bcx, llfn, &llargs); + fn need_invoke(bcx: &BlockAndBuilder, had_lpad: bool) -> bool { + if bcx.sess().no_landing_pads() || had_lpad { + false + } else { + bcx.fcx().needs_invoke() + } + } + + let _icx = push_ctxt("invoke_"); + let (llret, bcx) = if need_invoke(&bcx, lpad.is_some()) { + debug!("invoking {:?} at {:?}", Value(llfn), bcx.llbb()); + for &llarg in &llargs { + debug!("arg: {:?}", Value(llarg)); + } + let normal_bcx = bcx.fcx().new_block("normal-return"); + let landing_pad = bcx.fcx().get_landing_pad(); + + let llresult = bcx.invoke( + llfn, + &llargs[..], + normal_bcx.llbb, + landing_pad, + lpad, + ); + (llresult, normal_bcx.build()) + } else { + debug!("calling {:?} at {:?}", Value(llfn), bcx.llbb()); + for &llarg in &llargs { + debug!("arg: {:?}", Value(llarg)); + } + + let llresult = bcx.call(llfn, &llargs[..], lpad); + (llresult, bcx) + }; fn_ty.apply_attrs_callsite(llret); // If the function we just called does not use an outpointer, diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index a9e2f00ee73..e6db048cf86 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -46,7 +46,7 @@ pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>, let def_id = langcall(bcx.tcx(), None, "", ExchangeFreeFnLangItem); let args = [bcx.pointercast(v, Type::i8p(bcx.ccx())), size, align]; Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[])) - .call(bcx, &args, None).0 + .call(bcx, &args, None, None).0 } pub fn trans_exchange_free<'blk, 'tcx>(cx: BlockAndBuilder<'blk, 'tcx>, @@ -288,8 +288,7 @@ fn trans_custom_dtor<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>, _ => bug!("dtor for {:?} is not an impl???", t) }; let dtor_did = def.destructor().unwrap(); - bcx = Callee::def(bcx.ccx(), dtor_did, vtbl.substs) - .call(bcx, args, None).0; + bcx = Callee::def(bcx.ccx(), dtor_did, vtbl.substs).call(bcx, args, None, None).0; bcx.fcx().pop_and_trans_custom_cleanup_scope(bcx, contents_scope) } @@ -456,9 +455,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>, let data_ptr = get_dataptr(&bcx, v0); let vtable_ptr = bcx.load(get_meta(&bcx, v0)); let dtor = bcx.load(vtable_ptr); - bcx.call(dtor, - &[bcx.pointercast(bcx.load(data_ptr), Type::i8p(bcx.ccx()))], - bcx.lpad().and_then(|b| b.bundle())); + bcx.call(dtor, &[bcx.pointercast(bcx.load(data_ptr), Type::i8p(bcx.ccx()))], None); bcx } ty::TyAdt(def, ..) if def.dtor_kind().is_present() && !skip_dtor => { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 90f8c64a2cf..303f0f27362 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -119,7 +119,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, // These are the only intrinsic functions that diverge. if name == "abort" { let llfn = ccx.get_intrinsic(&("llvm.trap")); - bcx.call(llfn, &[], bcx.lpad().and_then(|b| b.bundle())); + bcx.call(llfn, &[], None); return; } else if name == "unreachable" { // FIXME: do nothing? @@ -131,15 +131,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, let simple = get_simple_intrinsic(ccx, name); let llval = match (simple, name) { (Some(llfn), _) => { - bcx.call(llfn, &llargs, bcx.lpad().and_then(|b| b.bundle())) + bcx.call(llfn, &llargs, None) } (_, "likely") => { let expect = ccx.get_intrinsic(&("llvm.expect.i1")); - bcx.call(expect, &[llargs[0], C_bool(ccx, true)], bcx.lpad().and_then(|b| b.bundle())) + bcx.call(expect, &[llargs[0], C_bool(ccx, true)], None) } (_, "unlikely") => { let expect = ccx.get_intrinsic(&("llvm.expect.i1")); - bcx.call(expect, &[llargs[0], C_bool(ccx, false)], bcx.lpad().and_then(|b| b.bundle())) + bcx.call(expect, &[llargs[0], C_bool(ccx, false)], None) } (_, "try") => { try_intrinsic(bcx, llargs[0], llargs[1], llargs[2], llresult); @@ -147,7 +147,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, } (_, "breakpoint") => { let llfn = ccx.get_intrinsic(&("llvm.debugtrap")); - bcx.call(llfn, &[], bcx.lpad().and_then(|b| b.bundle())) + bcx.call(llfn, &[], None) } (_, "size_of") => { let tp_ty = substs.type_at(0); @@ -318,13 +318,13 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, "cttz" => count_zeros_intrinsic(bcx, &format!("llvm.cttz.i{}", width), llargs[0]), "ctpop" => bcx.call(ccx.get_intrinsic(&format!("llvm.ctpop.i{}", width)), - &llargs, bcx.lpad().and_then(|b| b.bundle())), + &llargs, None), "bswap" => { if width == 8 { llargs[0] // byte swap a u8/i8 is just a no-op } else { bcx.call(ccx.get_intrinsic(&format!("llvm.bswap.i{}", width)), - &llargs, bcx.lpad().and_then(|b| b.bundle())) + &llargs, None) } } "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => { @@ -654,7 +654,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, let f = declare::declare_cfn(ccx, name, Type::func(&inputs, &outputs)); - bcx.call(f, &llargs, bcx.lpad().and_then(|b| b.bundle())) + bcx.call(f, &llargs, None) } }; @@ -720,7 +720,7 @@ fn copy_intrinsic<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, bcx.mul(size, count), align, C_bool(ccx, volatile)], - bcx.lpad().and_then(|b| b.bundle())) + None) } fn memset_intrinsic<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, @@ -748,7 +748,7 @@ fn memset_intrinsic<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, bcx.mul(size, count), align, C_bool(ccx, volatile)], - bcx.lpad().and_then(|b| b.bundle())) + None) } fn count_zeros_intrinsic(bcx: &BlockAndBuilder, @@ -757,7 +757,7 @@ fn count_zeros_intrinsic(bcx: &BlockAndBuilder, -> ValueRef { let y = C_bool(bcx.ccx(), false); let llfn = bcx.ccx().get_intrinsic(&name); - bcx.call(llfn, &[val, y], bcx.lpad().and_then(|b| b.bundle())) + bcx.call(llfn, &[val, y], None) } fn with_overflow_intrinsic<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, @@ -769,7 +769,7 @@ fn with_overflow_intrinsic<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, let llfn = bcx.ccx().get_intrinsic(&name); // Convert `i1` to a `bool`, and write it to the out parameter - let val = bcx.call(llfn, &[a, b], bcx.lpad().and_then(|b| b.bundle())); + let val = bcx.call(llfn, &[a, b], None); let result = bcx.extract_value(val, 0); let overflow = bcx.zext(bcx.extract_value(val, 1), Type::bool(bcx.ccx())); bcx.store(result, bcx.struct_gep(out, 0)); @@ -786,7 +786,7 @@ fn try_intrinsic<'blk, 'tcx>( dest: ValueRef, ) { if bcx.sess().no_landing_pads() { - bcx.call(func, &[data], bcx.lpad().and_then(|b| b.bundle())); + bcx.call(func, &[data], None); bcx.store(C_null(Type::i8p(&bcx.ccx())), dest); } else if wants_msvc_seh(bcx.sess()) { trans_msvc_try(bcx, func, data, local_ptr, dest); @@ -863,7 +863,7 @@ fn trans_msvc_try<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, let i64p = Type::i64(ccx).ptr_to(); let slot = bcx.fcx().alloca(i64p, "slot"); bcx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), - bcx.lpad().and_then(|b| b.bundle())); + None); normal.ret(C_i32(ccx, 0)); @@ -890,7 +890,7 @@ fn trans_msvc_try<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bcx.call(llfn, &[func, data, local_ptr], bcx.lpad().and_then(|b| b.bundle())); + let ret = bcx.call(llfn, &[func, data, local_ptr], None); bcx.store(ret, dest); } @@ -936,7 +936,7 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, let func = llvm::get_param(bcx.fcx().llfn, 0); let data = llvm::get_param(bcx.fcx().llfn, 1); let local_ptr = llvm::get_param(bcx.fcx().llfn, 2); - bcx.invoke(func, &[data], then.llbb(), catch.llbb(), bcx.lpad().and_then(|b| b.bundle())); + bcx.invoke(func, &[data], then.llbb(), catch.llbb(), None); then.ret(C_i32(ccx, 0)); // Type indicator for the exception being thrown. @@ -956,7 +956,7 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bcx.call(llfn, &[func, data, local_ptr], bcx.lpad().and_then(|b| b.bundle())); + let ret = bcx.call(llfn, &[func, data, local_ptr], None); bcx.store(ret, dest); } diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 75746584bec..e23c545753f 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -91,7 +91,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, let dest = fcx.llretslotptr.get(); let llargs = get_params(fcx.llfn); - bcx = callee.call(bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], dest).0; + bcx = callee.call(bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], dest, None).0; fcx.finish(&bcx);