+
+ /// MachineInstrIndex - An opaque wrapper around machine indexes.
+ class MachineInstrIndex {
+ friend class VNInfo;
+ friend class LiveInterval;
+ friend class LiveIntervals;
+ friend struct DenseMapInfo<MachineInstrIndex>;
+
+ public:
+
+ enum Slot { LOAD, USE, DEF, STORE, NUM };
+
+ private:
+
+ unsigned index;
+
+ static const unsigned PHI_BIT = 1 << 31;
+
+ public:
+
+ /// Construct a default MachineInstrIndex pointing to a reserved index.
+ MachineInstrIndex() : index(0) {}
+
+ /// Construct an index from the given index, pointing to the given slot.
+ MachineInstrIndex(MachineInstrIndex m, Slot s)
+ : index((m.index / NUM) * NUM + s) {}
+
+ /// Print this index to the given raw_ostream.
+ void print(raw_ostream &os) const;
+
+ /// Print this index to the given std::ostream.
+ void print(std::ostream &os) const;
+
+ /// Compare two MachineInstrIndex objects for equality.
+ bool operator==(MachineInstrIndex other) const {
+ return ((index & ~PHI_BIT) == (other.index & ~PHI_BIT));
+ }
+ /// Compare two MachineInstrIndex objects for inequality.
+ bool operator!=(MachineInstrIndex other) const {
+ return ((index & ~PHI_BIT) != (other.index & ~PHI_BIT));
+ }
+
+ /// Compare two MachineInstrIndex objects. Return true if the first index
+ /// is strictly lower than the second.
+ bool operator<(MachineInstrIndex other) const {
+ return ((index & ~PHI_BIT) < (other.index & ~PHI_BIT));
+ }
+ /// Compare two MachineInstrIndex objects. Return true if the first index
+ /// is lower than, or equal to, the second.
+ bool operator<=(MachineInstrIndex other) const {
+ return ((index & ~PHI_BIT) <= (other.index & ~PHI_BIT));
+ }
+
+ /// Compare two MachineInstrIndex objects. Return true if the first index
+ /// is greater than the second.
+ bool operator>(MachineInstrIndex other) const {
+ return ((index & ~PHI_BIT) > (other.index & ~PHI_BIT));
+ }
+
+ /// Compare two MachineInstrIndex objects. Return true if the first index
+ /// is greater than, or equal to, the second.
+ bool operator>=(MachineInstrIndex other) const {
+ return ((index & ~PHI_BIT) >= (other.index & ~PHI_BIT));
+ }
+
+ /// Returns true if this index represents a load.
+ bool isLoad() const {
+ return ((index % NUM) == LOAD);
+ }
+
+ /// Returns true if this index represents a use.
+ bool isUse() const {
+ return ((index % NUM) == USE);
+ }
+
+ /// Returns true if this index represents a def.
+ bool isDef() const {
+ return ((index % NUM) == DEF);
+ }
+
+ /// Returns true if this index represents a store.
+ bool isStore() const {
+ return ((index % NUM) == STORE);
+ }
+
+ /// Returns the slot for this MachineInstrIndex.
+ Slot getSlot() const {
+ return static_cast<Slot>(index % NUM);
+ }
+
+ /// Returns true if this index represents a non-PHI use/def.
+ bool isNonPHIIndex() const {
+ return ((index & PHI_BIT) == 0);
+ }
+
+ /// Returns true if this index represents a PHI use/def.
+ bool isPHIIndex() const {
+ return ((index & PHI_BIT) == PHI_BIT);
+ }
+
+ private:
+
+ /// Construct an index from the given index, with its PHI kill marker set.
+ MachineInstrIndex(bool phi, MachineInstrIndex o) : index(o.index) {
+ if (phi)
+ index |= PHI_BIT;
+ else
+ index &= ~PHI_BIT;
+ }
+
+ explicit MachineInstrIndex(unsigned idx)
+ : index(idx & ~PHI_BIT) {}
+
+ MachineInstrIndex(bool phi, unsigned idx)
+ : index(idx & ~PHI_BIT) {
+ if (phi)
+ index |= PHI_BIT;
+ }
+
+ MachineInstrIndex(bool phi, unsigned idx, Slot slot)
+ : index(((idx / NUM) * NUM + slot) & ~PHI_BIT) {
+ if (phi)
+ index |= PHI_BIT;
+ }
+
+ MachineInstrIndex nextSlot() const {
+ assert((index & PHI_BIT) == ((index + 1) & PHI_BIT) &&
+ "Index out of bounds.");
+ return MachineInstrIndex(index + 1);
+ }
+
+ MachineInstrIndex nextIndex() const {
+ assert((index & PHI_BIT) == ((index + NUM) & PHI_BIT) &&
+ "Index out of bounds.");
+ return MachineInstrIndex(index + NUM);
+ }
+
+ MachineInstrIndex prevSlot() const {
+ assert((index & PHI_BIT) == ((index - 1) & PHI_BIT) &&
+ "Index out of bounds.");
+ return MachineInstrIndex(index - 1);
+ }
+
+ MachineInstrIndex prevIndex() const {
+ assert((index & PHI_BIT) == ((index - NUM) & PHI_BIT) &&
+ "Index out of bounds.");
+ return MachineInstrIndex(index - NUM);
+ }
+
+ int distance(MachineInstrIndex other) const {
+ return (other.index & ~PHI_BIT) - (index & ~PHI_BIT);
+ }
+
+ /// Returns an unsigned number suitable as an index into a
+ /// vector over all instructions.
+ unsigned getVecIndex() const {
+ return (index & ~PHI_BIT) / NUM;
+ }
+
+ /// Scale this index by the given factor.
+ MachineInstrIndex scale(unsigned factor) const {
+ unsigned i = (index & ~PHI_BIT) / NUM,
+ o = (index % ~PHI_BIT) % NUM;
+ assert(index <= (~0U & ~PHI_BIT) / (factor * NUM) &&
+ "Rescaled interval would overflow");
+ return MachineInstrIndex(i * NUM * factor, o);
+ }
+
+ static MachineInstrIndex emptyKey() {
+ return MachineInstrIndex(true, 0x7fffffff);
+ }
+
+ static MachineInstrIndex tombstoneKey() {
+ return MachineInstrIndex(true, 0x7ffffffe);
+ }
+
+ static unsigned getHashValue(const MachineInstrIndex &v) {
+ return v.index * 37;
+ }
+
+ };
+
+ inline raw_ostream& operator<<(raw_ostream &os, MachineInstrIndex mi) {
+ mi.print(os);
+ return os;
+ }
+
+ inline std::ostream& operator<<(std::ostream &os, MachineInstrIndex mi) {
+ mi.print(os);
+ return os;
+ }
+
+ /// Densemap specialization for MachineInstrIndex.
+ template <>
+ struct DenseMapInfo<MachineInstrIndex> {
+ static inline MachineInstrIndex getEmptyKey() {
+ return MachineInstrIndex::emptyKey();
+ }
+ static inline MachineInstrIndex getTombstoneKey() {
+ return MachineInstrIndex::tombstoneKey();
+ }
+ static inline unsigned getHashValue(const MachineInstrIndex &v) {
+ return MachineInstrIndex::getHashValue(v);
+ }
+ static inline bool isEqual(const MachineInstrIndex &LHS,
+ const MachineInstrIndex &RHS) {
+ return (LHS == RHS);
+ }
+ static inline bool isPod() { return true; }
+ };
+