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