Skip to content

Commit 08af43b

Browse files
committed
---
yaml --- r: 128743 b: refs/heads/try c: 857ba98 h: refs/heads/master i: 128741: b8d0e21 128739: dc36cba 128735: 2d714e8 v: v3
1 parent f388a93 commit 08af43b

File tree

16 files changed

+68
-396
lines changed

16 files changed

+68
-396
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 07d86b46a949a94223da714e35b343243e4ecce4
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a86d9ad15e339ab343a12513f9c90556f677b9ca
5-
refs/heads/try: e2273d945640442224a09e532865e4a58257a851
5+
refs/heads/try: 857ba988f189c9a2ebc7d30b1b7b6ec018908aa6
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libcore/intrinsics.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,13 +310,6 @@ extern "rust-intrinsic" {
310310
/// ```
311311
pub fn transmute<T,U>(e: T) -> U;
312312

313-
/// Gives the address for the return value of the enclosing function.
314-
///
315-
/// Using this instrinsic in a function that does not use an out pointer
316-
/// will trigger a compiler error.
317-
#[cfg(not(stage0))]
318-
pub fn return_address() -> *const u8;
319-
320313
/// Returns `true` if a type requires drop glue.
321314
pub fn needs_drop<T>() -> bool;
322315

branches/try/src/librustc/middle/trans/base.rs

Lines changed: 28 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ pub fn memcpy_ty(bcx: &Block, dst: ValueRef, src: ValueRef, t: ty::t) {
11221122
let llalign = llalign_of_min(ccx, llty);
11231123
call_memcpy(bcx, dst, src, llsz, llalign as u32);
11241124
} else {
1125-
store_ty(bcx, Load(bcx, src), dst, t);
1125+
Store(bcx, Load(bcx, src), dst);
11261126
}
11271127
}
11281128

@@ -1210,120 +1210,15 @@ pub fn arrayalloca(cx: &Block, ty: Type, v: ValueRef) -> ValueRef {
12101210
p
12111211
}
12121212

