]> granicus.if.org Git - llvm/commitdiff
Return iterator from Instruction::eraseFromParent.
authorDaniel Berlin <dberlin@dberlin.org>
Thu, 2 Apr 2015 00:03:07 +0000 (00:03 +0000)
committerDaniel Berlin <dberlin@dberlin.org>
Thu, 2 Apr 2015 00:03:07 +0000 (00:03 +0000)
Summary:
This is necessary in order to make removal while using reverse iterators work.

(See http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-March/084122.html)

Updates to other eraseFromParent's to come in later patches.

Reviewers: chandlerc

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D8783

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

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

index 8f5cdebcd10b2f4b1aad8fe2561de13051616d88..39ce37359bf7800159c44b778636afdbca44e3e1 100644 (file)
@@ -29,31 +29,6 @@ class TerminatorInst;
 class LLVMContext;
 class BlockAddress;
 
-template<> struct ilist_traits<Instruction>
-  : public SymbolTableListTraits<Instruction, BasicBlock> {
-
-  /// \brief Return a node that marks the end of a list.
-  ///
-  /// The sentinel is relative to this instance, so we use a non-static
-  /// method.
-  Instruction *createSentinel() const {
-    // Since i(p)lists always publicly derive from their corresponding traits,
-    // placing a data member in this class will augment the i(p)list.  But since
-    // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
-    // there is a legal viable downcast from it to NodeTy. We use this trick to
-    // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
-    // sentinel. Dereferencing the sentinel is forbidden (save the
-    // ilist_node<NodeTy>), so no one will ever notice the superposition.
-    return static_cast<Instruction*>(&Sentinel);
-  }
-  static void destroySentinel(Instruction*) {}
-
-  Instruction *provideInitialHead() const { return createSentinel(); }
-  Instruction *ensureHead(Instruction*) const { return createSentinel(); }
-  static void noteHead(Instruction*, Instruction*) {}
-private:
-  mutable ilist_half_node<Instruction> Sentinel;
-};
 
 /// \brief LLVM Basic Block Representation
 ///
index 9ada7059b6009307b76155826e1df64ffe012023..b4d72b5dd63abfde58457b8c1dc645d94bc9e2d4 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/SymbolTableListTraits.h"
 #include "llvm/IR/User.h"
 
 namespace llvm {
@@ -25,10 +26,27 @@ namespace llvm {
 class FastMathFlags;
 class LLVMContext;
 class MDNode;
+class BasicBlock;
 struct AAMDNodes;
 
-template<typename ValueSubClass, typename ItemParentClass>
-  class SymbolTableListTraits;
+template <>
+struct ilist_traits<Instruction>
+    : public SymbolTableListTraits<Instruction, BasicBlock> {
+
+  /// \brief Return a node that marks the end of a list.
+  ///
+  /// The sentinel is relative to this instance, so we use a non-static
+  /// method.
+  Instruction *createSentinel() const;
+  static void destroySentinel(Instruction *) {}
+
+  Instruction *provideInitialHead() const { return createSentinel(); }
+  Instruction *ensureHead(Instruction *) const { return createSentinel(); }
+  static void noteHead(Instruction *, Instruction *) {}
+
+private:
+  mutable ilist_half_node<Instruction> Sentinel;
+};
 
 class Instruction : public User, public ilist_node<Instruction> {
   void operator=(const Instruction &) = delete;
@@ -69,7 +87,8 @@ public:
   /// eraseFromParent - This method unlinks 'this' from the containing basic
   /// block and deletes it.
   ///
-  void eraseFromParent();
+  /// \returns an iterator pointing to the element after the erased one
+  iplist<Instruction>::iterator eraseFromParent();
 
   /// insertBefore - Insert an unlinked instructions into a basic block
   /// immediately before the specified instruction.
@@ -493,6 +512,17 @@ protected:
 
 };
 
+Instruction *ilist_traits<Instruction>::createSentinel() const {
+  // Since i(p)lists always publicly derive from their corresponding traits,
+  // placing a data member in this class will augment the i(p)list.  But since
+  // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
+  // there is a legal viable downcast from it to NodeTy. We use this trick to
+  // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
+  // sentinel. Dereferencing the sentinel is forbidden (save the
+  // ilist_node<NodeTy>), so no one will ever notice the superposition.
+  return static_cast<Instruction *>(&Sentinel);
+}
+
 // Instruction* is only 4-byte aligned.
 template<>
 class PointerLikeTypeTraits<Instruction*> {
index 7d9bd7ed5ffc6da90349ca3ea5aebfb481f9c0f8..57c143cca2c318863ec7cf23d858d0d6427436b5 100644 (file)
@@ -62,8 +62,8 @@ void Instruction::removeFromParent() {
   getParent()->getInstList().remove(this);
 }
 
-void Instruction::eraseFromParent() {
-  getParent()->getInstList().erase(this);
+iplist<Instruction>::iterator Instruction::eraseFromParent() {
+  return getParent()->getInstList().erase(this);
 }
 
 /// insertBefore - Insert an unlinked instructions into a basic block