Change a very hot piece of code in TableGen's register unit computations to use bit...
authorOwen Anderson <resistor@mac.com>
Fri, 30 Jan 2015 09:05:49 +0000 (09:05 +0000)
committerOwen Anderson <resistor@mac.com>
Fri, 30 Jan 2015 09:05:49 +0000 (09:05 +0000)
For target descriptions with very large and very dense register files, TableGen
can take an extremely long time to run.  This change makes a dent in that (~15%
in my measurements) by accelerating the single hottest operation with better data
structures.

I believe there's still a lot of room to make this even faster with more global
changes that require replacing some of the existing datastructures in this area
with bit vectors, but that's a more involved change and I wanted to get this
simpler improvement in first.

llvm-svn: 227562

llvm/utils/TableGen/CodeGenRegisters.cpp

index bef8a4b..1cf260d 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/ADT/IntEqClasses.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SparseBitVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Debug.h"
@@ -211,12 +212,24 @@ static bool hasRegUnit(CodeGenRegister::RegUnitList &RegUnits, unsigned Unit) {
 // Return true if the RegUnits changed.
 bool CodeGenRegister::inheritRegUnits(CodeGenRegBank &RegBank) {
   unsigned OldNumUnits = RegUnits.size();
+
+  SparseBitVector<> NewUnits;
+  for (unsigned RU : RegUnits)
+    NewUnits.set(RU);
+
   for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
        I != E; ++I) {
     CodeGenRegister *SR = I->second;
     // Merge the subregister's units into this register's RegUnits.
-    mergeRegUnits(RegUnits, SR->RegUnits);
+    for (unsigned RU : SR->RegUnits)
+      NewUnits.set(RU);
   }
+
+  RegUnits.clear();
+  RegUnits.reserve(NewUnits.count());
+  for (unsigned RU : NewUnits)
+    RegUnits.push_back(RU);
+
   return OldNumUnits != RegUnits.size();
 }