]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
Teaching llvm-tblgen to not emit a switch statement when there are no case statements.
authorAaron Ballman <aaron@aaronballman.com>
Mon, 15 Jul 2013 16:53:32 +0000 (16:53 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Mon, 15 Jul 2013 16:53:32 +0000 (16:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186330 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/AsmMatcherEmitter.cpp
utils/TableGen/FixedLenDecoderEmitter.cpp
utils/TableGen/InstrInfoEmitter.cpp

index 218af219a8b7878e6ca0b184bea2993db9a49ed1..b45d40a0a9ba4655a69ba83b6f1b32826f796795 100644 (file)
 #include <cassert>
 #include <map>
 #include <set>
+#include <sstream>
 using namespace llvm;
 
 static cl::opt<std::string>
@@ -2066,9 +2067,11 @@ static void emitIsSubclass(CodeGenTarget &Target,
   OS << "  if (A == B)\n";
   OS << "    return true;\n\n";
 
-  OS << "  switch (A) {\n";
-  OS << "  default:\n";
-  OS << "    return false;\n";
+  std::stringstream SS;
+  unsigned Count = 0;
+  SS << "  switch (A) {\n";
+  SS << "  default:\n";
+  SS << "    return false;\n";
   for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
          ie = Infos.end(); it != ie; ++it) {
     ClassInfo &A = **it;
@@ -2084,21 +2087,35 @@ static void emitIsSubclass(CodeGenTarget &Target,
 
     if (SuperClasses.empty())
       continue;
+    ++Count;
 
-    OS << "\n  case " << A.Name << ":\n";
+    SS << "\n  case " << A.Name << ":\n";
 
     if (SuperClasses.size() == 1) {
-      OS << "    return B == " << SuperClasses.back() << ";\n";
+      SS << "    return B == " << SuperClasses.back().str() << ";\n";
       continue;
     }
 
-    OS << "    switch (B) {\n";
-    OS << "    default: return false;\n";
-    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
-      OS << "    case " << SuperClasses[i] << ": return true;\n";
-    OS << "    }\n";
+    if (!SuperClasses.empty()) {
+      SS << "    switch (B) {\n";
+      SS << "    default: return false;\n";
+      for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+        SS << "    case " << SuperClasses[i].str() << ": return true;\n";
+      SS << "    }\n";
+    } else {
+      // No case statement to emit
+      SS << "    return false;\n";
+    }
   }
-  OS << "  }\n";
+  SS << "  }\n";
+
+  // If there were case statements emitted into the string stream, write them
+  // to the output stream, otherwise write the default.
+  if (Count)
+    OS << SS.str();
+  else
+    OS << "  return false;\n";
+
   OS << "}\n\n";
 }
 
@@ -2194,18 +2211,24 @@ static void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) {
 static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
   OS << "// User-level names for subtarget features that participate in\n"
      << "// instruction matching.\n"
-     << "static const char *getSubtargetFeatureName(unsigned Val) {\n"
-     << "  switch(Val) {\n";
-  for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
-         it = Info.SubtargetFeatures.begin(),
-         ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
-    SubtargetFeatureInfo &SFI = *it->second;
-    // FIXME: Totally just a placeholder name to get the algorithm working.
-    OS << "  case " << SFI.getEnumName() << ": return \""
-       << SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
+     << "static const char *getSubtargetFeatureName(unsigned Val) {\n";
+  if (!Info.SubtargetFeatures.empty()) {
+    OS << "  switch(Val) {\n";
+    for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
+           it = Info.SubtargetFeatures.begin(),
+           ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
+      SubtargetFeatureInfo &SFI = *it->second;
+      // FIXME: Totally just a placeholder name to get the algorithm working.
+      OS << "  case " << SFI.getEnumName() << ": return \""
+         << SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
+    }
+    OS << "  default: return \"(unknown)\";\n";
+    OS << "  }\n";
+  } else {
+    // Nothing to emit, so skip the switch
+    OS << "  return \"(unknown)\";\n";
   }
-  OS << "  default: return \"(unknown)\";\n";
-  OS << "  }\n}\n\n";
+  OS << "}\n\n";
 }
 
 /// emitComputeAvailableFeatures - Emit the function to compute the list of
