aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Target/TargetRegisterInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target/TargetRegisterInfo.h')
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h153
1 files changed, 147 insertions, 6 deletions
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index fccaad4705d5..e5a6c8ed2f2d 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -21,7 +21,6 @@
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Printable.h"
#include <cassert>
#include <functional>
@@ -71,6 +70,9 @@ public:
const uint8_t AllocationPriority;
/// Whether the class supports two (or more) disjunct subregister indices.
const bool HasDisjunctSubRegs;
+ /// Whether a combination of subregisters can cover every register in the
+ /// class. See also the CoveredBySubRegs description in Target.td.
+ const bool CoveredBySubRegs;
const sc_iterator SuperClasses;
ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
@@ -161,8 +163,21 @@ public:
}
/// Returns a bit vector of subclasses, including this one.
- /// The vector is indexed by class IDs, see hasSubClassEq() above for how to
- /// use it.
+ /// The vector is indexed by class IDs.
+ ///
+ /// To use it, consider the returned array as a chunk of memory that
+ /// contains an array of bits of size NumRegClasses. Each 32-bit chunk
+ /// contains a bitset of the ID of the subclasses in big-endian style.
+
+ /// I.e., the representation of the memory from left to right at the
+ /// bit level looks like:
+ /// [31 30 ... 1 0] [ 63 62 ... 33 32] ...
+ /// [ XXX NumRegClasses NumRegClasses - 1 ... ]
+ /// Where the number represents the class ID and XXX bits that
+ /// should be ignored.
+ ///
+ /// See the implementation of hasSubClassEq for an example of how it
+ /// can be used.
const uint32_t *getSubClassMask() const {
return SubClassMask;
}
@@ -212,7 +227,7 @@ public:
/// Returns the combination of all lane masks of register in this class.
/// The lane masks of the registers are the combination of all lane masks
- /// of their subregisters.
+ /// of their subregisters. Returns 1 if there are no subregisters.
LaneBitmask getLaneMask() const {
return LaneMask;
}
@@ -457,9 +472,13 @@ public:
/// Return a register mask that clobbers everything.
virtual const uint32_t *getNoPreservedMask() const {
- llvm_unreachable("target does not provide no presered mask");
+ llvm_unreachable("target does not provide no preserved mask");
}
+ /// Return true if all bits that are set in mask \p mask0 are also set in
+ /// \p mask1.
+ bool regmaskSubsetEqual(const uint32_t *mask0, const uint32_t *mask1) const;
+
/// Return all the call-preserved register masks defined for this target.
virtual ArrayRef<const uint32_t *> getRegMasks() const = 0;
virtual ArrayRef<const char *> getRegMaskNames() const = 0;
@@ -548,6 +567,20 @@ public:
return composeSubRegIndexLaneMaskImpl(IdxA, Mask);
}
+ /// Transform a lanemask given for a virtual register to the corresponding
+ /// lanemask before using subregister with index \p IdxA.
+ /// This is the reverse of composeSubRegIndexLaneMask(), assuming Mask is a
+ /// valie lane mask (no invalid bits set) the following holds:
+ /// X0 = composeSubRegIndexLaneMask(Idx, Mask)
+ /// X1 = reverseComposeSubRegIndexLaneMask(Idx, X0)
+ /// => X1 == Mask
+ LaneBitmask reverseComposeSubRegIndexLaneMask(unsigned IdxA,
+ LaneBitmask LaneMask) const {
+ if (!IdxA)
+ return LaneMask;
+ return reverseComposeSubRegIndexLaneMaskImpl(IdxA, LaneMask);
+ }
+
/// Debugging helper: dump register in human readable form to dbgs() stream.
static void dumpReg(unsigned Reg, unsigned SubRegIndex = 0,
const TargetRegisterInfo* TRI = nullptr);
@@ -564,6 +597,11 @@ protected:
llvm_unreachable("Target has no sub-registers");
}
+ virtual LaneBitmask reverseComposeSubRegIndexLaneMaskImpl(unsigned,
+ LaneBitmask) const {
+ llvm_unreachable("Target has no sub-registers");
+ }
+
public:
/// Find a common super-register class if it exists.
///
@@ -863,6 +901,17 @@ public:
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = nullptr) const = 0;
+ /// Return the assembly name for \p Reg.
+ virtual StringRef getRegAsmName(unsigned Reg) const {
+ // FIXME: We are assuming that the assembly name is equal to the TableGen
+ // name converted to lower case
+ //
+ // The TableGen name is the name of the definition for this register in the
+ // target's tablegen files. For example, the TableGen name of
+ // def EAX : Register <...>; is "EAX"
+ return StringRef(getName(Reg));
+ }
+
//===--------------------------------------------------------------------===//
/// Subtarget Hooks
@@ -926,8 +975,9 @@ public:
/// Returns the current sub-register index.
unsigned getSubReg() const { return SubReg; }
- /// Returns the bit mask if register classes that getSubReg() projects into
+ /// Returns the bit mask of register classes that getSubReg() projects into
/// RC.
+ /// See TargetRegisterClass::getSubClassMask() for how to use it.
const uint32_t *getMask() const { return Mask; }
/// Advance iterator to the next entry.
@@ -940,6 +990,97 @@ public:
}
};
+//===----------------------------------------------------------------------===//
+// BitMaskClassIterator
+//===----------------------------------------------------------------------===//
+/// This class encapuslates the logic to iterate over bitmask returned by
+/// the various RegClass related APIs.
+/// E.g., this class can be used to iterate over the subclasses provided by
+/// TargetRegisterClass::getSubClassMask or SuperRegClassIterator::getMask.
+class BitMaskClassIterator {
+ /// Total number of register classes.
+ const unsigned NumRegClasses;
+ /// Base index of CurrentChunk.
+ /// In other words, the number of bit we read to get at the
+ /// beginning of that chunck.
+ unsigned Base;
+ /// Adjust base index of CurrentChunk.
+ /// Base index + how many bit we read within CurrentChunk.
+ unsigned Idx;
+ /// Current register class ID.
+ unsigned ID;
+ /// Mask we are iterating over.
+ const uint32_t *Mask;
+ /// Current chunk of the Mask we are traversing.
+ uint32_t CurrentChunk;
+
+ /// Move ID to the next set bit.
+ void moveToNextID() {
+ // If the current chunk of memory is empty, move to the next one,
+ // while making sure we do not go pass the number of register
+ // classes.
+ while (!CurrentChunk) {
+ // Move to the next chunk.
+ Base += 32;
+ if (Base >= NumRegClasses) {
+ ID = NumRegClasses;
+ return;
+ }
+ CurrentChunk = *++Mask;
+ Idx = Base;
+ }
+ // Otherwise look for the first bit set from the right
+ // (representation of the class ID is big endian).
+ // See getSubClassMask for more details on the representation.
+ unsigned Offset = countTrailingZeros(CurrentChunk);
+ // Add the Offset to the adjusted base number of this chunk: Idx.
+ // This is the ID of the register class.
+ ID = Idx + Offset;
+
+ // Consume the zeros, if any, and the bit we just read
+ // so that we are at the right spot for the next call.
+ // Do not do Offset + 1 because Offset may be 31 and 32
+ // will be UB for the shift, though in that case we could
+ // have make the chunk being equal to 0, but that would
+ // have introduced a if statement.
+ moveNBits(Offset);
+ moveNBits(1);
+ }
+
+ /// Move \p NumBits Bits forward in CurrentChunk.
+ void moveNBits(unsigned NumBits) {
+ assert(NumBits < 32 && "Undefined behavior spotted!");
+ // Consume the bit we read for the next call.
+ CurrentChunk >>= NumBits;
+ // Adjust the base for the chunk.
+ Idx += NumBits;
+ }
+
+public:
+ /// Create a BitMaskClassIterator that visits all the register classes
+ /// represented by \p Mask.
+ ///
+ /// \pre \p Mask != nullptr
+ BitMaskClassIterator(const uint32_t *Mask, const TargetRegisterInfo &TRI)
+ : NumRegClasses(TRI.getNumRegClasses()), Base(0), Idx(0), ID(0),
+ Mask(Mask), CurrentChunk(*Mask) {
+ // Move to the first ID.
+ moveToNextID();
+ }
+
+ /// Returns true if this iterator is still pointing at a valid entry.
+ bool isValid() const { return getID() != NumRegClasses; }
+
+ /// Returns the current register class ID.
+ unsigned getID() const { return ID; }
+
+ /// Advance iterator to the next entry.
+ void operator++() {
+ assert(isValid() && "Cannot move iterator past end.");
+ moveToNextID();
+ }
+};
+
// This is useful when building IndexedMaps keyed on virtual registers
struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
unsigned operator()(unsigned Reg) const {