[llvm-commits] [llvm] r133051 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/Target/TargetRegisterInfo.cpp utils/TableGen/RegisterInfoEmitter.cpp

Owen Anderson resistor at mac.com
Tue Jun 14 23:53:50 PDT 2011


Author: resistor
Date: Wed Jun 15 01:53:50 2011
New Revision: 133051

URL: http://llvm.org/viewvc/llvm-project?rev=133051&view=rev
Log:
Replace the statically generated hashtables for checking register relationships with just scanning the (typically tiny) static lists.

At the time I wrote this code (circa 2007), TargetRegisterInfo was using a std::set to perform these queries.  Switching to the static hashtables was an obvious improvement, but in reality there's no reason to do anything other than scan.
With this change, total LLC time on a whole-program 403.gcc is reduced by approximately 1.5%, almost all of which comes from a 15% reduction in LiveVariables time.  It also reduces the binary size of LLC by 86KB, thanks to eliminating a bunch of very large static tables.

Modified:
    llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
    llvm/trunk/lib/Target/TargetRegisterInfo.cpp
    llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp

Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=133051&r1=133050&r2=133051&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Wed Jun 15 01:53:50 2011
@@ -285,11 +285,6 @@
 /// descriptor.
 ///
 class TargetRegisterInfo {
-protected:
-  const unsigned* SubregHash;
-  const unsigned SubregHashSize;
-  const unsigned* AliasesHash;
-  const unsigned AliasesHashSize;
 public:
   typedef const TargetRegisterClass * const * regclass_iterator;
 private:
@@ -307,11 +302,7 @@
                      regclass_iterator RegClassEnd,
                      const char *const *subregindexnames,
                      int CallFrameSetupOpcode = -1,
-                     int CallFrameDestroyOpcode = -1,
-                     const unsigned* subregs = 0,
-                     const unsigned subregsize = 0,
-                     const unsigned* aliases = 0,
-                     const unsigned aliasessize = 0);
+                     int CallFrameDestroyOpcode = -1);
   virtual ~TargetRegisterInfo();
 public:
 
