Skip to content

Commit 4bc0d61

Browse files
committed
---
yaml --- r: 64286 b: refs/heads/snap-stage3 c: dcd5d14 h: refs/heads/master v: v3
1 parent 9435b14 commit 4bc0d61

File tree

8 files changed

+114
-69
lines changed

8 files changed

+114
-69
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: a9eb86823049c2eff98e74fcac8ae75cc8760f33
4+
refs/heads/snap-stage3: dcd5d14e6cbb32aeccae3d12951181c525070ee7
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/middle/trans/base.rs

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,11 +1102,6 @@ pub fn trans_trace(bcx: block, sp_opt: Option<span>, trace_str: @str) {
11021102
Call(bcx, ccx.upcalls.trace, args);
11031103
}
11041104

1105-
pub fn build_return(bcx: block) {
1106-
let _icx = push_ctxt("build_return");
1107-
Br(bcx, bcx.fcx.llreturn);
1108-
}
1109-
11101105
pub fn ignore_lhs(_bcx: block, local: &ast::local) -> bool {
11111106
match local.node.pat.node {
11121107
ast::pat_wild => true, _ => false
@@ -1364,6 +1359,42 @@ pub fn cleanup_and_leave(bcx: block,
13641359
}
13651360
}
13661361

1362+
pub fn cleanup_block(bcx: block, upto: Option<BasicBlockRef>) -> block{
1363+
let _icx = push_ctxt("cleanup_block");
1364+
let mut cur = bcx;
1365+
let mut bcx = bcx;
1366+
loop {
1367+
debug!("cleanup_block: %s", cur.to_str());
1368+
1369+
if bcx.sess().trace() {
1370+
trans_trace(
1371+
bcx, None,
1372+
(fmt!("cleanup_block(%s)", cur.to_str())).to_managed());
1373+
}
1374+
1375+
let mut cur_scope = cur.scope;
1376+
loop {
1377+
cur_scope = match cur_scope {
1378+
Some (inf) => {
1379+
bcx = trans_block_cleanups_(bcx, inf.cleanups.to_owned(), false);
1380+
inf.parent
1381+
}
1382+
None => break
1383+
}
1384+
}
1385+
1386+
match upto {
1387+
Some(bb) => { if cur.llbb == bb { break; } }
1388+
_ => ()
1389+
}
1390+
cur = match cur.parent {
1391+
Some(next) => next,
1392+
None => { assert!(upto.is_none()); break; }
1393+
};
1394+
}
1395+
bcx
1396+
}
1397+
13671398
pub fn cleanup_and_Br(bcx: block, upto: block, target: BasicBlockRef) {
13681399
let _icx = push_ctxt("cleanup_and_Br");
13691400
cleanup_and_leave(bcx, Some(upto.llbb), Some(target));
@@ -1544,7 +1575,6 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
15441575

15451576
pub struct BasicBlocks {
15461577
sa: BasicBlockRef,
1547-
rt: BasicBlockRef
15481578
}
15491579

15501580
// Creates the standard set of basic blocks for a function
@@ -1554,12 +1584,18 @@ pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks {
15541584
BasicBlocks {
15551585
sa: str::as_c_str("static_allocas",
15561586
|buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)),
1557-
rt: str::as_c_str("return",
1558-
|buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf))
15591587
}
15601588
}
15611589
}
15621590

1591+
pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
1592+
unsafe {
1593+
let cx = task_llcx();
1594+
str::as_c_str("return",
1595+
|buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf))
1596+
}
1597+
}
1598+
15631599
// Creates and returns space for, or returns the argument representing, the
15641600
// slot where the return value of the function must go.
15651601
pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
@@ -1613,7 +1649,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16131649
llretptr: None,
16141650
llstaticallocas: llbbs.sa,
16151651
llloadenv: None,
1616-
llreturn: llbbs.rt,
1652+
llreturn: None,
16171653
llself: None,
16181654
personality: None,
16191655
loop_ret: None,
@@ -1757,16 +1793,24 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
17571793