1213-
// Creates the alloca slot which holds the pointer to the slot for the final return value
1214-
pub fn make_return_slot_pointer(fcx: &FunctionContext, output_type: ty::t) -> ValueRef {
1215-
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
1216-
1217-
// We create an alloca to hold a pointer of type `output_type`
1218-
// which will hold the pointer to the right alloca which has the
1219-
// final ret value
1220-
if fcx.needs_ret_allocas {
1221-
// Let's create the stack slot
1222-
let slot = AllocaFcx(fcx, lloutputtype.ptr_to(), "llretslotptr");
1223-
1224-
// and if we're using an out pointer, then store that in our newly made slot
1225-
if type_of::return_uses_outptr(fcx.ccx, output_type) {
1226-
let outptr = get_param(fcx.llfn, 0);
1227-
1228-
let b = fcx.ccx.builder();
1229-
b.position_before(fcx.alloca_insert_pt.get().unwrap());
1230-
b.store(outptr, slot);
1231-
}
1232-
1233-
slot
1234-
1235-
// But if there are no nested returns, we skip the indirection and have a single
1236-
// retslot
1213+
// Creates and returns space for, or returns the argument representing, the
1214+
// slot where the return value of the function must go.
1215+
pub fn make_return_pointer(fcx: &FunctionContext, output_type: ty::t)
1216+
-> ValueRef {
1217+
if type_of::return_uses_outptr(fcx.ccx, output_type) {
1218+
get_param(fcx.llfn, 0)
12371219
} else {
1238-
if type_of::return_uses_outptr(fcx.ccx, output_type) {
1239-
get_param(fcx.llfn, 0)
1240-
} else {
1241-
AllocaFcx(fcx, lloutputtype, "sret_slot")
1242-
}
1243-
}
1244-
}
1245-
1246-
struct CheckForNestedReturnsVisitor {
1247-
found: bool
1248-
}
1249-
1250-
impl Visitor<bool> for CheckForNestedReturnsVisitor {
1251-
fn visit_expr(&mut self, e: &ast::Expr, in_return: bool) {
1252-
match e.node {
1253-
ast::ExprRet(..) if in_return => {
1254-
self.found = true;
1255-
return;
1256-
}
1257-
ast::ExprRet(..) => visit::walk_expr(self, e, true),
1258-
_ => visit::walk_expr(self, e, in_return)
1259-
}
1260-
}
1261-
}
1262-
1263-
fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
1264-
match tcx.map.find(id) {
1265-
Some(ast_map::NodeItem(i)) => {
1266-
match i.node {
1267-
ast::ItemFn(_, _, _, _, blk) => {
1268-
let mut explicit = CheckForNestedReturnsVisitor { found: false };
1269-
let mut implicit = CheckForNestedReturnsVisitor { found: false };
1270-
visit::walk_item(&mut explicit, &*i, false);
1271-
visit::walk_expr_opt(&mut implicit, blk.expr, true);
1272-
explicit.found || implicit.found
1273-
}
1274-
_ => tcx.sess.bug("unexpected item variant in has_nested_returns")
1275-
}
1276-
}
1277-
Some(ast_map::NodeTraitMethod(trait_method)) => {
1278-
match *trait_method {
1279-
ast::Provided(m) => {
1280-
match m.node {
1281-
ast::MethDecl(_, _, _, _, _, _, blk, _) => {
1282-
let mut explicit = CheckForNestedReturnsVisitor { found: false };
1283-
let mut implicit = CheckForNestedReturnsVisitor { found: false };
1284-
visit::walk_method_helper(&mut explicit, &*m, false);
1285-
visit::walk_expr_opt(&mut implicit, blk.expr, true);
1286-
explicit.found || implicit.found
1287-
}
1288-
ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
1289-
}
1290-
}
1291-
ast::Required(_) => tcx.sess.bug("unexpected variant: required trait method in \
1292-
has_nested_returns")
1293-
}
1294-
}
1295-
Some(ast_map::NodeMethod(m)) => {
1296-
match m.node {
1297-
ast::MethDecl(_, _, _, _, _, _, blk, _) => {
1298-
let mut explicit = CheckForNestedReturnsVisitor { found: false };
1299-
let mut implicit = CheckForNestedReturnsVisitor { found: false };
1300-
visit::walk_method_helper(&mut explicit, &*m, false);
1301-
visit::walk_expr_opt(&mut implicit, blk.expr, true);
1302-
explicit.found || implicit.found
1303-
}
1304-
ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
1305-
}
1306-
}
1307-
Some(ast_map::NodeExpr(e)) => {
1308-
match e.node {
1309-
ast::ExprFnBlock(_, blk) | ast::ExprProc(_, blk) | ast::ExprUnboxedFn(_, blk) => {
1310-
let mut explicit = CheckForNestedReturnsVisitor { found: false };
1311-
let mut implicit = CheckForNestedReturnsVisitor { found: false };
1312-
visit::walk_expr(&mut explicit, &*e, false);
1313-
visit::walk_expr_opt(&mut implicit, blk.expr, true);
1314-
explicit.found || implicit.found
1315-
}
1316-
_ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
1317-
}
1318-
}
1319-
1320-
Some(ast_map::NodeVariant(..)) | Some(ast_map::NodeStructCtor(..)) => false,
1321-
1322-
// glue, shims, etc
1323-
None if id == ast::DUMMY_NODE_ID => false,
1324-
1325-
_ => tcx.sess.bug(format!("unexpected variant in has_nested_returns: {}",
1326-
tcx.map.path_to_string(id)).as_slice())
1220+
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
1221+
AllocaFcx(fcx, lloutputtype, "__make_return_pointer")
13271222
}
13281223
}
13291224

@@ -1359,15 +1254,13 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext,
13591254
let substd_output_type = output_type.substp(ccx.tcx(), param_substs);
13601255
let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type);
13611256
let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
1362-
let nested_returns = has_nested_returns(ccx.tcx(), id);
13631257

13641258
let mut fcx = FunctionContext {
13651259
llfn: llfndecl,
13661260
llenv: None,
1367-
llretslotptr: Cell::new(None),
1261+
llretptr: Cell::new(None),
13681262
alloca_insert_pt: Cell::new(None),
13691263
llreturn: Cell::new(None),
1370-
needs_ret_allocas: nested_returns,
13711264
personality: Cell::new(None),
13721265
caller_expects_out_pointer: uses_outptr,
13731266
llargs: RefCell::new(NodeMap::new()),
@@ -1410,12 +1303,12 @@ pub fn init_function<'a>(fcx: &'a FunctionContext<'a>,
14101303

14111304
if !return_type_is_void(fcx.ccx, substd_output_type) {
14121305
// If the function returns nil/bot, there is no real return
1413-
// value, so do not set `llretslotptr`.
1306+
// value, so do not set `llretptr`.
14141307
if !skip_retptr || fcx.caller_expects_out_pointer {
1415-
// Otherwise, we normally allocate the llretslotptr, unless we
1308+
// Otherwise, we normally allocate the llretptr, unless we
14161309
// have been instructed to skip it for immediate return
14171310
// values.
1418-
fcx.llretslotptr.set(Some(make_return_slot_pointer(fcx, substd_output_type)));
1311+
fcx.llretptr.set(Some(make_return_pointer(fcx, substd_output_type)));
14191312
}
14201313
}
14211314

@@ -1640,18 +1533,13 @@ pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>,
16401533

16411534
// Builds the return block for a function.
16421535
pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block, retty: ty::t) {
1643-
if fcx.llretslotptr.get().is_none() ||
1644-
(!fcx.needs_ret_allocas && fcx.caller_expects_out_pointer) {
1536+
// Return the value if this function immediate; otherwise, return void.
1537+
if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer {
16451538
return RetVoid(ret_cx);
16461539
}
16471540

1648-
let retslot = if fcx.needs_ret_allocas {
1649-
Load(ret_cx, fcx.llretslotptr.get().unwrap())
1650-
} else {
1651-
fcx.llretslotptr.get().unwrap()
1652-
};
1653-
let retptr = Value(retslot);
1654-
match retptr.get_dominating_store(ret_cx) {
1541+
let retptr = Value(fcx.llretptr.get().unwrap());
1542+
let retval = match retptr.get_dominating_store(ret_cx) {
16551543
// If there's only a single store to the ret slot, we can directly return
16561544
// the value that was stored and omit the store and the alloca
16571545
Some(s) => {
@@ -1662,29 +1550,17 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block, retty: ty::t) {
16621550
retptr.erase_from_parent();
16631551
}
16641552

1665-
let retval = if ty::type_is_bool(retty) {
1553+
if ty::type_is_bool(retty) {
16661554
Trunc(ret_cx, retval, Type::i1(fcx.ccx))
16671555
} else {
16681556
retval
1669-
};
1670-
1671-
if fcx.caller_expects_out_pointer {
1672-
store_ty(ret_cx, retval, get_param(fcx.llfn, 0), retty);
1673-
return RetVoid(ret_cx);
1674-
} else {
1675-
return Ret(ret_cx, retval);
16761557
}
16771558
}
1678-
// Otherwise, copy the return value to the ret slot
1679-
None => {
1680-
if fcx.caller_expects_out_pointer {
1681-
memcpy_ty(ret_cx, get_param(fcx.llfn, 0), retslot, retty);
1682-
return RetVoid(ret_cx);
1683-
} else {
1684-
return Ret(ret_cx, load_ty(ret_cx, retslot, retty));
1685-
}
1686-
}
1687-
}
1559+
// Otherwise, load the return value from the ret slot
1560+
None => load_ty(ret_cx, fcx.llretptr.get().unwrap(), retty)
1561+
};
1562+
1563+
Ret(ret_cx, retval);
16881564
}
16891565

16901566
#[deriving(Clone, Eq, PartialEq)]
@@ -1782,10 +1658,10 @@ pub fn trans_closure(ccx: &CrateContext,
17821658
// emitting should be enabled.
17831659
debuginfo::start_emitting_source_locations(&fcx);
17841660

1785-
let dest = match fcx.llretslotptr.get() {
1786-
Some(_) => expr::SaveIn(fcx.get_ret_slot(bcx, block_ty, "iret_slot")),
1661+
let dest = match fcx.llretptr.get() {
1662+
Some(e) => {expr::SaveIn(e)}
17871663
None => {
1788-
assert!(type_is_zero_size(bcx.ccx(), block_ty));
1664+
assert!(type_is_zero_size(bcx.ccx(), block_ty))
17891665
expr::Ignore
17901666
}
17911667
};
@@ -1796,13 +1672,6 @@ pub fn trans_closure(ccx: &CrateContext,
17961672
// (trans_block, trans_expr, et cetera).
17971673
bcx = controlflow::trans_block(bcx, body, dest);
17981674

1799-
match dest {
1800-
expr::SaveIn(slot) if fcx.needs_ret_allocas => {
1801-
Store(bcx, slot, fcx.llretslotptr.get().unwrap());
1802-
}
1803-
_ => {}
1804-
}
1805-
18061675
match fcx.llreturn.get() {
18071676
Some(_) => {
18081677
Br(bcx, fcx.return_exit_block());
@@ -1967,24 +1836,21 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
19671836
param_substs, None, &arena, TranslateItems);
19681837
let bcx = init_function(&fcx, false, result_ty);
19691838

1970-
assert!(!fcx.needs_ret_allocas);
1971-
19721839
let arg_tys = ty::ty_fn_args(ctor_ty);
19731840

19741841
let arg_datums = create_datums_for_fn_args(&fcx, arg_tys.as_slice());
19751842

19761843
if !type_is_zero_size(fcx.ccx, result_ty) {
1977-
let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
19781844
let repr = adt::represent_type(ccx, result_ty);
19791845
for (i, arg_datum) in arg_datums.move_iter().enumerate() {
19801846
let lldestptr = adt::trans_field_ptr(bcx,
19811847
&*repr,
1982-
dest,
1848+
fcx.llretptr.get().unwrap(),
19831849
disr,
19841850
i);
19851851
arg_datum.store_to(bcx, lldestptr);
19861852
}
1987-
adt::trans_set_discr(bcx, &*repr, dest, disr);
1853+
adt::trans_set_discr(bcx, &*repr, fcx.llretptr.get().unwrap(), disr);
19881854
}
19891855

19901856
finish_fn(&fcx, bcx, result_ty);

branches/try/src/librustc/middle/trans/callee.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ pub fn trans_unboxing_shim(bcx: &Block,
334334
let return_type = ty::ty_fn_ret(boxed_function_type);
335335
let fcx = new_fn_ctxt(ccx,
336336
llfn,
337-
ast::DUMMY_NODE_ID,
337+
-1,
338338
false,
339339
return_type,
340340
&empty_param_substs,
@@ -389,11 +389,6 @@ pub fn trans_unboxing_shim(bcx: &Block,
389389
for i in range(1, arg_types.len()) {
390390
llshimmedargs.push(get_param(fcx.llfn, fcx.arg_pos(i) as u32));
391391
}
392-
assert!(!fcx.needs_ret_allocas);
393-
let dest = match fcx.llretslotptr.get() {
394-
Some(_) => Some(expr::SaveIn(fcx.get_ret_slot(bcx, return_type, "ret_slot"))),
395-
None => None
396-
};
397392
bcx = trans_call_inner(bcx,
398393
None,
399394
function_type,
@@ -404,7 +399,10 @@ pub fn trans_unboxing_shim(bcx: &Block,
404399
}
405400
},
406401
ArgVals(llshimmedargs.as_slice()),
407-
dest).bcx;
402+
match fcx.llretptr.get() {
403+
None => None,
404+
Some(llretptr) => Some(expr::SaveIn(llretptr)),
405+
}).bcx;
408406

409407
bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_scope);
410408
finish_fn(&fcx, bcx, return_type);
@@ -760,11 +758,9 @@ pub fn trans_call_inner<'a>(
760758
assert!(abi == synabi::RustIntrinsic);
761759
assert!(dest.is_some());
762760

763-
let call_info = call_info.expect("no call info for intrinsic call?");
764761
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
765762
arg_cleanup_scope, args,
766-
dest.unwrap(), substs,
767-
call_info);
763+
dest.unwrap(), substs);
768764
}
769765
NamedTupleConstructor(substs, disr) => {
770766
assert!(dest.is_some());

branches/try/src/librustc/middle/trans/closure.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -574,25 +574,24 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
574574

575575
let arena = TypedArena::new();
576576
let empty_param_substs = param_substs::empty();
577-
let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, true, f.sig.output,
577+
let fcx = new_fn_ctxt(ccx, llfn, -1, true, f.sig.output,
578578
&empty_param_substs, None, &arena, TranslateItems);
579579
let bcx = init_function(&fcx, true, f.sig.output);
580580

581581
let args = create_datums_for_fn_args(&fcx,
582582
ty::ty_fn_args(closure_ty)
583583
.as_slice());
584584
let mut llargs = Vec::new();
585-
match fcx.llretslotptr.get() {
585+
match fcx.llretptr.get() {
586586
Some(llretptr) => {
587-
assert!(!fcx.needs_ret_allocas);
588587
llargs.push(llretptr);
589588
}
590589
None => {}
591590
}
592591
llargs.extend(args.iter().map(|arg| arg.val));
593592

594593
let retval = Call(bcx, fn_ptr, llargs.as_slice(), None);
595-
if type_is_zero_size(ccx, f.sig.output) || fcx.llretslotptr.get().is_some() {
594+
if type_is_zero_size(ccx, f.sig.output) || fcx.llretptr.get().is_some() {
596595
RetVoid(bcx);
597596
} else {
598597
Ret(bcx, retval);

0 commit comments

Comments
 (0)