Introduce TargetRegisterInfo::getOverlaps(Reg), returning a list of all
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 14 Dec 2010 23:03:42 +0000 (23:03 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 14 Dec 2010 23:03:42 +0000 (23:03 +0000)
registers that alias Reg, including itself. This is almost the same as the
existing getAliasSet() method, except for the inclusion of Reg.

The name matches the reflexive TRI::regsOverlap(x, y) relation.

It is very common to do stuff to a register and all its aliases:

  stuff(Reg)
  for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias)
    stuff(*Alias);

That can now be written as the simpler:

  for (const unsigned *Alias = TRI->getOverlaps(Reg); *Alias; ++Alias)
    stuff(*Alias);

This change requires a bit more constant space for the alias lists because Reg
is included and because the empty alias list cannot be shared any longer.

If the getAliasSet method is eventually removed, this space can be reclaimed by
sharing overlap lists. For instance, %rax and %eax have identical overlap sets.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121800 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetRegisterInfo.h
utils/TableGen/RegisterInfoEmitter.cpp

index 5af90fbf8cddbe990d905768456a43b0f4c726ad..ceb61300ae156e8b6b229db264f827a2a300132c 100644 (file)
@@ -32,19 +32,18 @@ template<class T> class SmallVectorImpl;
 class raw_ostream;
 
 /// TargetRegisterDesc - This record contains all of the information known about
-/// a particular register.  The AliasSet field (if not null) contains a pointer
-/// to a Zero terminated array of registers that this register aliases.  This is
-/// needed for architectures like X86 which have AL alias AX alias EAX.
-/// Registers that this does not apply to simply should set this to null.
-/// 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
+/// 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.
 ///
 struct TargetRegisterDesc {
   const char     *Name;         // Printable name for the reg (for debugging)
-  const unsigned *AliasSet;     // Register Alias Set, described above
+  const unsigned *Overlaps;     // Overlapping registers, described above
   const unsigned *SubRegs;      // Sub-register set, described above
   const unsigned *SuperRegs;    // Super-register set, described above
 };
@@ -355,7 +354,17 @@ public:
   /// terminated.
   ///
   const unsigned *getAliasSet(unsigned RegNo) const {
-    return get(RegNo).AliasSet;
+    // The Overlaps set always begins with Reg itself.
+    return get(RegNo).Overlaps + 1;
+  }
+
+  /// getOverlaps - Return a list of registers that overlap Reg, including
+  /// itself. This is the same as the alias set except Reg is included in the
+  /// list.
+  /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
+  ///
+  const unsigned *getOverlaps(unsigned RegNo) const {
+    return get(RegNo).Overlaps;
   }
 
   /// getSubRegisters - Return the list of registers that are sub-registers of
index ab5dd7e076b50e0e5c44febc96fde7c370f9eda4..96399a4d0525108053cd428bc1dc55b8f4d70e2f 100644 (file)
@@ -777,17 +777,13 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
   delete [] AliasesHashTable;
 
   if (!RegisterAliases.empty())
-    OS << "\n\n  // Register Alias Sets...\n";
+    OS << "\n\n  // Register Overlap Lists...\n";
 
-  // Emit the empty alias list
-  OS << "  const unsigned Empty_AliasSet[] = { 0 };\n";
-  // Loop over all of the registers which have aliases, emitting the alias list
-  // to memory.
+  // Emit an overlap list for all registers.
   for (std::map<Record*, std::set<Record*>, LessRecord >::iterator
          I = RegisterAliases.begin(), E = RegisterAliases.end(); I != E; ++I) {
-    if (I->second.empty())
-      continue;
-    OS << "  const unsigned " << I->first->getName() << "_AliasSet[] = { ";
+    OS << "  const unsigned " << I->first->getName() << "_Overlaps[] = { "
+       << getQualifiedName(I->first) << ", ";
     for (std::set<Record*>::iterator ASI = I->second.begin(),
            E = I->second.end(); ASI != E; ++ASI)
       OS << getQualifiedName(*ASI) << ", ";
@@ -849,11 +845,7 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
     const CodeGenRegister &Reg = Regs[i];
     OS << "    { \"";
-    OS << Reg.getName() << "\",\t";
-    if (!RegisterAliases[Reg.TheDef].empty())
-      OS << Reg.getName() << "_AliasSet,\t";
-    else
-      OS << "Empty_AliasSet,\t";
+    OS << Reg.getName() << "\",\t" << Reg.getName() << "_Overlaps,\t";
     if (!RegisterSubRegs[Reg.TheDef].empty())
       OS << Reg.getName() << "_SubRegsSet,\t";
     else