mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
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:
parent
76a7f072ab
commit
525a9598d6
@ -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
|
||||
///
|
||||
|
@ -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*> {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user