From 54911a5303f44694c43608eedf2142e9d65d7c22 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Mon, 15 Jul 2013 16:53:32 +0000 Subject: [PATCH] Teaching llvm-tblgen to not emit a switch statement when there are no case statements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186330 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 67 +++++++++++++++-------- utils/TableGen/FixedLenDecoderEmitter.cpp | 21 ++++--- utils/TableGen/InstrInfoEmitter.cpp | 53 ++++++++++-------- 3 files changed, 88 insertions(+), 53 deletions(-) diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 218af219a8b..b45d40a0a9b 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -114,6 +114,7 @@ #include #include #include +#include using namespace llvm; static cl::opt @@ -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::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::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::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 diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index 0c3017f3892..6e452409ab7 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -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"; } diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 1df8ae54c71..c8304de7b16 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -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 &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 &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 &OpcodeList = i->second; + OS << " switch(Opcode) {\n"; + unsigned TableIndex = 0; + for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end(); + i != e; ++i) { + std::vector &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"; -- 2.34.1