17581794
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
17591795
// and builds the return block.
1760-
pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef) {
1796+
pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
17611797
let _icx = push_ctxt("finish_fn");
17621798
tie_up_header_blocks(fcx, lltop);
1763-
build_return_block(fcx);
1799+
1800+
let ret_cx = match fcx.llreturn {
1801+
Some(llreturn) => {
1802+
if !last_bcx.terminated {
1803+
Br(last_bcx, llreturn);
1804+
}
1805+
raw_block(fcx, false, llreturn)
1806+
}
1807+
None => last_bcx
1808+
};
1809+
build_return_block(fcx, ret_cx);
17641810
}
17651811

17661812
// Builds the return block for a function.
1767-
pub fn build_return_block(fcx: fn_ctxt) {
1768-
let ret_cx = raw_block(fcx, false, fcx.llreturn);
1769-
1813+
pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
17701814
// Return the value if this function immediate; otherwise, return void.
17711815
if fcx.llretptr.is_some() && fcx.has_immediate_return_value {
17721816
Ret(ret_cx, Load(ret_cx, fcx.llretptr.get()))
@@ -1854,16 +1898,21 @@ pub fn trans_closure(ccx: @mut CrateContext,
18541898
}
18551899

18561900
finish(bcx);
1857-
cleanup_and_Br(bcx, bcx_top, fcx.llreturn);
1901+
match fcx.llreturn {
1902+
Some(llreturn) => cleanup_and_Br(bcx, bcx_top, llreturn),
1903+
None => bcx = cleanup_block(bcx, Some(bcx_top.llbb))
1904+
};
18581905

18591906
// Put return block after all other blocks.
18601907
// This somewhat improves single-stepping experience in debugger.
18611908
unsafe {
1862-
llvm::LLVMMoveBasicBlockAfter(fcx.llreturn, bcx.llbb);
1909+
for fcx.llreturn.iter().advance |&llreturn| {
1910+
llvm::LLVMMoveBasicBlockAfter(llreturn, bcx.llbb);
1911+
}
18631912
}
18641913

18651914
// Insert the mandatory first few basic blocks before lltop.
1866-
finish_fn(fcx, lltop);
1915+
finish_fn(fcx, lltop, bcx);
18671916
}
18681917

18691918
// trans_fn: creates an LLVM function corresponding to a source language
@@ -2046,8 +2095,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
20462095
let arg_ty = arg_tys[i];
20472096
memcpy_ty(bcx, lldestptr, llarg, arg_ty);
20482097
}
2049-
build_return(bcx);
2050-
finish_fn(fcx, lltop);
2098+
finish_fn(fcx, lltop, bcx);
20512099
}
20522100

20532101
pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
@@ -2288,8 +2336,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
22882336
let args = ~[llenvarg];
22892337
Call(bcx, main_llfn, args);
22902338

2291-
build_return(bcx);
2292-
finish_fn(fcx, lltop);
2339+
finish_fn(fcx, lltop, bcx);
22932340
return llfdecl;
22942341
}
22952342

branches/snap-stage3/src/librustc/middle/trans/callee.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ pub fn trans_call_inner(in_cx: block,
704704
Store(bcx, C_bool(false), bcx.fcx.llretptr.get());
705705
}
706706
}
707-
base::cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn));
707+
base::cleanup_and_leave(bcx, None, Some(bcx.fcx.get_llreturn()));
708708
Unreachable(bcx);
709709
bcx
710710
}

branches/snap-stage3/src/librustc/middle/trans/common.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ pub struct fn_ctxt_ {
184184
// (LLVM requires that arguments be copied to local allocas before
185185
// allowing most any operation to be performed on them.)
186186
llloadenv: Option<BasicBlockRef>,
187-
llreturn: BasicBlockRef,
187+
llreturn: Option<BasicBlockRef>,
188188
// The 'self' value currently in use in this function, if there
189189
// is one.
190190
//
@@ -251,6 +251,13 @@ impl fn_ctxt_ {
251251
}
252252
}
253253

254+
pub fn get_llreturn(&mut self) -> BasicBlockRef {
255+
if self.llreturn.is_none() {
256+
self.llreturn = Some(base::mk_return_basic_block(self.llfn));
257+
}
258+
259+
self.llreturn.get()
260+
}
254261
}
255262

256263
pub type fn_ctxt = @mut fn_ctxt_;

