Return iterator from Instruction::eraseFromParent.

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
This commit is contained in:
Daniel Berlin 2015-04-02 00:03:07 +00:00
parent 76a7f072ab
commit 525a9598d6
3 changed files with 35 additions and 30 deletions

View 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
///

View 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*> {

View 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