Precompute a bit vector of register sub-classes.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 30 Sep 2011 00:10:40 +0000 (00:10 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 30 Sep 2011 00:10:40 +0000 (00:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140827 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/CodeGenRegisters.cpp
utils/TableGen/CodeGenRegisters.h

index 9d0672d6fbb3ddb9094cf661d1aaa3a7e46aacfb..c7124950124fa69bc596eb37e5f8245e6b06463d 100644 (file)
@@ -388,6 +388,34 @@ const std::string &CodeGenRegisterClass::getName() const {
   return TheDef->getName();
 }
 
+// Compute sub-classes of all register classes.
+// Assume the classes are ordered topologically.
+void CodeGenRegisterClass::
+computeSubClasses(ArrayRef<CodeGenRegisterClass*> RegClasses) {
+  // Visit backwards so sub-classes are seen first.
+  for (unsigned rci = RegClasses.size(); rci; --rci) {
+    CodeGenRegisterClass &RC = *RegClasses[rci - 1];
+    RC.SubClasses.resize(RegClasses.size());
+    RC.SubClasses.set(RC.EnumValue);
+
+    // Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
+    for (unsigned s = rci; s != RegClasses.size(); ++s) {
+      if (RC.SubClasses.test(s))
+        continue;
+      CodeGenRegisterClass *SubRC = RegClasses[s];
+      if (!RC.hasSubClass(SubRC))
+        continue;
+      // SubRC is a sub-class. Grap all its sub-classes so we won't have to
+      // check them again.
+      RC.SubClasses |= SubRC->SubClasses;
+    }
+
+    // Sweep up missed clique members.  They will be immediately preceeding RC.
+    for (unsigned s = rci - 1; s && RC.hasSubClass(RegClasses[s - 1]); --s)
+      RC.SubClasses.set(s - 1);
+  }
+}
+
 //===----------------------------------------------------------------------===//
 //                               CodeGenRegBank
 //===----------------------------------------------------------------------===//
@@ -435,6 +463,7 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
   array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC);
   for (unsigned i = 0, e = RegClasses.size(); i != e; ++i)
     RegClasses[i]->EnumValue = i;
+  CodeGenRegisterClass::computeSubClasses(RegClasses);
 }
 
 CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
index 8edc541c4f27370adb9b856b003fafb471b98cb3..ae8f0d4abdf077d091f4e9188d73b9cb69ac7702 100644 (file)
@@ -19,6 +19,7 @@
 #include "SetTheory.h"
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
 #include <cstdlib>
@@ -87,6 +88,8 @@ namespace llvm {
     CodeGenRegister::Set Members;
     const std::vector<Record*> *Elements;
     std::vector<SmallVector<Record*, 16> > AltOrders;
+    // Bit mask of sub-classes including this, indexed by their EnumValue.
+    BitVector SubClasses;
   public:
     Record *TheDef;
     unsigned EnumValue;
@@ -139,6 +142,9 @@ namespace llvm {
     unsigned getNumOrders() const { return 1 + AltOrders.size(); }
 
     CodeGenRegisterClass(CodeGenRegBank&, Record *R);
+
+    // Called by CodeGenRegBank::CodeGenRegBank().
+    static void computeSubClasses(ArrayRef<CodeGenRegisterClass*>);
   };
 
   // CodeGenRegBank - Represent a target's registers and the relations between