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