Add a missing break, which caused a crash in an obscure situation
[oota-llvm.git] / lib / VMCore / BasicBlock.cpp
index 63a722b33e40389c0cf082e2ea7e9d98eb0ff5dd..c24a61e46652a6c6f5a35d14ee475098b5d4ecd5 100644 (file)
 #include "Support/LeakDetector.h"
 #include "SymbolTableListTraitsImpl.h"
 #include <algorithm>
+using namespace llvm;
+
+namespace {
+  /// DummyInst - An instance of this class is used to mark the end of the
+  /// instruction list.  This is not a real instruction.
+  struct DummyInst : public Instruction {
+    DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd) {
+      // This should not be garbage monitored.
+      LeakDetector::removeGarbageObject(this);
+    }
 
-namespace llvm {
-
-// DummyInst - An instance of this class is used to mark the end of the
-// instruction list.  This is not a real instruction.
-//
-struct DummyInst : public Instruction {
-  DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd) {
-    // This should not be garbage monitored.
-    LeakDetector::removeGarbageObject(this);
-  }
-
-  virtual Instruction *clone() const {
-    assert(0 && "Cannot clone EOL");abort();
-    return 0;
-  }
-  virtual const char *getOpcodeName() const { return "*end-of-list-inst*"; }
+    virtual Instruction *clone() const {
+      assert(0 && "Cannot clone EOL");abort();
+      return 0;
+    }
+    virtual const char *getOpcodeName() const { return "*end-of-list-inst*"; }
 
-  // Methods for support type inquiry through isa, cast, and dyn_cast...
-  static inline bool classof(const DummyInst *) { return true; }
-  static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == OtherOpsEnd;
-  }
-  static inline bool classof(const Value *V) {
-    return isa<Instruction>(V) && classof(cast<Instruction>(V));
-  }
-};
+    // Methods for support type inquiry through isa, cast, and dyn_cast...
+    static inline bool classof(const DummyInst *) { return true; }
+    static inline bool classof(const Instruction *I) {
+      return I->getOpcode() == OtherOpsEnd;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<Instruction>(V) && classof(cast<Instruction>(V));
+    }
+  };
+}
 
 Instruction *ilist_traits<Instruction>::createNode() {
   return new DummyInst();
@@ -61,25 +61,8 @@ iplist<Instruction> &ilist_traits<Instruction>::getList(BasicBlock *BB) {
 template class SymbolTableListTraits<Instruction, BasicBlock, Function>;
 
 
-// BasicBlock ctor - If the function parameter is specified, the basic block is
-// automatically inserted at the end of the function.
-//
-BasicBlock::BasicBlock(const std::string &name, Function *Parent)
-  : Value(Type::LabelTy, Value::BasicBlockVal, name) {
-  // Initialize the instlist...
-  InstList.setItemParent(this);
-
-  // Make sure that we get added to a function
-  LeakDetector::addGarbageObject(this);
-
-  if (Parent)
-    Parent->getBasicBlockList().push_back(this);
-}
-
-/// BasicBlock ctor - If the InsertBefore parameter is specified, the basic
-/// block is automatically inserted right before the specified block.
-///
-BasicBlock::BasicBlock(const std::string &Name, BasicBlock *InsertBefore)
+BasicBlock::BasicBlock(const std::string &Name, Function *Parent,
+                       BasicBlock *InsertBefore)
   : Value(Type::LabelTy, Value::BasicBlockVal, Name) {
   // Initialize the instlist...
   InstList.setItemParent(this);
@@ -88,10 +71,11 @@ BasicBlock::BasicBlock(const std::string &Name, BasicBlock *InsertBefore)
   LeakDetector::addGarbageObject(this);
 
   if (InsertBefore) {
-    assert(InsertBefore->getParent() &&
-           "Cannot insert block before another block that is not embedded into"
-           " a function yet!");
-    InsertBefore->getParent()->getBasicBlockList().insert(InsertBefore, this);
+    assert(Parent &&
+           "Cannot insert block before another block with no function!");
+    Parent->getBasicBlockList().insert(InsertBefore, this);
+  } else if (Parent) {
+    Parent->getBasicBlockList().push_back(this);
   }
 }
 
@@ -136,19 +120,6 @@ void BasicBlock::dropAllReferences() {
     I->dropAllReferences();
 }
 
-// hasConstantReferences() - This predicate is true if there is a 
-// reference to this basic block in the constant pool for this method.  For
-// example, if a block is reached through a switch table, that table resides
-// in the constant pool, and the basic block is reference from it.
-//
-bool BasicBlock::hasConstantReferences() const {
-  for (use_const_iterator I = use_begin(), E = use_end(); I != E; ++I)
-    if (isa<Constant>((Value*)*I))
-      return true;
-
-  return false;
-}
-
 // removePredecessor - This method is used to notify a BasicBlock that the
 // specified Predecessor of the block is no longer able to reach it.  This is
 // actually not used to update the Predecessor list, but is actually used to 
@@ -231,19 +202,14 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const std::string &BBName) {
   assert(I != InstList.end() && 
         "Trying to get me to create degenerate basic block!");
 
-  BasicBlock *New = new BasicBlock(BBName, getParent());
+  BasicBlock *New = new BasicBlock(BBName, getParent(), getNext());
 
-  // Go from the end of the basic block through to the iterator pointer, moving
-  // to the new basic block...
-  Instruction *Inst = 0;
-  do {
-    iterator EndIt = end();
-    Inst = InstList.remove(--EndIt);                  // Remove from end
-    New->InstList.push_front(Inst);                   // Add to front
-  } while (Inst != &*I);   // Loop until we move the specified instruction.
+  // Move all of the specified instructions from the original basic block into
+  // the new basic block.
+  New->getInstList().splice(New->end(), this->getInstList(), I, end());
 
   // Add a branch instruction to the newly formed basic block.
-  InstList.push_back(new BranchInst(New));
+  new BranchInst(New, this);
 
   // Now we must loop through all of the successors of the New block (which
   // _were_ the successors of the 'this' block), and update any PHI nodes in
@@ -265,5 +231,3 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const std::string &BBName) {
   }
   return New;
 }
-
-} // End llvm namespace