index 0c3017f38920dd5e2828c478a3ac6ef22a5810cd..6e452409ab73f26883498b150949c57749ecbdad 100644 (file)
@@ -879,15 +879,20 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
   OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
     << "uint64_t Bits) {\n";
   Indentation += 2;
-  OS.indent(Indentation) << "switch (Idx) {\n";
-  OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
-  unsigned Index = 0;
-  for (PredicateSet::const_iterator I = Predicates.begin(), E = Predicates.end();
-       I != E; ++I, ++Index) {
-    OS.indent(Indentation) << "case " << Index << ":\n";
-    OS.indent(Indentation+2) << "return (" << *I << ");\n";
+  if (!Predicates.empty()) {
+    OS.indent(Indentation) << "switch (Idx) {\n";
+    OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
+    unsigned Index = 0;
+    for (PredicateSet::const_iterator I = Predicates.begin(), E = Predicates.end();
+         I != E; ++I, ++Index) {
+      OS.indent(Indentation) << "case " << Index << ":\n";
+      OS.indent(Indentation+2) << "return (" << *I << ");\n";
+    }
+    OS.indent(Indentation) << "}\n";
+  } else {
+    // No case statement to emit
+    OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
   }
-  OS.indent(Indentation) << "}\n";
   Indentation -= 2;
   OS.indent(Indentation) << "}\n\n";
 }
index 1df8ae54c7167bef2c968a62a1f6b0d94ed9dcf1..c8304de7b16d9f4365e6bed1dfc1986de2f2ac83 100644 (file)
@@ -270,33 +270,40 @@ void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
   OS << "namespace llvm {";
   OS << "namespace " << Namespace << " {\n";
   OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
-  OS << "  static const int16_t OperandMap []["<< Operands.size() << "] = {\n";
-  for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end();
-                                                     i != e; ++i) {
-    const std::map<unsigned, unsigned> &OpList = i->first;
-    OS << "{";
-
-    // Emit a row of the OperandMap table
-    for (unsigned ii = 0, ie = Operands.size(); ii != ie; ++ii)
-      OS << (OpList.count(ii) == 0 ? -1 : (int)OpList.find(ii)->second) << ", ";
-
-    OS << "},\n";
-  }
-  OS << "};\n";
+  if (!Operands.empty()) {
+    OS << "  static const int16_t OperandMap [][" << Operands.size()
+       << "] = {\n";
+    for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end();
+                                                       i != e; ++i) {
+      const std::map<unsigned, unsigned> &OpList = i->first;
+      OS << "{";
+
+      // Emit a row of the OperandMap table
+      for (unsigned ii = 0, ie = Operands.size(); ii != ie; ++ii)
+        OS << (OpList.count(ii) == 0 ? -1 : (int)OpList.find(ii)->second)
+           << ", ";
+
+      OS << "},\n";
+    }
+    OS << "};\n";
 
-  OS << "  switch(Opcode) {\n";
-  unsigned TableIndex = 0;
-  for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end();
-                                                     i != e; ++i) {
-    std::vector<std::string> &OpcodeList = i->second;
+    OS << "  switch(Opcode) {\n";
+    unsigned TableIndex = 0;
+    for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end();
+                                                       i != e; ++i) {
+      std::vector<std::string> &OpcodeList = i->second;
 
-    for (unsigned ii = 0, ie = OpcodeList.size(); ii != ie; ++ii)
-      OS << "  case " << OpcodeList[ii] << ":\n";
+      for (unsigned ii = 0, ie = OpcodeList.size(); ii != ie; ++ii)
+        OS << "  case " << OpcodeList[ii] << ":\n";
 
-    OS << "    return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
+      OS << "    return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
+    }
+    OS << "    default: return -1;\n";
+    OS << "  }\n";
+  } else {
+    // There are no operands, so no need to emit anything
+    OS << "  return -1;\n";
   }
-  OS << "    default: return -1;\n";
-  OS << "  }\n";
   OS << "}\n";
   OS << "} // End namespace " << Namespace << "\n";
   OS << "} // End namespace llvm\n";