]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/trans/base.rs
auto merge of #7903 : michaelwoerister/rust/end_of_spanned, r=jdm
[rust.git] / src / librustc / middle / trans / base.rs
index 8ba0dfa671650c51c193a7a0eb047dda5d2ad3a1..32a5ebe0c39cb100bd884a200a6c5ed4ca9e37c0 100644 (file)
@@ -41,6 +41,7 @@
 use middle::trans::adt;
 use middle::trans::base;
 use middle::trans::build::*;
+use middle::trans::builder::{Builder, noname};
 use middle::trans::callee;
 use middle::trans::common::*;
 use middle::trans::consts;
@@ -1499,11 +1500,12 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
 }
 
 pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) {
+    if cx.unreachable { return; }
     let _icx = push_ctxt("zero_mem");
     let bcx = cx;
     let ccx = cx.ccx();
     let llty = type_of::type_of(ccx, t);
-    memzero(bcx, llptr, llty);
+    memzero(&B(bcx), llptr, llty);
 }
 
 // Always use this function instead of storing a zero constant to the memory
@@ -1511,9 +1513,9 @@ pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) {
 // allocation for large data structures, and the generated code will be
 // awful. (A telltale sign of this is large quantities of
 // `mov [byte ptr foo],0` in the generated code.)
-pub fn memzero(cx: block, llptr: ValueRef, ty: Type) {
+pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
     let _icx = push_ctxt("memzero");
-    let ccx = cx.ccx();
+    let ccx = b.ccx;
 
     let intrinsic_key = match ccx.sess.targ_cfg.arch {
         X86 | Arm | Mips => "llvm.memset.p0i8.i32",
@@ -1521,12 +1523,12 @@ pub fn memzero(cx: block, llptr: ValueRef, ty: Type) {
     };
 
     let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key);
-    let llptr = PointerCast(cx, llptr, Type::i8().ptr_to());
+    let llptr = b.pointercast(llptr, Type::i8().ptr_to());
     let llzeroval = C_u8(0);
-    let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type);
+    let size = machine::llsize_of(ccx, ty);
     let align = C_i32(llalign_of_min(ccx, ty) as i32);
     let volatile = C_i1(false);
-    Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
+    b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
 }
 
 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
             return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
         }
     }
-    let initcx = base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas());
-    let p = Alloca(initcx, ty, name);
-    if zero { memzero(initcx, p, ty); }
+    let p = Alloca(cx, ty, name);
+    if zero {
+        let b = cx.fcx.ccx.builder();
+        b.position_before(cx.fcx.alloca_insert_pt.get());
+        memzero(&b, p, ty);
+    }
     p
 }
 
@@ -1562,7 +1567,7 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
             return llvm::LLVMGetUndef(ty.to_ref());
         }
     }
-    return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas()), ty, v);
+    return ArrayAlloca(cx, ty, v);
 }
 
 pub struct BasicBlocks {
@@ -1593,8 +1598,8 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
             llvm::LLVMGetParam(fcx.llfn, 0)
         } else {
             let lloutputtype = type_of::type_of(fcx.ccx, output_type);
-            alloca(raw_block(fcx, false, fcx.get_llstaticallocas()), lloutputtype,
-                   "__make_return_pointer")
+            let bcx = fcx.entry_bcx.get();
+            Alloca(bcx, lloutputtype, "__make_return_pointer")
         }
     }
 }
@@ -1612,6 +1617,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
                         output_type: ty::t,
                         skip_retptr: bool,
                         param_substs: Option<@param_substs>,
+                        opt_node_info: Option<NodeInfo>,
                         sp: Option<span>)
                      -> fn_ctxt {
     for param_substs.iter().advance |p| { p.validate(); }
@@ -1635,8 +1641,8 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
               llvm::LLVMGetUndef(Type::i8p().to_ref())
           },
           llretptr: None,
-          llstaticallocas: None,
-          llloadenv: None,
+          entry_bcx: None,
+          alloca_insert_pt: None,
           llreturn: None,
           llself: None,
           personality: None,
@@ -1654,6 +1660,15 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
     fcx.llenv = unsafe {
           llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
     };
