@@ -1102,6 +1102,11 @@ pub fn trans_trace(bcx: block, sp_opt: Option<span>, trace_str: @str) {
1102
1102
Call ( bcx, ccx. upcalls. trace, args) ;
1103
1103
}
1104
1104
1105
+ pub fn build_return( bcx: block) {
1106
+ let _icx = push_ctxt( "build_return" ) ;
1107
+ Br ( bcx, bcx. fcx. llreturn) ;
1108
+ }
1109
+
1105
1110
pub fn ignore_lhs( _bcx: block, local: & ast:: local) -> bool {
1106
1111
match local. node. pat. node {
1107
1112
ast:: pat_wild => true , _ => false
@@ -1359,42 +1364,6 @@ pub fn cleanup_and_leave(bcx: block,
1359
1364
}
1360
1365
}
1361
1366
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
-
1398
1367
pub fn cleanup_and_Br( bcx: block, upto: block, target: BasicBlockRef ) {
1399
1368
let _icx = push_ctxt( "cleanup_and_Br" ) ;
1400
1369
cleanup_and_leave( bcx, Some ( upto. llbb) , Some ( target) ) ;
@@ -1557,7 +1526,7 @@ pub fn alloca_maybe_zeroed(cx: block, ty: Type, name: &str, zero: bool) -> Value
1557
1526
return llvm:: LLVMGetUndef ( ty. to_ref( ) ) ;
1558
1527
}
1559
1528
}
1560
- let initcx = base:: raw_block( cx. fcx, false , cx. fcx. get_llstaticallocas ( ) ) ;
1529
+ let initcx = base:: raw_block( cx. fcx, false , cx. fcx. llstaticallocas ) ;
1561
1530
let p = Alloca ( initcx, ty, name) ;
1562
1531
if zero { memzero( initcx, p, ty) ; }
1563
1532
p
@@ -1570,26 +1539,24 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
1570
1539
return llvm:: LLVMGetUndef ( ty. to_ref( ) ) ;
1571
1540
}
1572
1541
}
1573
- return ArrayAlloca ( base:: raw_block( cx. fcx, false , cx. fcx. get_llstaticallocas ( ) ) , ty, v) ;
1542
+ return ArrayAlloca ( base:: raw_block( cx. fcx, false , cx. fcx. llstaticallocas ) , ty, v) ;
1574
1543
}
1575
1544
1576
1545
pub struct BasicBlocks {
1577
1546
sa: BasicBlockRef ,
1547
+ rt: BasicBlockRef
1578
1548
}
1579
1549
1580
- pub fn mk_staticallocas_basic_block( llfn: ValueRef ) -> BasicBlockRef {
1550
+ // Creates the standard set of basic blocks for a function
1551
+ pub fn mk_standard_basic_blocks( llfn: ValueRef ) -> BasicBlocks {
1581
1552
unsafe {
1582
1553
let cx = task_llcx( ) ;
1583
- str :: as_c_str( "static_allocas" ,
1584
- |buf| llvm:: LLVMAppendBasicBlockInContext ( cx, llfn, buf) )
1585
- }
1586
- }
1587
-
1588
- pub fn mk_return_basic_block( llfn: ValueRef ) -> BasicBlockRef {
1589
- unsafe {
1590
- let cx = task_llcx( ) ;
1591
- str :: as_c_str( "return" ,
1592
- |buf| llvm:: LLVMAppendBasicBlockInContext ( cx, llfn, buf) )
1554
+ BasicBlocks {
1555
+ sa: str :: as_c_str( "static_allocas" ,
1556
+ |buf| llvm:: LLVMAppendBasicBlockInContext ( cx, llfn, buf) ) ,
1557
+ rt: str :: as_c_str( "return" ,
1558
+ |buf| llvm:: LLVMAppendBasicBlockInContext ( cx, llfn, buf) )
1559
+ }
1593
1560
}
1594
1561
}
1595
1562
@@ -1601,7 +1568,7 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
1601
1568
llvm:: LLVMGetParam ( fcx. llfn, 0 )
1602
1569
} else {
1603
1570
let lloutputtype = type_of:: type_of( fcx. ccx, output_type) ;
1604
- alloca( raw_block( fcx, false , fcx. get_llstaticallocas ( ) ) , lloutputtype,
1571
+ alloca( raw_block( fcx, false , fcx. llstaticallocas ) , lloutputtype,
1605
1572
"__make_return_pointer" )
1606
1573
}
1607
1574
}
@@ -1629,6 +1596,8 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
1629
1596
id,
1630
1597
param_substs. repr( ccx. tcx) ) ;
1631
1598
1599
+ let llbbs = mk_standard_basic_blocks( llfndecl) ;
1600
+
1632
1601
let substd_output_type = match param_substs {
1633
1602
None => output_type,
1634
1603
Some ( substs) => {
@@ -1642,9 +1611,9 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
1642
1611
llvm:: LLVMGetUndef ( Type :: i8p( ) . to_ref( ) )
1643
1612
} ,
1644
1613
llretptr: None ,
1645
- llstaticallocas: None ,
1614
+ llstaticallocas: llbbs . sa ,
1646
1615
llloadenv: None ,
1647
- llreturn: None ,
1616
+ llreturn: llbbs . rt ,
1648
1617
llself: None ,
1649
1618
personality: None ,
1650
1619
loop_ret: None ,
@@ -1788,24 +1757,16 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
1788
1757
1789
1758
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
1790
1759
// and builds the return block.
1791
- pub fn finish_fn( fcx: fn_ctxt, lltop: BasicBlockRef , last_bcx : block ) {
1760
+ pub fn finish_fn( fcx: fn_ctxt, lltop: BasicBlockRef ) {
1792
1761
let _icx = push_ctxt( "finish_fn" ) ;
1793
1762
tie_up_header_blocks( fcx, lltop) ;
1794
-
1795
- let ret_cx = match fcx. llreturn {
1796
- Some ( llreturn) => {
1797
- if !last_bcx. terminated {
1798
- Br ( last_bcx, llreturn) ;
1799
- }
1800
- raw_block( fcx, false , llreturn)
1801
- }
1802
- None => last_bcx
1803
- } ;
1804
- build_return_block( fcx, ret_cx) ;
1763
+ build_return_block( fcx) ;
1805
1764
}
1806
1765
1807
1766
// Builds the return block for a function.
1808
- pub fn build_return_block( fcx: fn_ctxt, ret_cx: block) {
1767
+ pub fn build_return_block( fcx: fn_ctxt) {
1768
+ let ret_cx = raw_block( fcx, false , fcx. llreturn) ;
1769
+
1809
1770
// Return the value if this function immediate; otherwise, return void.
1810
1771
if fcx. llretptr. is_some( ) && fcx. has_immediate_return_value {
1811
1772
Ret ( ret_cx, Load ( ret_cx, fcx. llretptr. get( ) ) )
@@ -1816,24 +1777,14 @@ pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
1816
1777
1817
1778
pub fn tie_up_header_blocks( fcx: fn_ctxt, lltop: BasicBlockRef ) {
1818
1779
let _icx = push_ctxt( "tie_up_header_blocks" ) ;
1819
- let llnext = match fcx. llloadenv {
1780
+ match fcx. llloadenv {
1820
1781
Some ( ll) => {
1821
- unsafe {
1822
- llvm:: LLVMMoveBasicBlockBefore ( ll, lltop) ;
1823
- }
1782
+ Br ( raw_block( fcx, false , fcx. llstaticallocas) , ll) ;
1824
1783
Br ( raw_block( fcx, false , ll) , lltop) ;
1825
- ll
1826
1784
}
1827
- None => lltop
1828
- } ;
1829
- match fcx. llstaticallocas {
1830
- Some ( ll) => {
1831
- unsafe {
1832
- llvm:: LLVMMoveBasicBlockBefore ( ll, llnext) ;
1833
- }
1834
- Br ( raw_block( fcx, false , ll) , llnext) ;
1785
+ None => {
1786
+ Br ( raw_block( fcx, false , fcx. llstaticallocas) , lltop) ;
1835
1787
}
1836
- None => ( )
1837
1788
}
1838
1789
}
1839
1790
@@ -1903,21 +1854,16 @@ pub fn trans_closure(ccx: @mut CrateContext,
1903
1854
}
1904
1855
1905
1856
finish( bcx) ;
1906
- match fcx. llreturn {
1907
- Some ( llreturn) => cleanup_and_Br( bcx, bcx_top, llreturn) ,
1908
- None => bcx = cleanup_block( bcx, Some ( bcx_top. llbb) )
1909
- } ;
1857
+ cleanup_and_Br( bcx, bcx_top, fcx. llreturn) ;
1910
1858
1911
1859
// Put return block after all other blocks.
1912
1860
// This somewhat improves single-stepping experience in debugger.
1913
1861
unsafe {
1914
- for fcx. llreturn. iter( ) . advance |& llreturn| {
1915
- llvm:: LLVMMoveBasicBlockAfter ( llreturn, bcx. llbb) ;
1916
- }
1862
+ llvm:: LLVMMoveBasicBlockAfter ( fcx. llreturn, bcx. llbb) ;
1917
1863
}
1918
1864
1919
1865
// Insert the mandatory first few basic blocks before lltop.
1920
- finish_fn( fcx, lltop, bcx ) ;
1866
+ finish_fn( fcx, lltop) ;
1921
1867
}
1922
1868
1923
1869
// trans_fn: creates an LLVM function corresponding to a source language
@@ -2100,7 +2046,8 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
2100
2046
let arg_ty = arg_tys[ i] ;
2101
2047
memcpy_ty( bcx, lldestptr, llarg, arg_ty) ;
2102
2048
}
2103
- finish_fn( fcx, lltop, bcx) ;
2049
+ build_return( bcx) ;
2050
+ finish_fn( fcx, lltop) ;
2104
2051
}
2105
2052
2106
2053
pub fn trans_enum_def( ccx: @mut CrateContext , enum_definition: & ast:: enum_def,
@@ -2341,7 +2288,8 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
2341
2288
let args = ~[ llenvarg] ;
2342
2289
Call ( bcx, main_llfn, args) ;
2343
2290
2344
- finish_fn( fcx, lltop, bcx) ;
2291
+ build_return( bcx) ;
2292
+ finish_fn( fcx, lltop) ;
2345
2293
return llfdecl;
2346
2294
}
2347
2295
0 commit comments