Reverting r237234, "Use std::bitset for SubtargetFeatures"

The buildbots are still not satisfied.
MIPS and ARM are failing (even though at least MIPS was expected to pass).

llvm-svn: 237245
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 65d930a..159bc23 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -2248,7 +2248,7 @@
     Info.AsmParser->getValueAsString("AsmParserClassName");
 
   OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
-     << "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
+     << "ComputeAvailableFeatures(uint64_t FB) const {\n";
   OS << "  uint64_t Features = 0;\n";
   for (const auto &SF : Info.SubtargetFeatures) {
     const SubtargetFeatureInfo &SFI = SF.second;
@@ -2270,10 +2270,12 @@
         Cond = Cond.substr(1);
       }
 
-      OS << "(";
+      OS << "((FB & " << Info.Target.getName() << "::" << Cond << ")";
       if (Neg)
-        OS << "!";
-      OS << "FB[" << Info.Target.getName() << "::" << Cond << "])";
+        OS << " == 0";
+      else
+        OS << " != 0";
+      OS << ")";
 
       if (Comma.second.empty())
         break;
@@ -2643,7 +2645,7 @@
   OS << "#undef GET_ASSEMBLER_HEADER\n";
   OS << "  // This should be included into the middle of the declaration of\n";
   OS << "  // your subclasses implementation of MCTargetAsmParser.\n";
-  OS << "  uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
+  OS << "  uint64_t ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
   OS << "  void convertToMCInst(unsigned Kind, MCInst &Inst, "
      << "unsigned Opcode,\n"
      << "                       const OperandVector "
diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index 6cb0d29..a4a46b3 100644
--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -848,7 +848,7 @@
   // The predicate function is just a big switch statement based on the
   // input predicate index.
   OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
-    << "const FeatureBitset& Bits) {\n";
+    << "uint64_t Bits) {\n";
   Indentation += 2;
   if (!Predicates.empty()) {
     OS.indent(Indentation) << "switch (Idx) {\n";
@@ -1102,10 +1102,10 @@
 static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
                                      const std::string &PredicateNamespace) {
   if (str[0] == '!')
-    o << "!Bits[" << PredicateNamespace << "::"
-      << str.slice(1,str.size()) << "]";
+    o << "!(Bits & " << PredicateNamespace << "::"
+      << str.slice(1,str.size()) << ")";
   else
-    o << "Bits[" << PredicateNamespace << "::" << str << "]";
+    o << "(Bits & " << PredicateNamespace << "::" << str << ")";
 }
 
 bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
@@ -2012,7 +2012,7 @@
      << "                                      InsnType insn, uint64_t Address,\n"
      << "                                      const void *DisAsm,\n"
      << "                                      const MCSubtargetInfo &STI) {\n"
-     << "  const FeatureBitset& Bits = STI.getFeatureBits();\n"
+     << "  uint64_t Bits = STI.getFeatureBits();\n"
      << "\n"
      << "  const uint8_t *Ptr = DecodeTable;\n"
      << "  uint32_t CurFieldValue = 0;\n"
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index ba1f592..d007c1d 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -549,15 +549,15 @@
   CodeGenTarget &Target = CDP.getTargetInfo();
   if (Inst.HasComplexDeprecationPredicate)
     // Emit a function pointer to the complex predicate method.
-    OS << ", { } "
+    OS << ",0"
        << ",&get" << Inst.DeprecatedReason << "DeprecationInfo";
   else if (!Inst.DeprecatedReason.empty())
     // Emit the Subtarget feature.
-    OS << ", { " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
-       << "} ,nullptr";
+    OS << "," << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
+       << ",nullptr";
   else
     // Instruction isn't deprecated.
-    OS << ", { } ,nullptr";
+    OS << ",0,nullptr";
 
   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
 }
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index de9c7a6..5ab7b13 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -16,7 +16,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/MC/MCInstrItineraries.h"
-#include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Format.h"
 #include "llvm/TableGen/Error.h"
@@ -63,7 +62,7 @@
   CodeGenSchedModels &SchedModels;
   std::string Target;
 
