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

Jakob Stoklund Olesen stoklund at 2pi.dk
Sun Jun 12 00:04:32 PDT 2011


Author: stoklund
Date: Sun Jun 12 02:04:32 2011
New Revision: 132888

URL: http://llvm.org/viewvc/llvm-project?rev=132888&view=rev
Log:
Tweak hash function and compress hash tables.

Make the hash tables as small as possible while ensuring that all
lookups can be done in less than 8 probes.

Cut the aliases hash table in half by only storing a < b pairs - it
is a symmetric relation.

Use larger multipliers on the initial hash function to ensure that it
properly covers the whole table, and to resolve some clustering in the
very regular ARM register bank.

This reduces the size of most of these tables by 4x - 8x. For instance,
the ARM tables shrink from 48 KB to 8 KB.

Modified:
    llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
    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=132888&r1=132887&r2=132888&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Sun Jun 12 02:04:32 2011
@@ -471,19 +471,21 @@
     if (regA == regB)
       return true;
 
+    if (regA > regB)
+      std::swap(regA, regB);
+
     if (isVirtualRegister(regA) || isVirtualRegister(regB))
       return false;
 
     // regA and regB are distinct physical registers. Do they alias?
-    size_t index = (regA + regB * 37) & (AliasesHashSize-1);
-    unsigned ProbeAmt = 0;
-    while (AliasesHash[index*2] != 0 &&
-           AliasesHash[index*2+1] != 0) {
+    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 += 2;
+      ProbeAmt += 1;
     }
 
     return false;
@@ -493,15 +495,14 @@
   ///
   bool isSubRegister(unsigned regA, unsigned regB) const {
     // SubregHash is a simple quadratically probed hash table.
-    size_t index = (regA + regB * 37) & (SubregHashSize-1);
-    unsigned ProbeAmt = 2;
-    while (SubregHash[index*2] != 0 &&
-           SubregHash[index*2+1] != 0) {
+    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 += 2;
+      ProbeAmt += 1;
     }
 
     return false;

Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=132888&r1=132887&r2=132888&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Sun Jun 12 02:04:32 2011
@@ -137,27 +137,31 @@
   unsigned HSize = Data.size();
   UUVector HT;
 
-  // Hashtable size must be a power of two.
-  HSize = 2 * NextPowerOf2(2 * HSize);
-  HT.assign(HSize, Sentinel);
-
-  // Insert all entries.
-  unsigned MaxProbes = 0;
-  for (unsigned i = 0, e = Data.size(); i != e; ++i) {
-    UUPair D = Data[i];
-    unsigned Idx = (D.first + D.second * 37) & (HSize - 1);
-    unsigned ProbeAmt = 2;
-    while (HT[Idx] != Sentinel) {
-      Idx = (Idx + ProbeAmt) & (HSize - 1);
-      ProbeAmt += 2;
+  // 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.
+    MaxProbes = 0;
+    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;
+      MaxProbes = std::max(MaxProbes, ProbeAmt);
     }
-    HT[Idx] = D;
-    MaxProbes = std::max(MaxProbes, ProbeAmt/2);
-  }
+    OS << "\n  // Max number of probes: " << MaxProbes;
+  } while (MaxProbes >= 8);
 
   // Print the hash table.
-  OS << "\n\n  // Max number of probes: " << MaxProbes
-     << "\n  // Used entries: " << Data.size()
+  OS << "\n  // Used entries: " << Data.size()
      << "\n  const unsigned " << Name << "Size = " << HSize << ';'
      << "\n  const unsigned " << Name << "[] = {\n";
 
@@ -441,13 +445,14 @@
 
   // 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 (*I != &Regs[i])
+      if (RegNo < (*I)->EnumValue)
         HTData.push_back(UUPair(RegNo, (*I)->EnumValue));
   }
   generateHashTable(OS, "AliasesHashTable", HTData);





More information about the llvm-commits mailing list