about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMark-Simulacrum <mark.simulacrum@gmail.com>2016-12-16 16:00:17 -0700
committerMark Simulacrum <mark.simulacrum@gmail.com>2016-12-20 20:03:27 -0700
commitcbbdb73eb07fb9a29e20f4fb16b8f1c059e9763f (patch)
tree0071e279eff97c161971464d7149491f7ce33b82 /src
parentbf8614b55ad248c254be6c00f4eba1f88ac97740 (diff)
downloadrust-cbbdb73eb07fb9a29e20f4fb16b8f1c059e9763f.tar.gz
rust-cbbdb73eb07fb9a29e20f4fb16b8f1c059e9763f.zip
Remove FunctionContext::cleanup, replacing it with a Drop impl.
Move alloca and initial entry block creation into FunctionContext::new.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_llvm/ffi.rs1
-rw-r--r--src/librustc_trans/base.rs1
-rw-r--r--src/librustc_trans/common.rs49
-rw-r--r--src/librustc_trans/intrinsic.rs1
-rw-r--r--src/librustc_trans/mir/mod.rs2
5 files changed, 28 insertions, 26 deletions
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index f3d4c17654d..d2b86ade7a2 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -710,6 +710,7 @@ extern "C" {
 
     // Operations on instructions
     pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
+    pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
     pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
     pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
 
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 6aee8fa5f97..e8a75d26534 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -653,7 +653,6 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
     /// and builds the return block.
     pub fn finish(&'blk self, ret_cx: &BlockAndBuilder<'blk, 'tcx>) {
         self.build_return_block(ret_cx);
-        self.cleanup();
     }
 
     // Builds the return block for a function.
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index 5d490307552..11c995accc5 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -283,7 +283,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
     // the function, due to LLVM's quirks.
     // A marker for the place where we want to insert the function's static
     // allocas, so that LLVM will coalesce them into a single alloca call.
-    pub alloca_insert_pt: Cell<Option<ValueRef>>,
+    alloca_insert_pt: Option<ValueRef>,
 
     // When working with landingpad-based exceptions this value is alloca'd and
     // later loaded when using the resume instruction. This ends up being
@@ -347,35 +347,37 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
             debuginfo::empty_function_debug_context(ccx)
         };
 
-        FunctionContext {
+        let mut fcx = FunctionContext {
             mir: mir,
             llfn: llfndecl,
             llretslotptr: Cell::new(None),
             param_env: ccx.tcx().empty_parameter_environment(),
-            alloca_insert_pt: Cell::new(None),
+            alloca_insert_pt: None,
             landingpad_alloca: Cell::new(None),
             fn_ty: fn_ty,
             param_substs: param_substs,
             ccx: ccx,
             debug_context: debug_context,
             alloca_builder: OwnedBuilder::new_with_ccx(ccx),
-        }
-    }
+        };
 
-    /// Performs setup on a newly created function, creating the entry
-    /// scope block and allocating space for the return pointer.
-    pub fn init(&'a self, skip_retptr: bool) -> BlockAndBuilder<'a, 'tcx> {
-        let entry_bcx = self.build_new_block("entry-block");
+        let val = {
+            let entry_bcx = fcx.build_new_block("entry-block");
+            let val = entry_bcx.load(C_null(Type::i8p(ccx)));
+            fcx.alloca_builder.builder.position_at_start(entry_bcx.llbb());
+            val
+        };
 
         // Use a dummy instruction as the insertion point for all allocas.
-        // This is later removed in FunctionContext::cleanup.
-        self.alloca_insert_pt.set(Some(unsafe {
-            entry_bcx.load(C_null(Type::i8p(self.ccx)));
-            llvm::LLVMGetFirstInstruction(entry_bcx.llbb())
-        }));
+        // This is later removed in the drop of FunctionContext.
+        fcx.alloca_insert_pt = Some(val);
 
-        self.alloca_builder.builder.position_at_start(entry_bcx.llbb());
+        fcx
+    }
 
+    /// Performs setup on a newly created function, creating the entry
+    /// scope block and allocating space for the return pointer.
+    pub fn init(&'a self, skip_retptr: bool) -> BlockAndBuilder<'a, 'tcx> {
         if !self.fn_ty.ret.is_ignore() && !skip_retptr {
             // We normally allocate the llretslotptr, unless we
             // have been instructed to skip it for immediate return
@@ -395,19 +397,15 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
             self.llretslotptr.set(Some(slot));
         }
 
-        entry_bcx
+        BlockAndBuilder::new(unsafe {
+            llvm::LLVMGetFirstBasicBlock(self.llfn)
+        }, self)
     }
 
     pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
         self.mir.as_ref().map(Ref::clone).expect("fcx.mir was empty")
     }
 
-    pub fn cleanup(&self) {
-        unsafe {
-            llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt.get().unwrap());
-        }
-    }
-
     pub fn new_block(&'a self, name: &str) -> BasicBlockRef {
         unsafe {
             let name = CString::new(name).unwrap();
@@ -517,6 +515,13 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
     }
 }
 
+impl<'a, 'tcx> Drop for FunctionContext<'a, 'tcx> {
+    fn drop(&mut self) {
+        unsafe {
+            llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt.unwrap());
+        }
+    }
+}
 
 pub struct OwnedBuilder<'blk, 'tcx: 'blk> {
     builder: Builder<'blk, 'tcx>
diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs
index 84a6406c8e7..716cbec718e 100644
--- a/src/librustc_trans/intrinsic.rs
+++ b/src/librustc_trans/intrinsic.rs
@@ -967,7 +967,6 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
     let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty);
     let fcx = FunctionContext::new(ccx, llfn, fn_ty, None);
     trans(fcx.init(true));
-    fcx.cleanup();
     llfn
 }
 
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index c721fa0d2ac..6c72791ec0f 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -306,8 +306,6 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
             block.delete();
         }
     }
-
-    fcx.cleanup();
 }
 
 /// Produce, for each argument, a `ValueRef` pointing at the