1
Fork 0

Refactor Callee::call to take bcx by-reference.

Also change to not return anything; nothing used the return ValueRef.

Inlines with_cond.
This commit is contained in:
Mark-Simulacrum 2016-12-17 12:27:48 -07:00 committed by Mark Simulacrum
parent 9a198534e2
commit 937001a1f8
4 changed files with 46 additions and 75 deletions

View file

@ -480,24 +480,6 @@ pub fn to_immediate(bcx: &BlockAndBuilder, val: ValueRef, ty: Ty) -> ValueRef {
}
}
pub fn with_cond<'blk, 'tcx, F>(
bcx: BlockAndBuilder<'blk, 'tcx>, val: ValueRef, f: F
) -> BlockAndBuilder<'blk, 'tcx>
where F: FnOnce(BlockAndBuilder<'blk, 'tcx>) -> BlockAndBuilder<'blk, 'tcx>
{
if common::const_to_opt_uint(val) == Some(0) {
return bcx;
}
let fcx = bcx.fcx();
let next_cx = fcx.build_new_block("next");
let cond_cx = fcx.build_new_block("cond");
bcx.cond_br(val, cond_cx.llbb(), next_cx.llbb());
let after_cx = f(cond_cx);
after_cx.br(next_cx.llbb());
next_cx
}
pub enum Lifetime { Start, End }
impl Lifetime {

View file

@ -189,11 +189,10 @@ impl<'tcx> Callee<'tcx> {
/// For non-lang items, `dest` is always Some, and hence the result is written
/// into memory somewhere. Nonetheless we return the actual return value of the
/// function.
pub fn call<'a, 'blk>(self, bcx: BlockAndBuilder<'blk, 'tcx>,
pub fn call<'a, 'blk>(self, bcx: &BlockAndBuilder<'blk, 'tcx>,
args: &[ValueRef],
dest: Option<ValueRef>,
lpad: Option<&'blk llvm::OperandBundleDef>)
-> (BlockAndBuilder<'blk, 'tcx>, ValueRef) {
lpad: Option<&'blk llvm::OperandBundleDef>) {
trans_call_inner(bcx, self, args, dest, lpad)
}
@ -538,7 +537,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
data: Fn(llfnpointer),
ty: bare_fn_ty
};
let bcx = callee.call(bcx, &llargs[(self_idx + 1)..], fcx.llretslotptr, None).0;
callee.call(&bcx, &llargs[(self_idx + 1)..], fcx.llretslotptr, None);
fcx.finish(&bcx);
ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn);
@ -648,12 +647,11 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// ______________________________________________________________________
// Translating calls
fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
fn trans_call_inner<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
callee: Callee<'tcx>,
args: &[ValueRef],
opt_llretslot: Option<ValueRef>,
lpad: Option<&'blk llvm::OperandBundleDef>)
-> (BlockAndBuilder<'blk, 'tcx>, ValueRef) {
dest: Option<ValueRef>,
lpad: Option<&'blk llvm::OperandBundleDef>) {
// Introduce a temporary cleanup scope that will contain cleanups
// for the arguments while they are being evaluated. The purpose
// this cleanup is to ensure that, should a panic occur while
@ -661,61 +659,52 @@ fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
// cleaned up. If no panic occurs, the values are handed off to
// the callee, and hence none of the cleanups in this temporary
// scope will ever execute.
let fcx = &bcx.fcx();
let ccx = fcx.ccx;
let ccx = bcx.ccx();
let fn_ret = callee.ty.fn_ret();
let fn_ty = callee.direct_fn_type(ccx, &[]);
let mut callee = match callee.data {
NamedTupleConstructor(_) | Intrinsic => {
bug!("{:?} calls should not go through Callee::call", callee);
}
f => f
};
// If there no destination, return must be direct, with no cast.
if opt_llretslot.is_none() {
if dest.is_none() {
assert!(!fn_ty.ret.is_indirect() && fn_ty.ret.cast.is_none());
}
let mut llargs = Vec::new();
if fn_ty.ret.is_indirect() {
let mut llretslot = opt_llretslot.unwrap();
if let Some(ty) = fn_ty.ret.cast {
llretslot = bcx.pointercast(llretslot, ty.ptr_to());
}
let dest = dest.unwrap();
let llretslot = if let Some(ty) = fn_ty.ret.cast {
bcx.pointercast(dest, ty.ptr_to())
} else {
dest
};
llargs.push(llretslot);
}
match callee {
let llfn = match callee.data {
NamedTupleConstructor(_) | Intrinsic => {
bug!("{:?} calls should not go through Callee::call", callee);
}
Virtual(idx) => {
llargs.push(args[0]);
let fn_ptr = meth::get_virtual_method(&bcx, args[1], idx);
let llty = fn_ty.llvm_type(&bcx.ccx()).ptr_to();
callee = Fn(bcx.pointercast(fn_ptr, llty));
llargs.extend_from_slice(&args[2..]);
bcx.pointercast(fn_ptr, llty)
}
Fn(f) => {
llargs.extend_from_slice(args);
f
}
_ => llargs.extend_from_slice(args)
}
let llfn = match callee {
Fn(f) => f,
_ => bug!("expected fn pointer callee, found {:?}", callee)
};
let llret = bcx.call(llfn, &llargs[..], lpad);
fn_ty.apply_attrs_callsite(llret);
// If the function we just called does not use an outpointer,
// store the result into the rust outpointer. Cast the outpointer
// type to match because some ABIs will use a different type than
// the Rust type. e.g., a {u32,u32} struct could be returned as
// u64.
// store the result into the Rust outpointer.
if !fn_ty.ret.is_indirect() {
if let Some(llretslot) = opt_llretslot {
if let Some(llretslot) = dest {
fn_ty.ret.store(&bcx, llret, llretslot);
}
}
@ -723,6 +712,4 @@ fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
if fn_ret.0.is_never() {
bcx.unreachable();
}
(bcx, llret)
}

View file

@ -35,21 +35,18 @@ use Disr;
use syntax_pos::DUMMY_SP;
pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
v: ValueRef,
size: ValueRef,
align: ValueRef)
-> BlockAndBuilder<'blk, 'tcx> {
align: ValueRef) {
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, None).0
Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[])).call(&bcx, &args, None, None)
}
pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
ptr: ValueRef,
content_ty: Ty<'tcx>)
-> BlockAndBuilder<'blk, 'tcx> {
content_ty: Ty<'tcx>) {
assert!(type_is_sized(bcx.ccx().tcx(), content_ty));
let sizing_type = sizing_type_of(bcx.ccx(), content_ty);
let content_size = llsize_of_alloc(bcx.ccx(), sizing_type);
@ -58,9 +55,7 @@ pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
if content_size != 0 {
let content_align = align_of(bcx.ccx(), content_ty);
let ccx = bcx.ccx();
trans_exchange_free_dyn(bcx, ptr, C_uint(ccx, content_size), C_uint(ccx, content_align))
} else {
bcx
trans_exchange_free_dyn(bcx, ptr, C_uint(ccx, content_size), C_uint(ccx, content_align));
}
}
@ -410,14 +405,23 @@ fn make_drop_glue<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
llsize,
C_uint(bcx.ccx(), 0u64),
);
with_cond(bcx, needs_free, |bcx| {
trans_exchange_free_dyn(bcx, llbox, llsize, llalign)
})
if const_to_opt_uint(needs_free) == Some(0) {
bcx
} else {
let fcx = bcx.fcx();
let next_cx = fcx.build_new_block("next");
let cond_cx = fcx.build_new_block("cond");
bcx.cond_br(needs_free, cond_cx.llbb(), next_cx.llbb());
trans_exchange_free_dyn(&cond_cx, llbox, llsize, llalign);
cond_cx.br(next_cx.llbb());
next_cx
}
} else {
let llval = v0;
let llbox = bcx.load(llval);
drop_ty(&bcx, llbox, content_ty);
trans_exchange_free_ty(bcx, llbox, content_ty)
trans_exchange_free_ty(&bcx, llbox, content_ty);
bcx
}
}
ty::TyDynamic(..) => {

View file

@ -82,12 +82,10 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
attributes::set_frame_pointer_elimination(ccx, llfn);
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None, false);
let mut bcx = fcx.get_entry_block();
let bcx = fcx.get_entry_block();
let llargs = get_params(fcx.llfn);
bcx = callee.call(bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], fcx.llretslotptr,
None).0;
callee.call(&bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], fcx.llretslotptr, None);
fcx.finish(&bcx);
llfn