X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=include%2Fllvm%2FIR%2FInstruction.h;h=9dd16fd5a60918226c3433f128d5656a26adf137;hb=2c3e0051c31c3f5b2328b447eadf1cf9c4427442;hp=dc96b57674c6a5901a881f23b98d606e31808afb;hpb=e1bc145815f4334641be19f1c45ecf85d25b6e5a;p=android-x86%2Fexternal-llvm.git diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index dc96b57674c..9dd16fd5a60 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -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 - class SymbolTableListTraits; +template <> +struct ilist_traits + : public SymbolTableListTraits { + + /// \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 Sentinel; +}; class Instruction : public User, public ilist_node { void operator=(const Instruction &) = delete; @@ -44,7 +62,7 @@ class Instruction : public User, public ilist_node { }; public: // Out of line virtual method, so the vtable, etc has a home. - ~Instruction(); + ~Instruction() override; /// user_back - Specialize the methods defined in Value, as we know that an /// instruction can only be used by other instructions. @@ -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::iterator eraseFromParent(); /// insertBefore - Insert an unlinked instructions into a basic block /// immediately before the specified instruction. @@ -134,9 +153,7 @@ public: /// hasMetadata() - Return true if this instruction has any metadata attached /// to it. - bool hasMetadata() const { - return !DbgLoc.isUnknown() || hasMetadataHashEntry(); - } + bool hasMetadata() const { return DbgLoc || hasMetadataHashEntry(); } /// hasMetadataOtherThanDebugLoc - Return true if this instruction has /// metadata attached to it other than a debug location. @@ -495,6 +512,17 @@ protected: }; +inline Instruction *ilist_traits::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, + // 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), so no one will ever notice the superposition. + return static_cast(&Sentinel); +} + // Instruction* is only 4-byte aligned. template<> class PointerLikeTypeTraits {