Skip to content

Commit 044fbea

Browse files
committed
Adapt callee to avoid intermediary for move/copy arguments (cc #3402)
1 parent bbfc6f8 commit 044fbea

File tree

1 file changed

+88
-80
lines changed

1 file changed

+88
-80
lines changed

src/rustc/middle/trans/callee.rs

Lines changed: 88 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ fn trans_arg_expr(bcx: block,
484484
{
485485
let _icx = bcx.insn_ctxt("trans_arg_expr");
486486
let ccx = bcx.ccx();
487+
let mut bcx = bcx;
487488

488489
debug!("trans_arg_expr(formal_ty=(%?,%s), arg_expr=%s, \
489490
ret_flag=%?)",
@@ -492,97 +493,104 @@ fn trans_arg_expr(bcx: block,
492493
ret_flag.map(|v| bcx.val_str(v)));
493494
let _indenter = indenter();
494495

495-
// translate the arg expr to a datum
496-
let arg_datumblock = match ret_flag {
497-
None => expr::trans_to_datum(bcx, arg_expr),
498-
499-
// If there is a ret_flag, this *must* be a loop body
500-
Some(_) => {
501-
match arg_expr.node {
502-
ast::expr_loop_body(
503-
blk @ @{node:ast::expr_fn_block(decl, body, cap), _}) =>
504-
{
505-
let scratch_ty = expr_ty(bcx, blk);
506-
let scratch = alloc_ty(bcx, scratch_ty);
507-
let arg_ty = expr_ty(bcx, arg_expr);
508-
let proto = ty::ty_fn_proto(arg_ty);
509-
let bcx = closure::trans_expr_fn(
510-
bcx, proto, decl, body, blk.id,
511-
cap, Some(ret_flag), expr::SaveIn(scratch));
512-
DatumBlock {bcx: bcx,
513-
datum: Datum {val: scratch,
514-
ty: scratch_ty,
515-
mode: ByRef,
516-
source: FromRvalue}}
517-
}
518-
_ => {
519-
bcx.sess().impossible_case(
520-
arg_expr.span, ~"ret_flag with non-loop-\
521-
body expr");
522-
}
523-
}
524-
}
525-
};
526-
let mut arg_datum = arg_datumblock.datum;
527-
let mut bcx = arg_datumblock.bcx;
528-
529-
debug!(" arg datum: %s", arg_datum.to_str(bcx.ccx()));
530-
531496
// finally, deal with the various modes
532497
let arg_mode = ty::resolved_mode(ccx.tcx, formal_ty.mode);
533498
let mut val;
534-
if ty::type_is_bot(arg_datum.ty) {
535-
// For values of type _|_, we generate an
536-
// "undef" value, as such a value should never
537-
// be inspected. It's important for the value
538-
// to have type lldestty (the callee's expected type).
539-
let llformal_ty = type_of::type_of(ccx, formal_ty.ty);
540-
val = llvm::LLVMGetUndef(llformal_ty);
541-
} else {
542-
match arg_mode {
543-
ast::by_ref | ast::by_mutbl_ref => {
544-
val = arg_datum.to_ref_llval(bcx);
545-
}
499+
match arg_mode {
500+
ast::by_ref | ast::by_mutbl_ref => {
501+
let datum = unpack_datum!(bcx, {
502+
trans_arg_expr_to_datum(bcx, arg_expr, ret_flag)
503+
});
504+
val = datum.to_ref_llval(bcx);
505+
}
546506

547-
ast::by_val => {
548-
// NB: avoid running the take glue.
549-
val = arg_datum.to_value_llval(bcx);
550-
}
507+
ast::by_val => {
508+
let datum = unpack_datum!(bcx, {
509+
trans_arg_expr_to_datum(bcx, arg_expr, ret_flag)
510+
});
511+
val = datum.to_value_llval(bcx);
512+
}
551513

552-
ast::by_copy | ast::by_move => {
553-
let scratch = scratch_datum(bcx, arg_datum.ty, false);
514+
ast::by_copy | ast::by_move => {
515+
let scratch = scratch_datum(bcx, formal_ty.ty, false);
516+
bcx = trans_arg_expr_into(bcx, arg_expr, ret_flag,
517+
expr::SaveIn(scratch.val));
518+
519+
// Technically, ownership of val passes to the callee.
520+
// However, we must cleanup should we fail before the
521+
// callee is actually invoked.
522+
scratch.add_clean(bcx);
523+
vec::push(*temp_cleanups, scratch.val);
524+
val = scratch.val;
525+
}
526+
}
554527

555-
if arg_mode == ast::by_move {
556-
// NDM---Doesn't seem like this should be necessary
557-
if !arg_datum.store_will_move() {
558-
bcx.sess().span_bug(
559-
arg_expr.span,
560-
fmt!("move mode but datum will not store: %s",
561-
arg_datum.to_str(bcx.ccx())));
562-
}
563-
}
528+
/*
529+
if formal_ty.ty != arg_datum.ty {
530+
// this could happen due to e.g. subtyping
531+
let llformal_ty = type_of::type_of_explicit_arg(ccx, formal_ty);
532+
debug!("casting actual type (%s) to match formal (%s)",
533+
bcx.val_str(val), bcx.llty_str(llformal_ty));
534+
val = PointerCast(bcx, val, llformal_ty);
535+
}
536+
*/
564537

565-
arg_datum.store_to_datum(bcx, INIT, scratch);
538+
debug!("--- trans_arg_expr passing %s", val_str(bcx.ccx().tn, val));
539+
return rslt(bcx, val);
566540

567-
// Technically, ownership of val passes to the callee.
568-
// However, we must cleanup should we fail before the
569-
// callee is actually invoked.
570-
scratch.add_clean(bcx);
571-
vec::push(*temp_cleanups, scratch.val);
572-
val = scratch.val;
573-
}
574-
}
541+
fn trans_arg_expr_to_datum(bcx: block,
542+
arg_expr: @ast::expr,
543+
ret_flag: Option<ValueRef>) -> DatumBlock {
544+
match ret_flag {
545+
None => {
546+
expr::trans_to_datum(bcx, arg_expr)
547+
}
575548

576-
if formal_ty.ty != arg_datum.ty {
577-
// this could happen due to e.g. subtyping
578-
let llformal_ty = type_of::type_of_explicit_arg(ccx, formal_ty);
579-
debug!("casting actual type (%s) to match formal (%s)",
580-
bcx.val_str(val), bcx.llty_str(llformal_ty));
581-
val = PointerCast(bcx, val, llformal_ty);
549+
// If there is a ret_flag, this *must* be a loop body
550+
Some(_) => {
551+
match arg_expr.node {
552+
ast::expr_loop_body(
553+
blk @ @{node:ast::expr_fn_block(decl, body,
554+
cap), _}) =>
555+
{
556+
let scratch_ty = expr_ty(bcx, blk);
557+
let scratch = alloc_ty(bcx, scratch_ty);
558+
let arg_ty = expr_ty(bcx, arg_expr);
559+
let proto = ty::ty_fn_proto(arg_ty);
560+
let bcx = closure::trans_expr_fn(
561+
bcx, proto, decl, body, blk.id,
562+
cap, Some(ret_flag), expr::SaveIn(scratch));
563+
DatumBlock {bcx: bcx,
564+
datum: Datum {val: scratch,
565+
ty: scratch_ty,
566+
mode: ByRef,
567+
source: FromRvalue}}
568+
}
569+
_ => {
570+
bcx.sess().impossible_case(
571+
arg_expr.span, ~"ret_flag with non-loop-\
572+
body expr");
573+
}
574+
}
575+
}
582576
}
583577
}
584578

585-
debug!("--- trans_arg_expr passing %s", val_str(bcx.ccx().tn, val));
586-
return rslt(bcx, val);
579+
fn trans_arg_expr_into(bcx: block,
580+
arg_expr: @ast::expr,
581+
ret_flag: Option<ValueRef>,
582+
dest: expr::Dest) -> block {
583+
match ret_flag {
584+
None => {
585+
expr::trans_into(bcx, arg_expr, dest)
586+
}
587+
588+
Some(_) => {
589+
let DatumBlock {bcx, datum} =
590+
trans_arg_expr_to_datum(bcx, arg_expr, ret_flag);
591+
datum.store_to_dest(bcx, dest)
592+
}
593+
}
594+
}
587595
}
588596

0 commit comments

Comments
 (0)