X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FIR%2FInstruction.h;h=31f363f70a5b13100b899f536d9bfa393bd781fe;hb=04180d08dbf827905a44c866aab1dad5ca233bba;hp=0a245483ff762e3458acfaf14c8a49e88c6be17f;hpb=f611ae40fdd3815367dd8244fff037f68110fae0;p=oota-llvm.git diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 0a245483ff7..31f363f70a5 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -17,21 +17,40 @@ #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" -#include "llvm/Support/DebugLoc.h" 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 &) LLVM_DELETED_FUNCTION; - Instruction(const Instruction &) LLVM_DELETED_FUNCTION; + void operator=(const Instruction &) = delete; + Instruction(const Instruction &) = delete; BasicBlock *Parent; DebugLoc DbgLoc; // 'dbg' Metadata cache. @@ -43,16 +62,24 @@ class Instruction : public User, public ilist_node { }; public: // Out of line virtual method, so the vtable, etc has a home. - ~Instruction(); + ~Instruction() override; - /// use_back - Specialize the methods defined in Value, as we know that an + /// user_back - Specialize the methods defined in Value, as we know that an /// instruction can only be used by other instructions. - Instruction *use_back() { return cast(*use_begin());} - const Instruction *use_back() const { return cast(*use_begin());} + Instruction *user_back() { return cast(*user_begin());} + const Instruction *user_back() const { return cast(*user_begin());} inline const BasicBlock *getParent() const { return Parent; } inline BasicBlock *getParent() { return Parent; } + /// \brief Return the module owning the function this instruction belongs to + /// or nullptr it the function does not have a module. + /// + /// Note: this is undefined behavior if the instruction does not have a + /// parent, or the parent basic block does not have a parent function. + const Module *getModule() const; + Module *getModule(); + /// removeFromParent - This method unlinks 'this' from the containing basic /// block, but does not delete it. /// @@ -61,14 +88,15 @@ 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. + /// Insert an unlinked instruction into a basic block immediately before + /// the specified instruction. void insertBefore(Instruction *InsertPos); - /// insertAfter - Insert an unlinked instructions into a basic block - /// immediately after the specified instruction. + /// Insert an unlinked instruction into a basic block immediately after the + /// specified instruction. void insertAfter(Instruction *InsertPos); /// moveBefore - Unlink this instruction from its current basic block and @@ -126,9 +154,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. @@ -139,33 +165,39 @@ public: /// getMetadata - Get the metadata of given kind attached to this Instruction. /// If the metadata is not found then return null. MDNode *getMetadata(unsigned KindID) const { - if (!hasMetadata()) return 0; + if (!hasMetadata()) return nullptr; return getMetadataImpl(KindID); } /// getMetadata - Get the metadata of given kind attached to this Instruction. /// If the metadata is not found then return null. MDNode *getMetadata(StringRef Kind) const { - if (!hasMetadata()) return 0; + if (!hasMetadata()) return nullptr; return getMetadataImpl(Kind); } /// getAllMetadata - Get all metadata attached to this Instruction. The first /// element of each pair returned is the KindID, the second element is the /// metadata value. This list is returned sorted by the KindID. - void getAllMetadata(SmallVectorImpl > &MDs)const{ + void + getAllMetadata(SmallVectorImpl> &MDs) const { if (hasMetadata()) getAllMetadataImpl(MDs); } /// getAllMetadataOtherThanDebugLoc - This does the same thing as /// getAllMetadata, except that it filters out the debug location. - void getAllMetadataOtherThanDebugLoc(SmallVectorImpl > &MDs) const { + void getAllMetadataOtherThanDebugLoc( + SmallVectorImpl> &MDs) const { if (hasMetadataOtherThanDebugLoc()) getAllMetadataOtherThanDebugLocImpl(MDs); } + /// getAAMetadata - Fills the AAMDNodes structure with AA metadata from + /// this instruction. When Merge is true, the existing AA metadata is + /// merged with that from this instruction providing the most-general result. + void getAAMetadata(AAMDNodes &N, bool Merge = false) const; + /// setMetadata - Set the metadata of the specified kind to the specified /// node. This updates/replaces metadata if already present, or removes it if /// Node is null. @@ -177,7 +209,7 @@ public: /// convenience method for passes to do so. void dropUnknownMetadata(ArrayRef KnownIDs); void dropUnknownMetadata() { - return dropUnknownMetadata(ArrayRef()); + return dropUnknownMetadata(None); } void dropUnknownMetadata(unsigned ID1) { return dropUnknownMetadata(makeArrayRef(ID1)); @@ -187,8 +219,12 @@ public: return dropUnknownMetadata(IDs); } + /// setAAMetadata - Sets the metadata on this instruction from the + /// AAMDNodes structure. + void setAAMetadata(const AAMDNodes &N); + /// setDebugLoc - Set the debug location information for this instruction. - void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; } + void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } /// getDebugLoc - Return the debug location for this node as a DebugLoc. const DebugLoc &getDebugLoc() const { return DbgLoc; } @@ -218,11 +254,16 @@ public: /// this flag. void setHasAllowReciprocal(bool B); - /// Convenience function for setting all the fast-math flags on this + /// Convenience function for setting multiple fast-math flags on this /// instruction, which must be an operator which supports these flags. See - /// LangRef.html for the meaning of these flats. + /// LangRef.html for the meaning of these flags. void setFastMathFlags(FastMathFlags FMF); + /// Convenience function for transferring all fast-math flag values to this + /// instruction, which must be an operator which supports these flags. See + /// LangRef.html for the meaning of these flags. + void copyFastMathFlags(FastMathFlags FMF); + /// Determine whether the unsafe-algebra flag is set. bool hasUnsafeAlgebra() const; @@ -240,7 +281,7 @@ public: /// Convenience function for getting all the fast-math flags, which must be an /// operator which supports these flags. See LangRef.html for the meaning of - /// these flats. + /// these flags. FastMathFlags getFastMathFlags() const; /// Copy I's fast-math flags @@ -256,9 +297,10 @@ private: // These are all implemented in Metadata.cpp. MDNode *getMetadataImpl(unsigned KindID) const; MDNode *getMetadataImpl(StringRef Kind) const; - void getAllMetadataImpl(SmallVectorImpl > &)const; - void getAllMetadataOtherThanDebugLocImpl(SmallVectorImpl > &) const; + void + getAllMetadataImpl(SmallVectorImpl> &) const; + void getAllMetadataOtherThanDebugLocImpl( + SmallVectorImpl> &) const; void clearMetadataHashEntries(); public: //===--------------------------------------------------------------------===// @@ -321,6 +363,11 @@ public: return mayReadFromMemory() || mayWriteToMemory(); } + /// isAtomic - Return true if this instruction has an + /// AtomicOrdering of unordered or higher. + /// + bool isAtomic() const; + /// mayThrow - Return true if this instruction may throw an exception. /// bool mayThrow() const; @@ -335,7 +382,7 @@ public: /// /// Note that this does not consider malloc and alloca to have side /// effects because the newly allocated memory is completely invisible to - /// instructions which don't used the returned value. For cases where this + /// instructions which don't use the returned value. For cases where this /// matters, isSafeToSpeculativelyExecute may be more appropriate. bool mayHaveSideEffects() const { return mayWriteToMemory() || mayThrow() || !mayReturn(); @@ -459,13 +506,26 @@ protected: } Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, - Instruction *InsertBefore = 0); + Instruction *InsertBefore = nullptr); Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); - virtual Instruction *clone_impl() const = 0; +private: + /// Create a copy of this instruction. + Instruction *cloneImpl() const; }; +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 {