@@ -41,6 +41,7 @@ use middle::trans::_match;
41
41
use middle:: trans:: adt;
42
42
use middle:: trans:: base;
43
43
use middle:: trans:: build:: * ;
44
+ use middle:: trans:: builder:: { Builder , noname} ;
44
45
use middle:: trans:: callee;
45
46
use middle:: trans:: common:: * ;
46
47
use middle:: trans:: consts;
@@ -1499,34 +1500,35 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
1499
1500
}
1500
1501
1501
1502
pub fn zero_mem( cx: block, llptr: ValueRef , t: ty:: t) {
1503
+ if cx. unreachable { return ; }
1502
1504
let _icx = push_ctxt( "zero_mem" ) ;
1503
1505
let bcx = cx;
1504
1506
let ccx = cx. ccx( ) ;
1505
1507
let llty = type_of:: type_of( ccx, t) ;
1506
- memzero( bcx, llptr, llty) ;
1508
+ memzero( & B ( bcx) , llptr, llty) ;
1507
1509
}
1508
1510
1509
1511
// Always use this function instead of storing a zero constant to the memory
1510
1512
// in question. If you store a zero constant, LLVM will drown in vreg
1511
1513
// allocation for large data structures, and the generated code will be
1512
1514
// awful. (A telltale sign of this is large quantities of
1513
1515
// `mov [byte ptr foo],0` in the generated code.)
1514
- pub fn memzero( cx : block , llptr: ValueRef , ty: Type ) {
1516
+ pub fn memzero( b : & Builder , llptr: ValueRef , ty: Type ) {
1515
1517
let _icx = push_ctxt( "memzero" ) ;
1516
- let ccx = cx . ccx( ) ;
1518
+ let ccx = b . ccx;
1517
1519
1518
1520
let intrinsic_key = match ccx. sess. targ_cfg. arch {
1519
1521
X86 | Arm | Mips => "llvm.memset.p0i8.i32" ,
1520
1522
X86_64 => "llvm.memset.p0i8.i64"
1521
1523
} ;
1522
1524
1523
1525
let llintrinsicfn = ccx. intrinsics. get_copy( & intrinsic_key) ;
1524
- let llptr = PointerCast ( cx , llptr, Type :: i8 ( ) . ptr_to( ) ) ;
1526
+ let llptr = b . pointercast ( llptr, Type :: i8 ( ) . ptr_to( ) ) ;
1525
1527
let llzeroval = C_u8 ( 0 ) ;
1526
- let size = IntCast ( cx , machine:: llsize_of( ccx, ty) , ccx . int_type ) ;
1528
+ let size = machine:: llsize_of( ccx, ty) ;
1527
1529
let align = C_i32 ( llalign_of_min( ccx, ty) as i32 ) ;
1528
1530
let volatile = C_i1 ( false ) ;
1529
- Call ( cx , llintrinsicfn, [ llptr, llzeroval, size, align, volatile] ) ;
1531
+ b . call ( llintrinsicfn, [ llptr, llzeroval, size, align, volatile] ) ;
1530
1532
}
1531
1533
1532
1534
pub fn alloc_ty( bcx: block, t: ty:: t, name: & str ) -> ValueRef {
@@ -1549,9 +1551,12 @@ pub fn alloca_maybe_zeroed(cx: block, ty: Type, name: &str, zero: bool) -> Value
1549
1551
return llvm:: LLVMGetUndef ( ty. ptr_to( ) . to_ref( ) ) ;
1550
1552
}
1551
1553
}
1552
- let initcx = base:: raw_block( cx. fcx, false , cx. fcx. get_llstaticallocas( ) ) ;
1553
- let p = Alloca ( initcx, ty, name) ;
1554
- if zero { memzero( initcx, p, ty) ; }
1554
+ let p = Alloca ( cx, ty, name) ;
1555
+ if zero {
1556
+ let b = cx. fcx. ccx. builder( ) ;
1557
+ b. position_before( cx. fcx. alloca_insert_pt. get( ) ) ;
1558
+ memzero( & b, p, ty) ;
1559
+ }
1555
1560
p
1556
1561
}
1557
1562
@@ -1562,7 +1567,7 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
1562
1567
return llvm:: LLVMGetUndef ( ty. to_ref( ) ) ;
1563
1568
}
1564
1569
}
1565
- return ArrayAlloca ( base :: raw_block ( cx . fcx , false , cx . fcx . get_llstaticallocas ( ) ) , ty, v) ;
1570
+ return ArrayAlloca ( cx , ty, v) ;
1566
1571
}
1567
1572
1568
1573
pub struct BasicBlocks {
@@ -1593,8 +1598,8 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
1593
1598
llvm:: LLVMGetParam ( fcx. llfn, 0 )
1594
1599
} else {
1595
1600
let lloutputtype = type_of:: type_of( fcx. ccx, output_type) ;
1596
- alloca ( raw_block ( fcx , false , fcx. get_llstaticallocas ( ) ) , lloutputtype ,
1597
- "__make_return_pointer" )
1601
+ let bcx = fcx. entry_bcx . get ( ) ;
1602
+ Alloca ( bcx , lloutputtype , "__make_return_pointer" )
1598
1603
}
1599
1604
}
1600
1605
}
@@ -1612,6 +1617,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
1612
1617
output_type: ty:: t,
1613
1618
skip_retptr: bool ,
1614
1619
param_substs: Option <@param_substs>,
1620
+ opt_node_info: Option <NodeInfo >,
1615
1621
sp: Option <span>)
1616
1622
-> fn_ctxt {
1617
1623
for param_substs. iter( ) . advance |p| { p. validate( ) ; }
@@ -1635,8 +1641,8 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
1635
1641
llvm:: LLVMGetUndef ( Type :: i8p( ) . to_ref( ) )
1636
1642
} ,
1637
1643
llretptr: None ,
1638
- llstaticallocas : None ,
1639
- llloadenv : None ,
1644
+ entry_bcx : None ,
1645
+ alloca_insert_pt : None ,
1640
1646
llreturn: None ,
1641
1647
llself: None ,
1642
1648
personality: None ,
@@ -1654,6 +1660,15 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
1654
1660
fcx. llenv = unsafe {
1655
1661
llvm:: LLVMGetParam ( llfndecl, fcx. env_arg_pos( ) as c_uint)
1656
1662
} ;
1663
+
1664
+ unsafe {
1665
+ let entry_bcx = top_scope_block( fcx, opt_node_info) ;
1666
+ Load ( entry_bcx, C_null ( Type :: i8p( ) ) ) ;
1667
+
1668
+ fcx. entry_bcx = Some ( entry_bcx) ;
1669
+ fcx. alloca_insert_pt = Some ( llvm:: LLVMGetFirstInstruction ( entry_bcx. llbb) ) ;
1670
+ }
1671
+
1657
1672
if !ty:: type_is_nil( substd_output_type) && !( is_immediate && skip_retptr) {
1658
1673
fcx. llretptr = Some ( make_return_pointer( fcx, substd_output_type) ) ;
1659
1674
}
@@ -1666,7 +1681,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
1666
1681
output_type: ty:: t,
1667
1682
sp: Option <span>)
1668
1683
-> fn_ctxt {
1669
- new_fn_ctxt_w_id( ccx, path, llfndecl, -1 , output_type, false , None , sp)
1684
+ new_fn_ctxt_w_id( ccx, path, llfndecl, -1 , output_type, false , None , None , sp)
1670
1685
}
1671
1686
1672
1687
// NB: must keep 4 fns in sync:
@@ -1781,9 +1796,8 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
1781
1796
1782
1797
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
1783
1798
// and builds the return block.
1784
- pub fn finish_fn( fcx: fn_ctxt, lltop : BasicBlockRef , last_bcx: block) {
1799
+ pub fn finish_fn( fcx: fn_ctxt, last_bcx: block) {
1785
1800
let _icx = push_ctxt( "finish_fn" ) ;
1786
- tie_up_header_blocks( fcx, lltop) ;
1787
1801
1788
1802
let ret_cx = match fcx. llreturn {
1789
1803
Some ( llreturn) => {
@@ -1795,6 +1809,7 @@ pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
1795
1809
None => last_bcx
1796
1810
} ;
1797
1811
build_return_block( fcx, ret_cx) ;
1812
+ fcx. cleanup( ) ;
1798
1813
}
1799
1814
1800
1815
// Builds the return block for a function.
@@ -1807,29 +1822,6 @@ pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
1807
1822
}
1808
1823
}
1809
1824
1810
- pub fn tie_up_header_blocks( fcx: fn_ctxt, lltop: BasicBlockRef ) {
1811
- let _icx = push_ctxt( "tie_up_header_blocks" ) ;
1812
- let llnext = match fcx. llloadenv {
1813
- Some ( ll) => {
1814
- unsafe {
1815
- llvm:: LLVMMoveBasicBlockBefore ( ll, lltop) ;
1816
- }
1817
- Br ( raw_block( fcx, false , ll) , lltop) ;
1818
- ll
1819
- }
1820
- None => lltop
1821
- } ;
1822
- match fcx. llstaticallocas {
1823
- Some ( ll) => {
1824
- unsafe {
1825
- llvm:: LLVMMoveBasicBlockBefore ( ll, llnext) ;
1826
- }
1827
- Br ( raw_block( fcx, false , ll) , llnext) ;
1828
- }
1829
- None => ( )
1830
- }
1831
- }
1832
-
1833
1825
pub enum self_arg { impl_self( ty:: t, ty:: SelfMode ) , no_self, }
1834
1826
1835
1827
// trans_closure: Builds an LLVM function out of a source function.
@@ -1862,6 +1854,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
1862
1854
output_type,
1863
1855
false ,
1864
1856
param_substs,
1857
+ body. info( ) ,
1865
1858
Some ( body. span) ) ;
1866
1859
let raw_llargs = create_llargs_for_fn_args( fcx, self_arg, decl. inputs) ;
1867
1860
@@ -1873,9 +1866,8 @@ pub fn trans_closure(ccx: @mut CrateContext,
1873
1866
1874
1867
// Create the first basic block in the function and keep a handle on it to
1875
1868
// pass to finish_fn later.
1876
- let bcx_top = top_scope_block ( fcx, body . info ( ) ) ;
1869
+ let bcx_top = fcx. entry_bcx . get ( ) ;
1877
1870
let mut bcx = bcx_top;
1878
- let lltop = bcx. llbb;
1879
1871
let block_ty = node_id_type( bcx, body. id) ;
1880
1872
1881
1873
let arg_tys = ty:: ty_fn_args( node_id_type( bcx, id) ) ;
@@ -1911,7 +1903,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
1911
1903
}
1912
1904
1913
1905
// Insert the mandatory first few basic blocks before lltop.
1914
- finish_fn( fcx, lltop , bcx) ;
1906
+ finish_fn( fcx, bcx) ;
1915
1907
}
1916
1908
1917
1909
// trans_fn: creates an LLVM function corresponding to a source language
@@ -2081,12 +2073,12 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
2081
2073
result_ty,
2082
2074
false ,
2083
2075
param_substs,
2076
+ None ,
2084
2077
None ) ;
2085
2078
2086
2079
let raw_llargs = create_llargs_for_fn_args( fcx, no_self, fn_args) ;
2087
2080
2088
- let bcx = top_scope_block( fcx, None ) ;
2089
- let lltop = bcx. llbb;
2081
+ let bcx = fcx. entry_bcx. get( ) ;
2090
2082
let arg_tys = ty:: ty_fn_args( ctor_ty) ;
2091
2083
2092
2084
insert_synthetic_type_entries( bcx, fn_args, arg_tys) ;
@@ -2104,7 +2096,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
2104
2096
let arg_ty = arg_tys[ i] ;
2105
2097
memcpy_ty( bcx, lldestptr, llarg, arg_ty) ;
2106
2098
}
2107
- finish_fn( fcx, lltop , bcx) ;
2099
+ finish_fn( fcx, bcx) ;
2108
2100
}
2109
2101
2110
2102
pub fn trans_enum_def( ccx: @mut CrateContext , enum_definition: & ast:: enum_def,
@@ -2332,9 +2324,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
2332
2324
// be updated if this assertion starts to fail.
2333
2325
assert!( fcx. has_immediate_return_value) ;
2334
2326
2335
- let bcx = top_scope_block( fcx, None ) ;
2336
- let lltop = bcx. llbb;
2337
-
2327
+ let bcx = fcx. entry_bcx. get( ) ;
2338
2328
// Call main.
2339
2329
let llenvarg = unsafe {
2340
2330
let env_arg = fcx. env_arg_pos( ) ;
@@ -2343,7 +2333,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
2343
2333
let args = ~[ llenvarg] ;
2344
2334
Call ( bcx, main_llfn, args) ;
2345
2335
2346
- finish_fn( fcx, lltop , bcx) ;
2336
+ finish_fn( fcx, bcx) ;
2347
2337
return llfdecl;
2348
2338
}
2349
2339
0 commit comments