@@ -41,7 +41,7 @@ use middle::trans::_match;
4141use middle:: trans:: adt;
4242use middle:: trans:: base;
4343use middle:: trans:: build:: * ;
44- use middle:: trans:: builder:: noname;
44+ use middle:: trans:: builder:: { Builder , noname} ;
4545use middle:: trans:: callee;
4646use middle:: trans:: common:: * ;
4747use middle:: trans:: consts;
@@ -1503,34 +1503,35 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
15031503}
15041504
15051505pub fn zero_mem( cx: block, llptr: ValueRef , t: ty:: t) {
1506+ if cx. unreachable { return ; }
15061507 let _icx = push_ctxt( "zero_mem" ) ;
15071508 let bcx = cx;
15081509 let ccx = cx. ccx( ) ;
15091510 let llty = type_of:: type_of( ccx, t) ;
1510- memzero( bcx, llptr, llty) ;
1511+ memzero( & B ( bcx) , llptr, llty) ;
15111512}
15121513
15131514// Always use this function instead of storing a zero constant to the memory
15141515// in question. If you store a zero constant, LLVM will drown in vreg
15151516// allocation for large data structures, and the generated code will be
15161517// awful. (A telltale sign of this is large quantities of
15171518// `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 ) {
15191520 let _icx = push_ctxt( "memzero" ) ;
1520- let ccx = cx . ccx( ) ;
1521+ let ccx = b . ccx;
15211522
15221523 let intrinsic_key = match ccx. sess. targ_cfg. arch {
15231524 X86 | Arm | Mips => "llvm.memset.p0i8.i32" ,
15241525 X86_64 => "llvm.memset.p0i8.i64"
15251526 } ;
15261527
15271528 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( ) ) ;
15291530 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) ;
15311532 let align = C_i32 ( llalign_of_min( ccx, ty) as i32 ) ;
15321533 let volatile = C_i1 ( false ) ;
1533- Call ( cx , llintrinsicfn, [ llptr, llzeroval, size, align, volatile] ) ;
1534+ b . call ( llintrinsicfn, [ llptr, llzeroval, size, align, volatile] ) ;
15341535}
15351536
15361537pub 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
15531554 return llvm:: LLVMGetUndef ( ty. ptr_to( ) . to_ref( ) ) ;
15541555 }
15551556 }
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+ }
15591563 p
15601564}
15611565
@@ -1566,7 +1570,7 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
15661570 return llvm:: LLVMGetUndef ( ty. to_ref( ) ) ;
15671571 }
15681572 }
1569- return ArrayAlloca ( base :: raw_block ( cx . fcx , false , cx . fcx . get_llstaticallocas ( ) ) , ty, v) ;
1573+ return ArrayAlloca ( cx , ty, v) ;
15701574}
15711575
15721576pub struct BasicBlocks {
@@ -1597,8 +1601,8 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
15971601 llvm:: LLVMGetParam ( fcx. llfn, 0 )
15981602 } else {
15991603 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" )
16021606 }
16031607 }
16041608}
@@ -1616,6 +1620,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16161620 output_type: ty:: t,
16171621 skip_retptr: bool ,
16181622 param_substs: Option <@param_substs>,
1623+ opt_node_info: Option <NodeInfo >,
16191624 sp: Option <span>)
16201625 -> fn_ctxt {
16211626 for param_substs. iter( ) . advance |p| { p. validate( ) ; }
@@ -1639,8 +1644,8 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16391644 llvm:: LLVMGetUndef ( Type :: i8p( ) . to_ref( ) )
16401645 } ,
16411646 llretptr: None ,
1642- llstaticallocas : None ,
1643- llloadenv : None ,
1647+ entry_bcx : None ,
1648+ alloca_insert_pt : None ,
16441649 llreturn: None ,
16451650 llself: None ,
16461651 personality: None ,
@@ -1658,6 +1663,15 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16581663 fcx. llenv = unsafe {
16591664 llvm:: LLVMGetParam ( llfndecl, fcx. env_arg_pos( ) as c_uint)
16601665 } ;
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+
16611675 if !ty:: type_is_nil( substd_output_type) && !( is_immediate && skip_retptr) {
16621676 fcx. llretptr = Some ( make_return_pointer( fcx, substd_output_type) ) ;
16631677 }
@@ -1670,7 +1684,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
16701684 output_type: ty:: t,
16711685 sp: Option <span>)
16721686 -> 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)
16741688}
16751689
16761690// NB: must keep 4 fns in sync:
@@ -1785,9 +1799,8 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
17851799
17861800// Ties up the llstaticallocas -> llloadenv -> lltop edges,
17871801// 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) {
17891803 let _icx = push_ctxt( "finish_fn" ) ;
1790- tie_up_header_blocks( fcx, lltop) ;
17911804
17921805 let ret_cx = match fcx. llreturn {
17931806 Some ( llreturn) => {
@@ -1799,6 +1812,7 @@ pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
17991812 None => last_bcx
18001813 } ;
18011814 build_return_block( fcx, ret_cx) ;
1815+ fcx. cleanup( ) ;
18021816}
18031817
18041818// Builds the return block for a function.
@@ -1811,29 +1825,6 @@ pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
18111825 }
18121826}
18131827
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-
18371828pub enum self_arg { impl_self( ty:: t, ty:: SelfMode ) , no_self, }
18381829
18391830// trans_closure: Builds an LLVM function out of a source function.
@@ -1866,6 +1857,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
18661857 output_type,
18671858 false ,
18681859 param_substs,
1860+ body. info( ) ,
18691861 Some ( body. span) ) ;
18701862 let raw_llargs = create_llargs_for_fn_args( fcx, self_arg, decl. inputs) ;
18711863
@@ -1877,9 +1869,8 @@ pub fn trans_closure(ccx: @mut CrateContext,
18771869
18781870 // Create the first basic block in the function and keep a handle on it to
18791871 // pass to finish_fn later.
1880- let bcx_top = top_scope_block ( fcx, body . info ( ) ) ;
1872+ let bcx_top = fcx. entry_bcx . get ( ) ;
18811873 let mut bcx = bcx_top;
1882- let lltop = bcx. llbb;
18831874 let block_ty = node_id_type( bcx, body. id) ;
18841875
18851876 let arg_tys = ty:: ty_fn_args( node_id_type( bcx, id) ) ;
@@ -1915,7 +1906,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
19151906 }
19161907
19171908 // Insert the mandatory first few basic blocks before lltop.
1918- finish_fn( fcx, lltop , bcx) ;
1909+ finish_fn( fcx, bcx) ;
19191910}
19201911
19211912// 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>(
20852076 result_ty,
20862077 false ,
20872078 param_substs,
2079+ None ,
20882080 None ) ;
20892081
20902082 let raw_llargs = create_llargs_for_fn_args( fcx, no_self, fn_args) ;
20912083
2092- let bcx = top_scope_block( fcx, None ) ;
2093- let lltop = bcx. llbb;
2084+ let bcx = fcx. entry_bcx. get( ) ;
20942085 let arg_tys = ty:: ty_fn_args( ctor_ty) ;
20952086
20962087 insert_synthetic_type_entries( bcx, fn_args, arg_tys) ;
@@ -2108,7 +2099,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
21082099 let arg_ty = arg_tys[ i] ;
21092100 memcpy_ty( bcx, lldestptr, llarg, arg_ty) ;
21102101 }
2111- finish_fn( fcx, lltop , bcx) ;
2102+ finish_fn( fcx, bcx) ;
21122103}
21132104
21142105pub fn trans_enum_def( ccx: @mut CrateContext , enum_definition: & ast:: enum_def,
@@ -2336,9 +2327,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23362327 // be updated if this assertion starts to fail.
23372328 assert!( fcx. has_immediate_return_value) ;
23382329
2339- let bcx = top_scope_block( fcx, None ) ;
2340- let lltop = bcx. llbb;
2341-
2330+ let bcx = fcx. entry_bcx. get( ) ;
23422331 // Call main.
23432332 let llenvarg = unsafe {
23442333 let env_arg = fcx. env_arg_pos( ) ;
@@ -2347,7 +2336,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23472336 let args = ~[ llenvarg] ;
23482337 Call ( bcx, main_llfn, args) ;
23492338
2350- finish_fn( fcx, lltop , bcx) ;
2339+ finish_fn( fcx, bcx) ;
23512340 return llfdecl;
23522341 }
23532342
0 commit comments