diff options
Diffstat (limited to 'contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp')
-rw-r--r-- | contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp | 204 |
1 files changed, 66 insertions, 138 deletions
diff --git a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp index ba30d97..08f6728 100644 --- a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -14,6 +14,7 @@ #include "CodeGenTarget.h" #include "IntrinsicEmitter.h" #include "Record.h" +#include "StringMatcher.h" #include "llvm/ADT/StringExtras.h" #include <algorithm> using namespace llvm; @@ -67,16 +68,19 @@ void IntrinsicEmitter::run(raw_ostream &OS) { void IntrinsicEmitter::EmitPrefix(raw_ostream &OS) { OS << "// VisualStudio defines setjmp as _setjmp\n" - "#if defined(_MSC_VER) && defined(setjmp)\n" - "#define setjmp_undefined_for_visual_studio\n" - "#undef setjmp\n" + "#if defined(_MSC_VER) && defined(setjmp) && \\\n" + " !defined(setjmp_undefined_for_msvc)\n" + "# pragma push_macro(\"setjmp\")\n" + "# undef setjmp\n" + "# define setjmp_undefined_for_msvc\n" "#endif\n\n"; } void IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { - OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_visual_studio)\n" + OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)\n" "// let's return it to _setjmp state\n" - "#define setjmp _setjmp\n" + "# pragma pop_macro(\"setjmp\")\n" + "# undef setjmp_undefined_for_msvc\n" "#endif\n\n"; } @@ -96,37 +100,48 @@ void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, void IntrinsicEmitter:: EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { - // Build a function name -> intrinsic name mapping. - std::map<std::string, unsigned> IntMapping; + // Build a 'first character of function name' -> intrinsic # mapping. + std::map<char, std::vector<unsigned> > IntMapping; for (unsigned i = 0, e = Ints.size(); i != e; ++i) - IntMapping[Ints[i].Name] = i; - + IntMapping[Ints[i].Name[5]].push_back(i); + OS << "// Function name -> enum value recognizer code.\n"; OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; - OS << " switch (Name[5]) {\n"; - OS << " default:\n"; - // Emit the intrinsics in sorted order. - char LastChar = 0; - for (std::map<std::string, unsigned>::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<char, std::vector<unsigned> >::iterator I = IntMapping.begin(), E = IntMapping.end(); I != E; ++I) { - if (I->first[5] != LastChar) { - LastChar = I->first[5]; - OS << " break;\n"; - OS << " case '" << LastChar << "':\n"; + OS << " case '" << I->first << "':\n"; + std::vector<unsigned> &IntList = I->second; + + // Emit all the overloaded intrinsics first, build a table of the + // non-overloaded ones. + std::vector<StringMatcher::StringPair> 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 - if (Ints[I->second].isOverloaded) - OS << " if (Len > " << I->first.size() - << " && !memcmp(Name, \"" << I->first << ".\", " - << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::" - << Ints[I->second].EnumName << ";\n"; - else - OS << " if (Len == " << I->first.size() - << " && !memcmp(Name, \"" << I->first << "\", " - << I->first.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"; } @@ -180,6 +195,8 @@ static void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { OS << "Type::getVoidTy(Context)"; } else if (VT == MVT::Metadata) { OS << "Type::getMetadataTy(Context)"; + } else if (VT == MVT::x86mmx) { + OS << "Type::getX86_MMXTy(Context)"; } else { assert(false && "Unsupported ValueType!"); } @@ -556,11 +573,13 @@ EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ OS << " return DoesNotAccessMemory;\n"; break; case CodeGenIntrinsic::ReadArgMem: + OS << " return OnlyReadsArgumentPointees;\n"; + break; case CodeGenIntrinsic::ReadMem: OS << " return OnlyReadsMemory;\n"; break; case CodeGenIntrinsic::ReadWriteArgMem: - OS << " return AccessesArguments;\n"; + OS << " return OnlyAccessesArgumentPointees;\n"; break; } } @@ -584,112 +603,22 @@ EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ OS << "#endif\n\n"; } -/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified -/// sorted range of builtin names is equal to the current builtin. This breaks -/// it down into a simple tree. -/// -/// At this point, we know that all the builtins in the range have the same name -/// for the first 'CharStart' characters. Only the end of the name needs to be -/// discriminated. -typedef std::map<std::string, std::string>::const_iterator StrMapIterator; -static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End, - unsigned CharStart, unsigned Indent, - std::string TargetPrefix, raw_ostream &OS) { - if (Start == End) return; // empty range. - - // Determine what, if anything, is the same about all these strings. - std::string CommonString = Start->first; - unsigned NumInRange = 0; - for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) { - // Find the first character that doesn't match. - const std::string &ThisStr = I->first; - unsigned NonMatchChar = CharStart; - while (NonMatchChar < CommonString.size() && - NonMatchChar < ThisStr.size() && - CommonString[NonMatchChar] == ThisStr[NonMatchChar]) - ++NonMatchChar; - // Truncate off pieces that don't match. - CommonString.resize(NonMatchChar); - } - - // Just compare the rest of the string. - if (NumInRange == 1) { - if (CharStart != CommonString.size()) { - OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; - if (CharStart) OS << "+" << CharStart; - OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; - OS << CommonString.size() - CharStart << "))\n"; - ++Indent; - } - OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix - << "Intrinsic::"; - OS << Start->second << ";\n"; - return; - } - - // At this point, we potentially have a common prefix for these builtins, emit - // a check for this common prefix. - if (CommonString.size() != CharStart) { - OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; - if (CharStart) OS << "+" << CharStart; - OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; - OS << CommonString.size()-CharStart << ")) {\n"; - - EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, - TargetPrefix, OS); - OS << std::string(Indent*2, ' ') << "}\n"; - return; - } - - // Output a switch on the character that differs across the set. - OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart - << "]) {"; - if (CharStart) - OS << " // \"" << std::string(Start->first.begin(), - Start->first.begin()+CharStart) << "\""; - OS << "\n"; - - for (StrMapIterator I = Start; I != End; ) { - char ThisChar = I->first[CharStart]; - OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n"; - // Figure out the range that has this common character. - StrMapIterator NextChar = I; - for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar; - ++NextChar) - /*empty*/; - EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS); - OS << std::string(Indent*2, ' ') << " break;\n"; - I = NextChar; - } - OS << std::string(Indent*2, ' ') << "}\n"; -} - /// EmitTargetBuiltins - All of the builtins in the specified map are for the /// same target, and we already checked it. static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, const std::string &TargetPrefix, raw_ostream &OS) { - // Rearrange the builtins by length. - std::vector<std::map<std::string, std::string> > BuiltinsByLen; - BuiltinsByLen.reserve(100); - for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { - if (I->first.size() >= BuiltinsByLen.size()) - BuiltinsByLen.resize(I->first.size()+1); - BuiltinsByLen[I->first.size()].insert(*I); - } + std::vector<StringMatcher::StringPair> Results; - // Now that we have all the builtins by their length, emit a switch stmt. - OS << " switch (strlen(BuiltinName)) {\n"; - OS << " default: break;\n"; - for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) { - if (BuiltinsByLen[i].empty()) continue; - OS << " case " << i << ":\n"; - EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(), - 0, 3, TargetPrefix, OS); - OS << " break;\n"; + for (std::map<std::string, std::string>::const_iterator I = BIM.begin(), + E = BIM.end(); I != E; ++I) { + std::string ResultCode = + "return " + TargetPrefix + "Intrinsic::" + I->second + ";"; + Results.push_back(StringMatcher::StringPair(I->first, ResultCode)); } - OS << " }\n"; + + StringMatcher("BuiltinName", Results, OS).Emit(); } @@ -719,24 +648,20 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, if (TargetOnly) { OS << "static " << TargetPrefix << "Intrinsic::ID " << "getIntrinsicForGCCBuiltin(const char " - << "*TargetPrefix, const char *BuiltinName) {\n"; - OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = "; + << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; } else { OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " - << "*TargetPrefix, const char *BuiltinName) {\n"; - OS << " Intrinsic::ID IntrinsicID = "; + << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; } - if (TargetOnly) - OS << "(" << TargetPrefix<< "Intrinsic::ID)"; - - OS << "Intrinsic::not_intrinsic;\n"; + OS << " StringRef BuiltinName(BuiltinNameStr);\n"; + OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n"; // Note: this could emit significantly better code if we cared. for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ OS << " "; if (!I->first.empty()) - OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) "; + OS << "if (TargetPrefix == \"" << I->first << "\") "; else OS << "/* Target Independent Builtins */ "; OS << "{\n"; @@ -745,7 +670,10 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, EmitTargetBuiltins(I->second, TargetPrefix, OS); OS << " }\n"; } - OS << " return IntrinsicID;\n"; + OS << " return "; + if (!TargetPrefix.empty()) + OS << "(" << TargetPrefix << "Intrinsic::ID)"; + OS << "Intrinsic::not_intrinsic;\n"; OS << "}\n"; OS << "#endif\n\n"; } |