Teaching llvm-tblgen to not emit a switch statement when there are no case statements.

llvm-svn: 186330
This commit is contained in:
Aaron Ballman 2013-07-15 16:53:32 +00:00
parent a75eba9c05
commit e59e358823
3 changed files with 89 additions and 54 deletions

View File

@ -114,6 +114,7 @@
#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

View 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";
}

View 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 << "{";
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) << ", ";
// 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 << "};\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;
for (unsigned ii = 0, ie = OpcodeList.size(); ii != ie; ++ii)
OS << " case " << OpcodeList[ii] << ":\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 << "};\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;
for (unsigned ii = 0, ie = OpcodeList.size(); ii != ie; ++ii)
OS << " case " << OpcodeList[ii] << ":\n";
OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
}
OS << " default: return -1;\n";
OS << " }\n";
OS << "}\n";
OS << "} // End namespace " << Namespace << "\n";
OS << "} // End namespace llvm\n";