-  void Enumeration(raw_ostream &OS, const char *ClassName);
+  void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits);
   unsigned FeatureKeyValues(raw_ostream &OS);
   unsigned CPUKeyValues(raw_ostream &OS);
   void FormItineraryStageString(const std::string &Names,
@@ -113,7 +112,8 @@
 // Enumeration - Emit the specified class as an enumeration.
 //
 void SubtargetEmitter::Enumeration(raw_ostream &OS,
-                                   const char *ClassName) {
+                                   const char *ClassName,
+                                   bool isBits) {
   // Get all records of class and sort
   std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
   std::sort(DefList.begin(), DefList.end(), LessRecord());
@@ -121,8 +121,8 @@
   unsigned N = DefList.size();
   if (N == 0)
     return;
-  if (N > MAX_SUBTARGET_FEATURES)
-    PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");
+  if (N > 64)
+    PrintFatalError("Too many (> 64) subtarget features!");
 
   OS << "namespace " << Target << " {\n";
 
@@ -135,14 +135,21 @@
     Record *Def = DefList[i];
 
     // Get and emit name
-    OS << "  " << Def->getName() << " = " << i;
+    OS << "  " << Def->getName();
+
+    // If bit flags then emit expression (1 << i)
+    if (isBits)  OS << " = " << " 1ULL << " << i;
+
+    // Depending on 'if more in the list' emit comma
     if (++i < N) OS << ",";
 
     OS << "\n";
   }
 
-  // Close enumeration and namespace
-  OS << "};\n}\n";
+  // Close enumeration
+  OS << "};\n";
+
+  OS << "}\n";
 }
 
 //
@@ -176,24 +183,22 @@
 
     if (CommandLineName.empty()) continue;
 
-    // Emit as { "feature", "description", { featureEnum }, { i1 , i2 , ... , in } }
+    // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
     OS << "  { "
        << "\"" << CommandLineName << "\", "
        << "\"" << Desc << "\", "
-       << "{ " << Target << "::" << Name << " }, ";
+       << Target << "::" << Name << ", ";
 
     const std::vector<Record*> &ImpliesList =
       Feature->getValueAsListOfDefs("Implies");
 
     if (ImpliesList.empty()) {
-      OS << "{ }";
+      OS << "0ULL";
     } else {
-      OS << "{ ";
       for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
         OS << Target << "::" << ImpliesList[j]->getName();
-        if (++j < M) OS << ", ";
+        if (++j < M) OS << " | ";
       }
-      OS << " }";
     }
 
     OS << " }";
@@ -235,24 +240,22 @@
     const std::vector<Record*> &FeatureList =
       Processor->getValueAsListOfDefs("Features");
 
-    // Emit as { "cpu", "description", { f1 , f2 , ... fn } },
+    // Emit as { "cpu", "description", f1 | f2 | ... fn },
     OS << "  { "
        << "\"" << Name << "\", "
        << "\"Select the " << Name << " processor\", ";
 
     if (FeatureList.empty()) {
-      OS << "{ }";
+      OS << "0ULL";
     } else {
-      OS << "{ ";
       for (unsigned j = 0, M = FeatureList.size(); j < M;) {
         OS << Target << "::" << FeatureList[j]->getName();
-        if (++j < M) OS << ", ";
+        if (++j < M) OS << " | ";
       }
-      OS << " }";
     }
 
-    // The { } is for the "implies" section of this data structure.
-    OS << ", { } }";
+    // The "0" is for the "implies" section of this data structure.
+    OS << ", 0ULL }";
 
     // Depending on 'if more in the list' emit comma
     if (++i < N) OS << ",";
@@ -1380,7 +1383,7 @@
   }
 
   OS << "  InitMCProcessorInfo(CPU, FS);\n"
-     << "  const FeatureBitset& Bits = getFeatureBits();\n";
+     << "  uint64_t Bits = getFeatureBits();\n";
 
   for (unsigned i = 0; i < Features.size(); i++) {
     // Next record
@@ -1390,12 +1393,12 @@
     const std::string &Attribute = R->getValueAsString("Attribute");
 
     if (Value=="true" || Value=="false")
-      OS << "  if (Bits[" << Target << "::"
-         << Instance << "]) "
+      OS << "  if ((Bits & " << Target << "::"
+         << Instance << ") != 0) "
          << Attribute << " = " << Value << ";\n";
     else
-      OS << "  if (Bits[" << Target << "::"
-         << Instance << "] && "
+      OS << "  if ((Bits & " << Target << "::"
+         << Instance << ") != 0 && "
          << Attribute << " < " << Value << ") "
          << Attribute << " = " << Value << ";\n";
   }
@@ -1413,7 +1416,7 @@
   OS << "#undef GET_SUBTARGETINFO_ENUM\n";
 
   OS << "namespace llvm {\n";
-  Enumeration(OS, "SubtargetFeature");
+  Enumeration(OS, "SubtargetFeature", true);
   OS << "} // End llvm namespace \n";
   OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";