about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trans/basic_block.rs6
-rw-r--r--src/librustc_trans/mir/mod.rs17
2 files changed, 16 insertions, 7 deletions
diff --git a/src/librustc_trans/basic_block.rs b/src/librustc_trans/basic_block.rs
index 919ea49b392..60bd3fb8ef1 100644
--- a/src/librustc_trans/basic_block.rs
+++ b/src/librustc_trans/basic_block.rs
@@ -49,4 +49,10 @@ impl BasicBlock {
             _ => None
         }
     }
+
+    pub fn delete(self) {
+        unsafe {
+            llvm::LLVMDeleteBasicBlock(self.0);
+        }
+    }
 }
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index 27e09d04a9d..e1a0d33fa13 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -19,6 +19,8 @@ use common::{self, Block, BlockAndBuilder, FunctionContext};
 use std::ops::Deref;
 use std::rc::Rc;
 
+use trans::basic_block::BasicBlock;
+
 use rustc_data_structures::bitvec::BitVector;
 
 use self::lvalue::{LvalueRef, get_dataptr, get_meta};
@@ -170,19 +172,20 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
         mircx.trans_block(bb);
     }
 
-    // Add unreachable instructions at the end of unreachable blocks
-    // so they're actually terminated.
-    // TODO: Remove the blocks from the function
+    // Remove blocks that haven't been visited, or have no
+    // predecessors.
     for &bb in &mir_blocks {
+        let block = mircx.blocks[bb.index()];
+        let block = BasicBlock(block.llbb);
+        // Unreachable block
         if !visited.contains(bb.index()) {
-            mircx.blocks[bb.index()].build().unreachable();
+            block.delete();
+        } else if block.pred_iter().count() == 0 {
+            block.delete();
         }
     }
 
-
     fcx.cleanup();
-
-    debug!("trans_mir: {:?}", ::trans::value::Value(fcx.llfn));
 }
 
 /// Produce, for each argument, a `ValueRef` pointing at the