@@ -41,6 +41,7 @@ use middle::trans::_match;
4141use middle:: trans:: adt;
4242use middle:: trans:: base;
4343use middle:: trans:: build:: * ;
44+ use middle:: trans:: builder:: { Builder , noname} ;
4445use middle:: trans:: callee;
4546use middle:: trans:: common:: * ;
4647use middle:: trans:: consts;
@@ -1499,34 +1500,35 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
14991500}
15001501
15011502pub fn zero_mem( cx: block, llptr: ValueRef , t: ty:: t) {
1503+ if cx. unreachable { return ; }
15021504 let _icx = push_ctxt( "zero_mem" ) ;
15031505 let bcx = cx;
15041506 let ccx = cx. ccx( ) ;
15051507 let llty = type_of:: type_of( ccx, t) ;
1506- memzero( bcx, llptr, llty) ;
1508+ memzero( & B ( bcx) , llptr, llty) ;
15071509}
15081510
15091511// Always use this function instead of storing a zero constant to the memory
15101512// in question. If you store a zero constant, LLVM will drown in vreg
15111513// allocation for large data structures, and the generated code will be
15121514// awful. (A telltale sign of this is large quantities of
15131515// `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 ) {
15151517 let _icx = push_ctxt( "memzero" ) ;
1516- let ccx = cx . ccx( ) ;
1518+ let ccx = b . ccx;
15171519
15181520 let intrinsic_key = match ccx. sess. targ_cfg. arch {
15191521 X86 | Arm | Mips => "llvm.memset.p0i8.i32" ,
15201522 X86_64 => "llvm.memset.p0i8.i64"
15211523 } ;
15221524
15231525 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( ) ) ;
15251527 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) ;
15271529 let align = C_i32 ( llalign_of_min( ccx, ty) as i32 ) ;
15281530 let volatile = C_i1 ( false ) ;
1529- Call ( cx , llintrinsicfn, [ llptr, llzeroval, size, align, volatile] ) ;
1531+ b . call ( llintrinsicfn, [ llptr, llzeroval, size, align, volatile] ) ;
15301532}
15311533
15321534pub 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
15491551 return llvm:: LLVMGetUndef ( ty. ptr_to( ) . to_ref( ) ) ;
15501552 }
15511553 }
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+ }
15551560 p
15561561}
15571562
@@ -1562,7 +1567,7 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
15621567 return llvm:: LLVMGetUndef ( ty. to_ref( ) ) ;
15631568 }
15641569 }
1565- return ArrayAlloca ( base :: raw_block ( cx . fcx , false , cx . fcx . get_llstaticallocas ( ) ) , ty, v) ;
1570+ return ArrayAlloca ( cx , ty, v) ;
15661571}
15671572
15681573pub struct BasicBlocks {
@@ -1593,8 +1598,8 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
15931598 llvm:: LLVMGetParam ( fcx. llfn, 0 )
15941599 } else {
15951600 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" )
15981603 }
15991604 }
16001605}
@@ -1612,6 +1617,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16121617 output_type: ty:: t,
16131618 skip_retptr: bool ,
16141619 param_substs: Option <@param_substs>,
1620+ opt_node_info: Option <NodeInfo >,
16151621 sp: Option <span>)
16161622 -> fn_ctxt {
16171623 for param_substs. iter( ) . advance |p| { p. validate( ) ; }
@@ -1635,8 +1641,8 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16351641 llvm:: LLVMGetUndef ( Type :: i8p( ) . to_ref( ) )
16361642 } ,
16371643 llretptr: None ,
1638- llstaticallocas : None ,
1639- llloadenv : None ,
1644+ entry_bcx : None ,
1645+ alloca_insert_pt : None ,
16401646 llreturn: None ,
16411647 llself: None ,
16421648 personality: None ,
@@ -1654,6 +1660,15 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16541660 fcx. llenv = unsafe {
16551661 llvm:: LLVMGetParam ( llfndecl, fcx. env_arg_pos( ) as c_uint)
16561662 } ;
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+
16571672 if !ty:: type_is_nil( substd_output_type) && !( is_immediate && skip_retptr) {
16581673 fcx. llretptr = Some ( make_return_pointer( fcx, substd_output_type) ) ;
16591674 }
@@ -1666,7 +1681,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
16661681 output_type: ty:: t,
16671682 sp: Option <span>)
16681683 -> 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)
16701685}
16711686
16721687// NB: must keep 4 fns in sync:
@@ -1781,9 +1796,8 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
17811796
17821797// Ties up the llstaticallocas -> llloadenv -> lltop edges,
17831798// 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) {
17851800 let _icx = push_ctxt( "finish_fn" ) ;
1786- tie_up_header_blocks( fcx, lltop) ;
17871801
17881802 let ret_cx = match fcx. llreturn {
17891803 Some ( llreturn) => {
@@ -1795,6 +1809,7 @@ pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
17951809 None => last_bcx
17961810 } ;
17971811 build_return_block( fcx, ret_cx) ;
1812+ fcx. cleanup( ) ;
17981813}
17991814
18001815// Builds the return block for a function.
@@ -1807,29 +1822,6 @@ pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
18071822 }
18081823}
18091824
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-
18331825pub enum self_arg { impl_self( ty:: t, ty:: SelfMode ) , no_self, }
18341826
18351827// trans_closure: Builds an LLVM function out of a source function.
@@ -1862,6 +1854,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
18621854 output_type,
18631855 false ,
18641856 param_substs,
1857+ body. info( ) ,
18651858 Some ( body. span) ) ;
18661859 let raw_llargs = create_llargs_for_fn_args( fcx, self_arg, decl. inputs) ;
18671860
@@ -1873,9 +1866,8 @@ pub fn trans_closure(ccx: @mut CrateContext,
18731866
18741867 // Create the first basic block in the function and keep a handle on it to
18751868 // pass to finish_fn later.
1876- let bcx_top = top_scope_block ( fcx, body . info ( ) ) ;
1869+ let bcx_top = fcx. entry_bcx . get ( ) ;
18771870 let mut bcx = bcx_top;
1878- let lltop = bcx. llbb;
18791871 let block_ty = node_id_type( bcx, body. id) ;
18801872
18811873 let arg_tys = ty:: ty_fn_args( node_id_type( bcx, id) ) ;
@@ -1911,7 +1903,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
19111903 }
19121904
19131905 // Insert the mandatory first few basic blocks before lltop.
1914- finish_fn( fcx, lltop , bcx) ;
1906+ finish_fn( fcx, bcx) ;
19151907}
19161908
19171909// 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>(
20812073 result_ty,
20822074 false ,
20832075 param_substs,
2076+ None ,
20842077 None ) ;
20852078
20862079 let raw_llargs = create_llargs_for_fn_args( fcx, no_self, fn_args) ;
20872080
2088- let bcx = top_scope_block( fcx, None ) ;
2089- let lltop = bcx. llbb;
2081+ let bcx = fcx. entry_bcx. get( ) ;
20902082 let arg_tys = ty:: ty_fn_args( ctor_ty) ;
20912083
20922084 insert_synthetic_type_entries( bcx, fn_args, arg_tys) ;
@@ -2104,7 +2096,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
21042096 let arg_ty = arg_tys[ i] ;
21052097 memcpy_ty( bcx, lldestptr, llarg, arg_ty) ;
21062098 }
2107- finish_fn( fcx, lltop , bcx) ;
2099+ finish_fn( fcx, bcx) ;
21082100}
21092101
21102102pub fn trans_enum_def( ccx: @mut CrateContext , enum_definition: & ast:: enum_def,
@@ -2332,9 +2324,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23322324 // be updated if this assertion starts to fail.
23332325 assert!( fcx. has_immediate_return_value) ;
23342326
2335- let bcx = top_scope_block( fcx, None ) ;
2336- let lltop = bcx. llbb;
2337-
2327+ let bcx = fcx. entry_bcx. get( ) ;
23382328 // Call main.
23392329 let llenvarg = unsafe {
23402330 let env_arg = fcx. env_arg_pos( ) ;
@@ -2343,7 +2333,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23432333 let args = ~[ llenvarg] ;
23442334 Call ( bcx, main_llfn, args) ;
23452335
2346- finish_fn( fcx, lltop , bcx) ;
2336+ finish_fn( fcx, bcx) ;
23472337 return llfdecl;
23482338 }
23492339
0 commit comments