summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCRegisterInfo.h95
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp49
-rw-r--r--utils/TableGen/CodeGenRegisters.h3
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp17
4 files changed, 74 insertions, 90 deletions
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index 47833b02fd..0c4a53f615 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 1fe08b84b8..9d72d0d4bd 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -526,55 +526,6 @@ CodeGenRegister::addSubRegsPreOrder(SetVector<const CodeGenRegister*> &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<const CodeGenRegister*> Roots = RU.getRoots();
- for (unsigned ri = 0, re = Roots.size(); ri != re; ++ri) {
- const CodeGenRegister *Root = Roots[ri];
- Overlaps.insert(Root);
- ArrayRef<const CodeGenRegister*> 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 b56555dade..ba62db4827 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -205,9 +205,6 @@ namespace llvm {
// Canonically ordered set.
typedef std::set<const CodeGenRegister*, Less> 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 f519b21de0..2907c3332d 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<CodeGenRegister*> &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<const CodeGenRegister*> RegVec;
// Differentially encoded lists.
SequenceToOffsetTable<DiffVec> DiffSeqs;
SmallVector<DiffVec, 4> SubRegLists(Regs.size());
SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
- SmallVector<DiffVec, 4> OverlapLists(Regs.size());
SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
SmallVector<unsigned, 4> 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]) << ", "