diff options
Diffstat (limited to 'include/llvm/Target/TargetRegisterInfo.h')
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 153 |
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 { |