IR: Add BasicBlock::insertInto()
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 1 Aug 2014 21:22:04 +0000 (21:22 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 1 Aug 2014 21:22:04 +0000 (21:22 +0000)
Although unlinked `BasicBlock`s can be created, there's currently no way
to insert them into `Function`s after the fact.  In particular,
`moveAfter()` and `moveBefore()` require that the basic block is already
linked.

Extract the logic for initially linking a `BasicBlock` out of the
constructor and into a member function that can be used for lazy
insertion.

  - Asserts that the basic block is currently unlinked.
  - Matches the logic of the constructor.
  - Changed the constructor to use it since the logic matches.

This is needed in a follow-up commit for PR5680.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214563 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/BasicBlock.h
lib/IR/BasicBlock.cpp

index a19489aa49b1df410570af8511dc1988ad48d47e..026c39f0551f0880390d1fefdd127a6fc3670325 100644 (file)
@@ -173,6 +173,13 @@ public:
   /// right after \p MovePos in the function \p MovePos lives in.
   void moveAfter(BasicBlock *MovePos);
 
+  /// \brief Insert unlinked basic block into a function.
+  ///
+  /// Inserts an unlinked basic block into \c Parent.  If \c InsertBefore is
+  /// provided, inserts before that basic block, otherwise inserts at the end.
+  ///
+  /// \pre \a getParent() is \c nullptr.
+  void insertInto(Function *Parent, BasicBlock *InsertBefore = nullptr);
 
   /// \brief Return the predecessor of this block if it has a single predecessor
   /// block. Otherwise return a null pointer.
index ba07433103b6e16496213bbf8b1d0e7d0b339fed..1ec977811ce6a378b5bf2f86054423f7980337dc 100644 (file)
@@ -50,17 +50,24 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
   // Make sure that we get added to a function
   LeakDetector::addGarbageObject(this);
 
-  if (InsertBefore) {
-    assert(NewParent &&
+  if (NewParent)
+    insertInto(NewParent, InsertBefore);
+  else
+    assert(!InsertBefore &&
            "Cannot insert block before another block with no function!");
-    NewParent->getBasicBlockList().insert(InsertBefore, this);
-  } else if (NewParent) {
-    NewParent->getBasicBlockList().push_back(this);
-  }
 
   setName(Name);
 }
 
+void BasicBlock::insertInto(Function *NewParent, BasicBlock *InsertBefore) {
+  assert(NewParent && "Expected a parent");
+  assert(!Parent && "Already has a parent");
+
+  if (InsertBefore)
+    NewParent->getBasicBlockList().insert(InsertBefore, this);
+  else
+    NewParent->getBasicBlockList().push_back(this);
+}
 
 BasicBlock::~BasicBlock() {
   // If the address of the block is taken and it is being deleted (e.g. because