diff options
Diffstat (limited to 'llvm/include/llvm/IR/Instruction.h')
-rw-r--r-- | llvm/include/llvm/IR/Instruction.h | 87 |
1 files changed, 66 insertions, 21 deletions
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index 3bfa0e4afc398..a03eac0ad40d6 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -15,6 +15,7 @@ #define LLVM_IR_INSTRUCTION_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Bitfields.h" #include "llvm/ADT/None.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ilist_node.h" @@ -22,6 +23,7 @@ #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" +#include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Casting.h" #include <algorithm> #include <cassert> @@ -45,11 +47,37 @@ class Instruction : public User, BasicBlock *Parent; DebugLoc DbgLoc; // 'dbg' Metadata cache. - enum { - /// This is a bit stored in the SubClassData field which indicates whether - /// this instruction has metadata attached to it or not. - HasMetadataBit = 1 << 15 - }; + /// Relative order of this instruction in its parent basic block. Used for + /// O(1) local dominance checks between instructions. + mutable unsigned Order = 0; + +protected: + // The 15 first bits of `Value::SubclassData` are available for subclasses of + // `Instruction` to use. + using OpaqueField = Bitfield::Element<uint16_t, 0, 15>; + + // Template alias so that all Instruction storing alignment use the same + // definiton. + // Valid alignments are powers of two from 2^0 to 2^MaxAlignmentExponent = + // 2^29. We store them as Log2(Alignment), so we need 5 bits to encode the 30 + // possible values. + template <unsigned Offset> + using AlignmentBitfieldElementT = + typename Bitfield::Element<unsigned, Offset, 5, + Value::MaxAlignmentExponent>; + + template <unsigned Offset> + using BoolBitfieldElementT = typename Bitfield::Element<bool, Offset, 1>; + + template <unsigned Offset> + using AtomicOrderingBitfieldElementT = + typename Bitfield::Element<AtomicOrdering, Offset, 3, + AtomicOrdering::LAST>; + +private: + // The last bit is used to store whether the instruction has metadata attached + // or not. + using HasMetadataField = Bitfield::Element<bool, 15, 1>; protected: ~Instruction(); // Use deleteValue() to delete a generic Instruction. @@ -117,6 +145,13 @@ public: /// the basic block that MovePos lives in, right after MovePos. void moveAfter(Instruction *MovePos); + /// Given an instruction Other in the same basic block as this instruction, + /// return true if this instruction comes before Other. In this worst case, + /// this takes linear time in the number of instructions in the block. The + /// results are cached, so in common cases when the block remains unmodified, + /// it takes constant time. + bool comesBefore(const Instruction *Other) const; + //===--------------------------------------------------------------------===// // Subclass classification. //===--------------------------------------------------------------------===// @@ -321,9 +356,6 @@ public: /// Returns false if no metadata was found. bool extractProfTotalWeight(uint64_t &TotalVal) const; - /// Sets the branch_weights metadata to \p W for CallInst. - void setProfWeight(uint64_t W); - /// Set the debug location information for this instruction. void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } @@ -385,6 +417,11 @@ public: /// this flag. void setHasAllowReciprocal(bool B); + /// Set or clear the allow-contract flag on this instruction, which must be + /// an operator which supports this flag. See LangRef.html for the meaning of + /// this flag. + void setHasAllowContract(bool B); + /// Set or clear the approximate-math-functions flag on this instruction, /// which must be an operator which supports this flag. See LangRef.html for /// the meaning of this flag. @@ -458,7 +495,7 @@ public: private: /// Return true if we have an entry in the on-the-side metadata hash. bool hasMetadataHashEntry() const { - return (getSubclassDataFromValue() & HasMetadataBit) != 0; + return Bitfield::test<HasMetadataField>(getSubclassDataFromValue()); } // These are all implemented in Metadata.cpp. @@ -738,6 +775,7 @@ public: private: friend class SymbolTableListTraits<Instruction>; + friend class BasicBlock; // For renumbering. // Shadow Value::setValueSubclassData with a private forwarding method so that // subclasses cannot accidentally use it. @@ -749,10 +787,7 @@ private: return Value::getSubclassDataFromValue(); } - void setHasMetadataHashEntry(bool V) { - setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) | - (V ? HasMetadataBit : 0)); - } + void setHasMetadataHashEntry(bool V) { setSubclassData<HasMetadataField>(V); } void setParent(BasicBlock *P); @@ -760,14 +795,24 @@ protected: // Instruction subclasses can stick up to 15 bits of stuff into the // SubclassData field of instruction with these members. - // Verify that only the low 15 bits are used. - void setInstructionSubclassData(unsigned short D) { - assert((D & HasMetadataBit) == 0 && "Out of range value put into field"); - setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D); - } - - unsigned getSubclassDataFromInstruction() const { - return getSubclassDataFromValue() & ~HasMetadataBit; + template <typename BitfieldElement> + typename BitfieldElement::Type getSubclassData() const { + static_assert( + std::is_same<BitfieldElement, HasMetadataField>::value || + !Bitfield::isOverlapping<BitfieldElement, HasMetadataField>(), + "Must not overlap with the metadata bit"); + return Bitfield::get<BitfieldElement>(getSubclassDataFromValue()); + } + + template <typename BitfieldElement> + void setSubclassData(typename BitfieldElement::Type Value) { + static_assert( + std::is_same<BitfieldElement, HasMetadataField>::value || + !Bitfield::isOverlapping<BitfieldElement, HasMetadataField>(), + "Must not overlap with the metadata bit"); + auto Storage = getSubclassDataFromValue(); + Bitfield::set<BitfieldElement>(Storage, Value); + setValueSubclassData(Storage); } Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, |