From c4de3dec62c3f60ae7297f93c19c799c403c2e9f Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sun, 1 Apr 2007 07:20:02 +0000 Subject: For PR1297: Implement code generation for overloaded intrinsic functions. The basic difference is that "actual" argument types must be provided when constructing intrinsic names and types. Also, for recognition, only the prefix is examined. If it matches, the suffix is assumed to match. The suffix is checked by the Verifier, however. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35539 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/IntrinsicEmitter.cpp | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'utils/TableGen/IntrinsicEmitter.cpp') diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 6247da2af5..f884c424a7 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -74,9 +74,9 @@ void IntrinsicEmitter:: EmitFnNameRecognizer(const std::vector &Ints, std::ostream &OS) { // Build a function name -> intrinsic name mapping. - std::map IntMapping; + std::map IntMapping; for (unsigned i = 0, e = Ints.size(); i != e; ++i) - IntMapping[Ints[i].Name] = Ints[i].EnumName; + IntMapping[Ints[i].Name] = i; OS << "// Function name -> enum value recognizer code.\n"; OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; @@ -84,7 +84,7 @@ EmitFnNameRecognizer(const std::vector &Ints, OS << " default:\n"; // Emit the intrinsics in sorted order. char LastChar = 0; - for (std::map::iterator I = IntMapping.begin(), + for (std::map::iterator I = IntMapping.begin(), E = IntMapping.end(); I != E; ++I) { if (I->first[5] != LastChar) { LastChar = I->first[5]; @@ -92,9 +92,15 @@ EmitFnNameRecognizer(const std::vector &Ints, OS << " case '" << LastChar << "':\n"; } - OS << " if (Len == " << I->first.size() - << " && !memcmp(Name, \"" << I->first << "\", Len)) return Intrinsic::" - << I->second << ";\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() + << ")) return Intrinsic::" << Ints[I->second].EnumName << ";\n"; + else + OS << " if (Len == " << I->first.size() + << " && !memcmp(Name, \"" << I->first << "\", Len)) return Intrinsic::" + << Ints[I->second].EnumName << ";\n"; } OS << " }\n"; OS << " // The 'llvm.' namespace is reserved!\n"; @@ -130,16 +136,20 @@ static bool EmitTypeVerify(std::ostream &OS, Record *ArgType) { return false; } -static void EmitTypeGenerate(std::ostream &OS, Record *ArgType) { +static void EmitTypeGenerate(std::ostream &OS, Record *ArgType, unsigned ArgNo){ if (ArgType->isSubClassOf("LLVMIntegerType")) { - OS << "IntegerType::get(" << ArgType->getValueAsInt("Width") << ")"; + unsigned BitWidth = ArgType->getValueAsInt("Width"); + if (BitWidth == 0) + OS << "Tys[" << ArgNo << "]"; + else + OS << "IntegerType::get(" << BitWidth << ")"; } else if (ArgType->isSubClassOf("LLVMVectorType")) { OS << "VectorType::get("; - EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy")); + EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); OS << ", " << ArgType->getValueAsInt("NumElts") << ")"; } else if (ArgType->isSubClassOf("LLVMPointerType")) { OS << "PointerType::get("; - EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy")); + EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); OS << ")"; } else if (ArgType->isSubClassOf("LLVMEmptyStructType")) { OS << "StructType::get(std::vector())"; @@ -194,7 +204,7 @@ void IntrinsicEmitter::EmitVerifier(const std::vector &Ints, } const std::vector &ArgTypes = I->first; - OS << " VerifyIntrinsicPrototype(IF, "; + OS << " VerifyIntrinsicPrototype(ID, IF, "; bool VarArg = false; for (unsigned j = 0; j != ArgTypes.size(); ++j) { VarArg = EmitTypeVerify(OS, ArgTypes[j]); @@ -246,12 +256,12 @@ void IntrinsicEmitter::EmitGenerator(const std::vector &Ints, } OS << " ResultTy = "; - EmitTypeGenerate(OS, ArgTypes[0]); + EmitTypeGenerate(OS, ArgTypes[0], 0); OS << ";\n"; for (unsigned j = 1; j != N; ++j) { OS << " ArgTys.push_back("; - EmitTypeGenerate(OS, ArgTypes[j]); + EmitTypeGenerate(OS, ArgTypes[j], j); OS << ");\n"; } -- cgit v1.2.3