branches/snap-stage3/src/librustc/middle/trans/controlflow.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ pub fn trans_break_cont(bcx: block,
279279
// This is a return from a loop body block
280280
None => {
281281
Store(bcx, C_bool(!to_end), bcx.fcx.llretptr.get());
282-
cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn));
282+
cleanup_and_leave(bcx, None, Some(bcx.fcx.get_llreturn()));
283283
Unreachable(bcx);
284284
return bcx;
285285
}
@@ -328,7 +328,7 @@ pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block {
328328
}
329329
_ => ()
330330
}
331-
cleanup_and_leave(bcx, None, Some(bcx.fcx.llreturn));
331+
cleanup_and_leave(bcx, None, Some(bcx.fcx.get_llreturn()));
332332
Unreachable(bcx);
333333
return bcx;
334334
}

branches/snap-stage3/src/librustc/middle/trans/foreign.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,10 @@ fn build_shim_fn_(ccx: @mut CrateContext,
164164
// follow the normal Rust calling conventions.
165165
tie_up_header_blocks(fcx, lltop);
166166

167-
let ret_cx = raw_block(fcx, false, fcx.llreturn);
167+
let ret_cx = match fcx.llreturn {
168+
Some(llreturn) => raw_block(fcx, false, llreturn),
169+
None => bcx
170+
};
168171
RetVoid(ret_cx);
169172

170173
return llshimfn;
@@ -217,7 +220,10 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
217220
tie_up_header_blocks(fcx, lltop);
218221

219222
// Then return according to the C ABI.
220-
let return_context = raw_block(fcx, false, fcx.llreturn);
223+
let return_context = match fcx.llreturn {
224+
Some(llreturn) => raw_block(fcx, false, llreturn),
225+
None => bcx
226+
};
221227

222228
let llfunctiontype = val_ty(llwrapfn);
223229
let llfunctiontype = llfunctiontype.element_type();
@@ -388,7 +394,6 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
388394
tys.ret_def,
389395
llargbundle,
390396
llretval);
391-
build_return(bcx);
392397
}
393398

394399
let lname = link_name(ccx, foreign_item);
@@ -438,8 +443,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
438443
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
439444
Store(bcx, retval, fcx.llretptr.get());
440445
}
441-
build_return(bcx);
442-
finish_fn(fcx, lltop);
446+
finish_fn(fcx, lltop, bcx);
443447
}
444448

445449
// FIXME (#2535): this is very shaky and probably gets ABIs wrong all
@@ -467,8 +471,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
467471
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
468472
Store(bcx, retval, fcx.llretptr.get());
469473
}
470-
build_return(bcx);
471-
finish_fn(fcx, lltop);
474+
finish_fn(fcx, lltop, bcx);
472475
}
473476

474477
fn build_wrap_fn(ccx: @mut CrateContext,
@@ -534,7 +537,6 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
534537
let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]);
535538
Store(bcx, Load(bcx, llretptr), retptr);
536539
}
537-
build_return(bcx);
538540
}
539541
}
540542
}
@@ -629,8 +631,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
629631
}
630632
}
631633

632-
build_return(bcx);
633-
finish_fn(fcx, lltop);
634+
finish_fn(fcx, lltop, bcx);
634635

635636
return;
636637
}
@@ -1124,8 +1125,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
11241125
ccx.sess.span_bug(item.span, "unknown intrinsic");
11251126
}
11261127
}
1127-
build_return(bcx);
1128-
finish_fn(fcx, lltop);
1128+
finish_fn(fcx, lltop, bcx);
11291129
}
11301130

11311131
/**
@@ -1257,8 +1257,6 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
12571257
// NB: The return pointer in the Rust ABI function is wired
12581258
// directly into the return slot in the shim struct.
12591259
}
1260-
1261-
build_return(bcx);
12621260
}
12631261

12641262
let shim_name = link::mangle_internal_name_by_path(
@@ -1314,7 +1312,6 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
13141312
fn build_ret(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) {
13151313
let _icx = push_ctxt("foreign::foreign::wrap::build_ret");
13161314
tys.fn_ty.build_wrap_ret(bcx, tys.llsig.llarg_tys, llargbundle);
1317-
build_return(bcx);
13181315
}
13191316
}
13201317

0 commit comments

Comments
 (0)