+
+    unsafe {
+        let entry_bcx = top_scope_block(fcx, opt_node_info);
+        Load(entry_bcx, C_null(Type::i8p()));
+
+        fcx.entry_bcx = Some(entry_bcx);
+        fcx.alloca_insert_pt = Some(llvm::LLVMGetFirstInstruction(entry_bcx.llbb));
+    }
+
     if !ty::type_is_nil(substd_output_type) && !(is_immediate && skip_retptr) {
         fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
     }
@@ -1666,7 +1681,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
                    output_type: ty::t,
                    sp: Option<span>)
                 -> fn_ctxt {
-    new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, sp)
+    new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, None, sp)
 }
 
 // NB: must keep 4 fns in sync:
@@ -1781,9 +1796,8 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
 
 // Ties up the llstaticallocas -> llloadenv -> lltop edges,
 // and builds the return block.
-pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
+pub fn finish_fn(fcx: fn_ctxt, last_bcx: block) {
     let _icx = push_ctxt("finish_fn");
-    tie_up_header_blocks(fcx, lltop);
 
     let ret_cx = match fcx.llreturn {
         Some(llreturn) => {
@@ -1795,6 +1809,7 @@ pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
         None => last_bcx
     };
     build_return_block(fcx, ret_cx);
+    fcx.cleanup();
 }
 
 // Builds the return block for a function.
@@ -1807,29 +1822,6 @@ pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
     }
 }
 
-pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) {
-    let _icx = push_ctxt("tie_up_header_blocks");
-    let llnext = match fcx.llloadenv {
-        Some(ll) => {
-            unsafe {
-                llvm::LLVMMoveBasicBlockBefore(ll, lltop);
-            }
-            Br(raw_block(fcx, false, ll), lltop);
-            ll
-        }
-        None => lltop
-    };
-    match fcx.llstaticallocas {
-        Some(ll) => {
-            unsafe {
-                llvm::LLVMMoveBasicBlockBefore(ll, llnext);
-            }
-            Br(raw_block(fcx, false, ll), llnext);
-        }
-        None => ()
-    }
-}
-
 pub enum self_arg { impl_self(ty::t, ty::SelfMode), no_self, }
 
 // trans_closure: Builds an LLVM function out of a source function.
@@ -1862,6 +1854,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
                                output_type,
                                false,
                                param_substs,
+                               body.info(),
                                Some(body.span));
     let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs);
 
@@ -1873,9 +1866,8 @@ pub fn trans_closure(ccx: @mut CrateContext,
 
     // Create the first basic block in the function and keep a handle on it to
     //  pass to finish_fn later.
-    let bcx_top = top_scope_block(fcx, body.info());
+    let bcx_top = fcx.entry_bcx.get();
     let mut bcx = bcx_top;
-    let lltop = bcx.llbb;
     let block_ty = node_id_type(bcx, body.id);
 
     let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
@@ -1911,7 +1903,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
     }
 
     // Insert the mandatory first few basic blocks before lltop.
-    finish_fn(fcx, lltop, bcx);
+    finish_fn(fcx, bcx);
 }
 
 // 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>(
                                result_ty,
                                false,
                                param_substs,
+                               None,
                                None);
 
     let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
 
-    let bcx = top_scope_block(fcx, None);
-    let lltop = bcx.llbb;
+    let bcx = fcx.entry_bcx.get();
     let arg_tys = ty::ty_fn_args(ctor_ty);
 
     insert_synthetic_type_entries(bcx, fn_args, arg_tys);
@@ -2104,7 +2096,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
         let arg_ty = arg_tys[i];
         memcpy_ty(bcx, lldestptr, llarg, arg_ty);
     }
-    finish_fn(fcx, lltop, bcx);
+    finish_fn(fcx, bcx);
 }
 
 pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
@@ -2332,9 +2324,7 @@ fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
         // be updated if this assertion starts to fail.
         assert!(fcx.has_immediate_return_value);
 
-        let bcx = top_scope_block(fcx, None);
-        let lltop = bcx.llbb;
-
+        let bcx = fcx.entry_bcx.get();
         // Call main.
         let llenvarg = unsafe {
             let env_arg = fcx.env_arg_pos();
@@ -2343,7 +2333,7 @@ fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
         let args = ~[llenvarg];
         Call(bcx, main_llfn, args);
 
-        finish_fn(fcx, lltop, bcx);
+        finish_fn(fcx, bcx);
         return llfdecl;
     }