summaryrefslogtreecommitdiff
path: root/llvm/include/llvm/IR/Instruction.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/IR/Instruction.h')
-rw-r--r--llvm/include/llvm/IR/Instruction.h87
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,