Teach TableGen to evaluate DAG expressions as set operations.

A TableGen backend can define how certain classes can be expanded into
ordered sets of defs, typically by evaluating a specific field in the
record. The SetTheory class can then evaluate DAG expressions that refer
to these named sets.

A number of standard set and list operations are predefined, and the
backend can add more specialized operators if needed. The -print-sets
backend is used by SetTheory.td to provide examples.

This is intended to simplify how register classes are defined:

  def GR32_NOSP : RegisterClass<"X86", [i32], 32, (sub GR32, ESP)>;

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132621 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index fb941c4..925b134 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -37,6 +37,7 @@
 #include "RegisterInfoEmitter.h"
 #include "ARMDecoderEmitter.h"
 #include "SubtargetEmitter.h"
+#include "SetTheory.h"
 #include "TGParser.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/Support/CommandLine.h"
@@ -80,7 +81,8 @@
   GenArmNeon,
   GenArmNeonSema,
   GenArmNeonTest,
-  PrintEnums
+  PrintEnums,
+  PrintSets
 };
 
 namespace {
@@ -162,6 +164,8 @@
                                "Generate ARM NEON tests for clang"),
                     clEnumValN(PrintEnums, "print-enums",
                                "Print enum values for a class"),
+                    clEnumValN(PrintSets, "print-sets",
+                               "Print expanded sets for testing DAG exprs"),
                     clEnumValEnd));
 
   cl::opt<std::string>
@@ -374,6 +378,21 @@
       Out.os() << "\n";
       break;
     }
+    case PrintSets:
+    {
+      SetTheory Sets(&Records);
+      Sets.addFieldExpander("Set", "Elements");
+      std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Set");
+      for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
+        Out.os() << Recs[i]->getName() << " = [";
+        const std::vector<Record*> *Elts = Sets.expand(Recs[i]);
+        assert(Elts && "Couldn't expand Set instance");
+        for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei)
+          Out.os() << ' ' << (*Elts)[ei]->getName();
+        Out.os() << " ]\n";
+      }
+      break;
+    }
     default:
       assert(1 && "Invalid Action");
       return 1;