@@ -468,50 +459,28 @@
   /// regsOverlap - Returns true if the two registers are equal or alias each
   /// other. The registers may be virtual register.
   bool regsOverlap(unsigned regA, unsigned regB) const {
-    if (regA == regB)
-      return true;
-
-    if (regA > regB)
-      std::swap(regA, regB);
-
+    if (regA == regB) return true;
     if (isVirtualRegister(regA) || isVirtualRegister(regB))
       return false;
-
-    // regA and regB are distinct physical registers. Do they alias?
-    size_t index = (regA * 11 + regB * 97) & (AliasesHashSize-1);
-    unsigned ProbeAmt = 1;
-    while (AliasesHash[index*2] != 0 && AliasesHash[index*2+1] != 0) {
-      if (AliasesHash[index*2] == regA && AliasesHash[index*2+1] == regB)
-        return true;
-
-      index = (index + ProbeAmt) & (AliasesHashSize-1);
-      ProbeAmt += 1;
+    for (const unsigned *regList = getOverlaps(regA)+1; *regList; ++regList) {
+      if (*regList == regB) return true;
     }
-
     return false;
   }
 
   /// isSubRegister - Returns true if regB is a sub-register of regA.
   ///
   bool isSubRegister(unsigned regA, unsigned regB) const {
-    // SubregHash is a simple quadratically probed hash table.
-    size_t index = (regA * 11 + regB * 97) & (SubregHashSize-1);
-    unsigned ProbeAmt = 1;
-    while (SubregHash[index*2] != 0 && SubregHash[index*2+1] != 0) {
-      if (SubregHash[index*2] == regA && SubregHash[index*2+1] == regB)
-        return true;
-
-      index = (index + ProbeAmt) & (SubregHashSize-1);
-      ProbeAmt += 1;
-    }
-
-    return false;
+    return isSuperRegister(regB, regA);
   }
 
   /// isSuperRegister - Returns true if regB is a super-register of regA.
   ///
   bool isSuperRegister(unsigned regA, unsigned regB) const {
-    return isSubRegister(regB, regA);
+    for (const unsigned *regList = getSuperRegisters(regA); *regList;++regList){
+      if (*regList == regB) return true;
+    }
+    return false;
   }
 
   /// getCalleeSavedRegs - Return a null-terminated list of all of the

Modified: llvm/trunk/lib/Target/TargetRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetRegisterInfo.cpp?rev=133051&r1=133050&r2=133051&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/TargetRegisterInfo.cpp Wed Jun 15 01:53:50 2011
@@ -23,12 +23,8 @@
 TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR,
                              regclass_iterator RCB, regclass_iterator RCE,
                              const char *const *subregindexnames,
-                             int CFSO, int CFDO,
-                             const unsigned* subregs, const unsigned subregsize,
-                         const unsigned* aliases, const unsigned aliasessize)
-  : SubregHash(subregs), SubregHashSize(subregsize),
-    AliasesHash(aliases), AliasesHashSize(aliasessize),
-    Desc(D), SubRegIndexNames(subregindexnames), NumRegs(NR),
+                             int CFSO, int CFDO)
+  : Desc(D), SubRegIndexNames(subregindexnames), NumRegs(NR),
     RegClassBegin(RCB), RegClassEnd(RCE) {
   assert(isPhysicalRegister(NumRegs) &&
          "Target has too many physical registers!");

Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=133051&r1=133050&r2=133051&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Wed Jun 15 01:53:50 2011
@@ -129,64 +129,6 @@
 typedef std::pair<unsigned, unsigned> UUPair;
 typedef std::vector<UUPair> UUVector;
 
-// Generate and print a quadratically probed hash table of unsigned pairs.
-// The pair (0,0) is used as a sentinel, so it cannot be a data point.
-static void generateHashTable(raw_ostream &OS, const char *Name,
-                              const UUVector &Data) {
-  const UUPair Sentinel(0, 0);
-  unsigned HSize = Data.size();
-  UUVector HT;
-
-  // Grow the hash table until all entries can be found in less than 8 probes.
-  unsigned MaxProbes;
-  do {
-    // Hashtable size must be a power of two.
-    HSize = NextPowerOf2(HSize);
-    HT.assign(HSize, Sentinel);
-
-    // Insert all entries.
-    for (unsigned i = 0, e = Data.size(); i != e; ++i) {
-      UUPair D = Data[i];
-      unsigned Idx = (D.first * 11 + D.second * 97) & (HSize - 1);
-      unsigned ProbeAmt = 1;
-      while (HT[Idx] != Sentinel) {
-        Idx = (Idx + ProbeAmt) & (HSize - 1);
-        ProbeAmt += 1;
-      }
-      HT[Idx] = D;
-    }
-
-    // Now measure the max number of probes for any worst case miss.
-    MaxProbes = 0;
-    unsigned TotalProbes = 0;
-    for (unsigned i = 0, e = HSize; i != e; ++i) {
-      unsigned Idx = i;
-      unsigned ProbeAmt = 1;
-      while (HT[Idx] != Sentinel) {
-        Idx = (Idx + ProbeAmt) & (HSize - 1);
-        ProbeAmt += 1;
-      }
-      TotalProbes += ProbeAmt;
-      MaxProbes = std::max(MaxProbes, ProbeAmt);
-    }
-    OS << "\n  // Max number of probes: " << MaxProbes
-       << format(", avg %.1f", float(TotalProbes)/HSize);
-  } while (MaxProbes >= 6);
-
-  // Print the hash table.
-  OS << "\n  // Used entries: " << Data.size()
-     << "\n  const unsigned " << Name << "Size = " << HSize << ';'
-     << "\n  const unsigned " << Name << "[] = {\n";
-
-  for (unsigned i = 0, e = HSize; i != e; ++i) {
-    UUPair D = HT[i];
-    OS << format("    %3u,%3u,", D.first, D.second);
-    if (i % 8 == 7 && i + 1 != e)
-      OS << '\n';
-  }
-  OS << "\n  };\n";
-}
-
 //
 // RegisterInfoEmitter::run - Main register file description emitter.
 //
@@ -445,33 +387,6 @@
   DwarfRegNumsMapTy DwarfRegNums;
   const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
 
-  // Print the SubregHashTable, a simple quadratically probed
-  // hash table for determining if a register is a subregister
-  // of another register.
-  UUVector HTData;
-  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
-    unsigned RegNo = Regs[i].EnumValue;
-    const CodeGenRegister::SuperRegList &SR = Regs[i].getSuperRegs();
-    for (CodeGenRegister::SuperRegList::const_iterator I = SR.begin(),
-         E = SR.end(); I != E; ++I)
-      HTData.push_back(UUPair((*I)->EnumValue, RegNo));
-  }
-  generateHashTable(OS, "SubregHashTable", HTData);
-
-  // Print the AliasHashTable, a simple quadratically probed
-  // hash table for determining if a register aliases another register.
-  // Since the overlaps() relation is symmetric, only store a < b pairs.
-  HTData.clear();
-  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
-    unsigned RegNo = Regs[i].EnumValue;
-    const CodeGenRegister::Set &O = Overlaps[&Regs[i]];
-    for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end();
-         I != E; ++I)
-      if (RegNo < (*I)->EnumValue)
-        HTData.push_back(UUPair(RegNo, (*I)->EnumValue));
-  }
-  generateHashTable(OS, "AliasesHashTable", HTData);
-
   // Emit an overlap list for all registers.
   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
     const CodeGenRegister *Reg = &Regs[i];
@@ -640,9 +555,7 @@
      << "  : TargetRegisterInfo(RegisterDescriptors, " << Regs.size()+1
      << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
      << "                 SubRegIndexTable,\n"
-     << "                 CallFrameSetupOpcode, CallFrameDestroyOpcode,\n"
-     << "                 SubregHashTable, SubregHashTableSize,\n"
-     << "                 AliasesHashTable, AliasesHashTableSize) {\n"
+     << "                 CallFrameSetupOpcode, CallFrameDestroyOpcode) {\n"
      << "}\n\n";
 
   // Collect all information about dwarf register numbers





More information about the llvm-commits mailing list