From cc67c75b67d22653ea9380020e9a40381233901d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 6 Sep 2010 03:58:45 +0000 Subject: [PATCH] emit the LLVM intrinsic name -> intrinsic number mapping table with StringMatcher instead of a linear sequence of memcmps. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113145 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/IntrinsicEmitter.cpp | 61 +++++++++++++++++------------ utils/TableGen/StringMatcher.cpp | 4 +- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 2eed07cd4b0..cee95cf6914 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -97,39 +97,48 @@ void IntrinsicEmitter::EmitEnumInfo(const std::vector &Ints, void IntrinsicEmitter:: EmitFnNameRecognizer(const std::vector &Ints, raw_ostream &OS) { - // Build a function name -> intrinsic name mapping. - std::map IntMapping; + // Build a 'first character of function name' -> intrinsic # mapping. + std::map > IntMapping; for (unsigned i = 0, e = Ints.size(); i != e; ++i) - IntMapping[Ints[i].Name.substr(5)] = i; - + IntMapping[Ints[i].Name[5]].push_back(i); + OS << "// Function name -> enum value recognizer code.\n"; OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; - OS << " Name += 5; Len -= 5; // Skip over 'llvm.'\n"; - OS << " switch (*Name) { // Dispatch on first letter.\n"; - OS << " default:\n"; - // Emit the intrinsics in sorted order. - char LastChar = 0; - for (std::map::iterator I = IntMapping.begin(), + OS << " StringRef NameR(Name+6, Len-6); // Skip over 'llvm.'\n"; + OS << " switch (Name[5]) { // Dispatch on first letter.\n"; + OS << " default: break;\n"; + // Emit the intrinsic matching stuff by first letter. + for (std::map >::iterator I = IntMapping.begin(), E = IntMapping.end(); I != E; ++I) { - if (I->first[0] != LastChar) { - LastChar = I->first[0]; - OS << " break;\n"; - OS << " case '" << LastChar << "':\n"; + OS << " case '" << I->first << "':\n"; + std::vector &IntList = I->second; + + // Emit all the overloaded intrinsics first, build a table of the + // non-overloaded ones. + std::vector MatchTable; + + for (unsigned i = 0, e = IntList.size(); i != e; ++i) { + unsigned IntNo = IntList[i]; + std::string Result = "return " + TargetPrefix + "Intrinsic::" + + Ints[IntNo].EnumName + ";"; + + if (!Ints[IntNo].isOverloaded) { + MatchTable.push_back(std::make_pair(Ints[IntNo].Name.substr(6),Result)); + continue; + } + + // For overloaded intrinsics, only the prefix needs to match + std::string TheStr = Ints[IntNo].Name.substr(6); + TheStr += '.'; // Require "bswap." instead of bswap. + OS << " if (NameR.startswith(\"" << TheStr << "\")) " + << Result << '\n'; } - // For overloaded intrinsics, only the prefix needs to match - std::string TheStr = I->first; - if (Ints[I->second].isOverloaded) { - TheStr += '.'; // Require "bswap." instead of bswap. - OS << " if (Len > " << I->first.size(); - } else { - OS << " if (Len == " << I->first.size(); - } - - OS << " && !memcmp(Name, \"" << TheStr << "\", " - << TheStr.size() << ")) return " << TargetPrefix << "Intrinsic::" - << Ints[I->second].EnumName << ";\n"; + // Emit the matcher logic for the fixed length strings. + StringMatcher("NameR", MatchTable, OS).Emit(1); + OS << " break; // end of '" << I->first << "' case.\n"; } + OS << " }\n"; OS << "#endif\n\n"; } diff --git a/utils/TableGen/StringMatcher.cpp b/utils/TableGen/StringMatcher.cpp index 68fbe7fcf31..1c43b6d1c8a 100644 --- a/utils/TableGen/StringMatcher.cpp +++ b/utils/TableGen/StringMatcher.cpp @@ -78,9 +78,9 @@ EmitStringMatcherForChar(const std::vector &Matches, << Matches[0]->first[CharNo] << "')\n"; OS << Indent << " break;\n"; } else { - // Do the comparison with if (Str.substr(1,3) != "foo"). + // Do the comparison with if (Str.substr(1, 3) != "foo"). // FIXME: Need to escape general strings. - OS << Indent << "if (" << StrVariableName << ".substr(" << CharNo << "," + OS << Indent << "if (" << StrVariableName << ".substr(" << CharNo << ", " << NumChars << ") != \""; OS << Matches[0]->first.substr(CharNo, NumChars) << "\")\n"; OS << Indent << " break;\n";