diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 47833b02fdf..0c4a53f6150 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -99,19 +99,15 @@ public: bool isAllocatable() const { return Allocatable; } }; -/// MCRegisterDesc - This record contains all of the information known about -/// a particular register. The Overlaps field contains a pointer to a zero -/// terminated array of registers that this register aliases, starting with -/// itself. This is needed for architectures like X86 which have AL alias AX -/// alias EAX. The SubRegs field is a zero terminated array of registers that -/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of -/// AX. The SuperRegs field is a zero terminated array of registers that are -/// super-registers of the specific register, e.g. RAX, EAX, are super-registers -/// of AX. +/// MCRegisterDesc - This record contains information about a particular +/// register. The SubRegs field is a zero terminated array of registers that +/// are sub-registers of the specific register, e.g. AL, AH are sub-registers +/// of AX. The SuperRegs field is a zero terminated array of registers that are +/// super-registers of the specific register, e.g. RAX, EAX, are +/// super-registers of AX. /// struct MCRegisterDesc { uint32_t Name; // Printable name for the reg (for debugging) - uint32_t Overlaps; // Overlapping registers, described above uint32_t SubRegs; // Sub-register set, described above uint32_t SuperRegs; // Super-register set, described above @@ -226,7 +222,6 @@ public: // internal list pointers. friend class MCSubRegIterator; friend class MCSuperRegIterator; - friend class MCRegAliasIterator; friend class MCRegUnitIterator; friend class MCRegUnitRootIterator; @@ -437,6 +432,7 @@ public: /// If IncludeSelf is set, Reg itself is included in the list. class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator { public: + MCSuperRegIterator() {} MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI, bool IncludeSelf = false) { init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs); @@ -446,19 +442,6 @@ public: } }; -/// MCRegAliasIterator enumerates all registers aliasing Reg. -/// If IncludeSelf is set, Reg itself is included in the list. -class MCRegAliasIterator : public MCRegisterInfo::DiffListIterator { -public: - MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI, - bool IncludeSelf = false) { - init(Reg, MCRI->DiffLists + MCRI->get(Reg).Overlaps); - // Initially, the iterator points to Reg itself. - if (!IncludeSelf) - ++*this; - } -}; - // Definition for isSuperRegister. Put it down here since it needs the // iterator defined above in addition to the MCRegisterInfo class itself. inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{ @@ -486,6 +469,7 @@ class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator { public: /// MCRegUnitIterator - Create an iterator that traverses the register units /// in Reg. + MCRegUnitIterator() {} MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) { assert(Reg && "Null register has no regunits"); // Decode the RegUnits MCRegisterDesc field. @@ -519,6 +503,7 @@ class MCRegUnitRootIterator { uint16_t Reg0; uint16_t Reg1; public: + MCRegUnitRootIterator() : Reg0(0), Reg1(0) {} MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) { assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit"); Reg0 = MCRI->RegUnitRoots[RegUnit][0]; @@ -543,6 +528,68 @@ public: } }; +/// MCRegAliasIterator enumerates all registers aliasing Reg. If IncludeSelf is +/// set, Reg itself is included in the list. This iterator does not guarantee +/// any ordering or that entries are unique. +class MCRegAliasIterator { +private: + unsigned Reg; + const MCRegisterInfo *MCRI; + bool IncludeSelf; + + MCRegUnitIterator RI; + MCRegUnitRootIterator RRI; + MCSuperRegIterator SI; +public: + MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI, + bool IncludeSelf) + : Reg(Reg), MCRI(MCRI), IncludeSelf(IncludeSelf) { + + // Initialize the iterators. + for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) { + for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) { + for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) { + if (!(!IncludeSelf && Reg == *SI)) + return; + } + } + } + } + + bool isValid() const { + return RI.isValid(); + } + + unsigned operator*() const { + assert (SI.isValid() && "Cannot dereference an invalid iterator."); + return *SI; + } + + void advance() { + // Assuming SI is valid. + ++SI; + if (SI.isValid()) return; + + ++RRI; + if (RRI.isValid()) { + SI = MCSuperRegIterator(*RRI, MCRI, true); + return; + } + + ++RI; + if (RI.isValid()) { + RRI = MCRegUnitRootIterator(*RI, MCRI); + SI = MCSuperRegIterator(*RRI, MCRI, true); + } + } + + void operator++() { + assert(isValid() && "Cannot move off the end of the list."); + do advance(); + while (!IncludeSelf && isValid() && *SI == Reg); + } +}; + } // End llvm namespace #endif diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 1fe08b84b89..9d72d0d4bd6 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -526,55 +526,6 @@ CodeGenRegister::addSubRegsPreOrder(SetVector &OSet, OSet.insert(I->second); } -// Compute overlapping registers. -// -// The standard set is all super-registers and all sub-registers, but the -// target description can add arbitrary overlapping registers via the 'Aliases' -// field. This complicates things, but we can compute overlapping sets using -// the following rules: -// -// 1. The relation overlap(A, B) is reflexive and symmetric but not transitive. -// -// 2. overlap(A, B) implies overlap(A, S) for all S in supers(B). -// -// Alternatively: -// -// overlap(A, B) iff there exists: -// A' in { A, subregs(A) } and B' in { B, subregs(B) } such that: -// A' = B' or A' in aliases(B') or B' in aliases(A'). -// -// Here subregs(A) is the full flattened sub-register set returned by -// A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the -// description of register A. -// -// This also implies that registers with a common sub-register are considered -// overlapping. This can happen when forming register pairs: -// -// P0 = (R0, R1) -// P1 = (R1, R2) -// P2 = (R2, R3) -// -// In this case, we will infer an overlap between P0 and P1 because of the -// shared sub-register R1. There is no overlap between P0 and P2. -// -void CodeGenRegister::computeOverlaps(CodeGenRegister::Set &Overlaps, - const CodeGenRegBank &RegBank) const { - assert(!RegUnits.empty() && "Compute register units before overlaps."); - - // Register units are assigned such that the overlapping registers are the - // super-registers of the root registers of the register units. - for (unsigned rui = 0, rue = RegUnits.size(); rui != rue; ++rui) { - const RegUnit &RU = RegBank.getRegUnit(RegUnits[rui]); - ArrayRef Roots = RU.getRoots(); - for (unsigned ri = 0, re = Roots.size(); ri != re; ++ri) { - const CodeGenRegister *Root = Roots[ri]; - Overlaps.insert(Root); - ArrayRef Supers = Root->getSuperRegs(); - Overlaps.insert(Supers.begin(), Supers.end()); - } - } -} - // Get the sum of this register's unit weights. unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const { unsigned Weight = 0; diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index b56555dade6..ba62db48274 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -205,9 +205,6 @@ namespace llvm { // Canonically ordered set. typedef std::set Set; - // Compute the set of registers overlapping this. - void computeOverlaps(Set &Overlaps, const CodeGenRegBank&) const; - private: bool SubRegsComplete; bool SuperRegsComplete; diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index f519b21de06..2907c3332d5 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -703,15 +703,14 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, const std::vector &Regs = RegBank.getRegisters(); - // The lists of sub-registers, super-registers, and overlaps all go in the - // same array. That allows us to share suffixes. + // The lists of sub-registers and super-registers go in the same array. That + // allows us to share suffixes. typedef std::vector RegVec; // Differentially encoded lists. SequenceToOffsetTable DiffSeqs; SmallVector SubRegLists(Regs.size()); SmallVector SuperRegLists(Regs.size()); - SmallVector OverlapLists(Regs.size()); SmallVector RegUnitLists(Regs.size()); SmallVector RegUnitInitScale(Regs.size()); @@ -747,15 +746,6 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, SuperRegList.begin(), SuperRegList.end()); DiffSeqs.add(SuperRegLists[i]); - // The list of overlaps doesn't need to have any particular order, and Reg - // itself must be omitted. - DiffVec &OverlapList = OverlapLists[i]; - CodeGenRegister::Set OSet; - Reg->computeOverlaps(OSet, RegBank); - OSet.erase(Reg); - diffEncode(OverlapList, Reg->EnumValue, OSet.begin(), OSet.end()); - DiffSeqs.add(OverlapList); - // Differentially encode the register unit list, seeded by register number. // First compute a scale factor that allows more diff-lists to be reused: // @@ -808,13 +798,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[] = { // Descriptors\n"; - OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n"; + OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0 },\n"; // Emit the register descriptors now. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; OS << " { " << RegStrings.get(Reg->getName()) << ", " - << DiffSeqs.get(OverlapLists[i]) << ", " << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i]) << ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "