From 82c443655d0b840d909bc0dc153ce02614a75f07 Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Thu, 5 Nov 2009 03:19:08 +0000 Subject: [PATCH] Reintroduce support for overloading target intrinsics git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86114 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetIntrinsicInfo.h | 19 ++++++- lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp | 52 ++++++++++++++++++- lib/Target/Blackfin/BlackfinIntrinsicInfo.h | 6 ++- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h index d70aa7e9fdf..ad8ac925e93 100644 --- a/include/llvm/Target/TargetIntrinsicInfo.h +++ b/include/llvm/Target/TargetIntrinsicInfo.h @@ -14,6 +14,8 @@ #ifndef LLVM_TARGET_TARGETINTRINSICINFO_H #define LLVM_TARGET_TARGETINTRINSICINFO_H +#include + namespace llvm { class Function; @@ -32,7 +34,13 @@ public: virtual ~TargetIntrinsicInfo(); /// Return the name of a target intrinsic, e.g. "llvm.bfin.ssync". - virtual const char *getName(unsigned IntrID) const =0; + /// The Tys and numTys parameters are for intrinsics with overloaded types + /// (e.g., those using iAny or fAny). For a declaration for an overloaded + /// intrinsic, Tys should point to an array of numTys pointers to Type, + /// and must provide exactly one type for each overloaded type in the + /// intrinsic. + virtual std::string getName(unsigned IID, const Type **Tys = 0, + unsigned numTys = 0) const = 0; /// Look up target intrinsic by name. Return intrinsic ID or 0 for unknown /// names. @@ -40,6 +48,15 @@ public: /// Return the target intrinsic ID of a function, or 0. virtual unsigned getIntrinsicID(Function *F) const; + + /// Returns true if the intrinsic can be overloaded. + virtual bool isOverloaded(unsigned IID) const = 0; + + /// Create or insert an LLVM Function declaration for an intrinsic, + /// and return it. The Tys and numTys are for intrinsics with overloaded + /// types. See above for more information. + virtual Function *getDeclaration(Module *M, unsigned ID, const Type **Tys = 0, + unsigned numTys = 0) const = 0; }; } // End llvm namespace diff --git a/lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp b/lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp index 544dc682471..c8c59253951 100644 --- a/lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp +++ b/lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp @@ -12,7 +12,11 @@ //===----------------------------------------------------------------------===// #include "BlackfinIntrinsicInfo.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" #include "llvm/Intrinsics.h" +#include "llvm/Module.h" +#include "llvm/Type.h" #include "llvm/Support/raw_ostream.h" #include @@ -30,18 +34,21 @@ namespace bfinIntrinsic { } -const char *BlackfinIntrinsicInfo::getName(unsigned IntrID) const { +std::string BlackfinIntrinsicInfo::getName(unsigned IntrID, const Type **Tys, + unsigned numTys) const { static const char *const names[] = { #define GET_INTRINSIC_NAME_TABLE #include "BlackfinGenIntrinsics.inc" #undef GET_INTRINSIC_NAME_TABLE }; + assert(!isOverloaded(IntrID) && "Blackfin intrinsics are not overloaded"); if (IntrID < Intrinsic::num_intrinsics) return 0; assert(IntrID < bfinIntrinsic::num_bfin_intrinsics && "Invalid intrinsic ID"); - return names[IntrID - Intrinsic::num_intrinsics]; + std::string Result(names[IntrID - Intrinsic::num_intrinsics]); + return Result; } unsigned @@ -51,3 +58,44 @@ BlackfinIntrinsicInfo::lookupName(const char *Name, unsigned Len) const { #undef GET_FUNCTION_RECOGNIZER return 0; } + +bool BlackfinIntrinsicInfo::isOverloaded(unsigned IntrID) const { + // Overload Table + const bool OTable[] = { + false, // illegal intrinsic +#define GET_INTRINSIC_OVERLOAD_TABLE +#include "BlackfinGenIntrinsics.inc" +#undef GET_INTRINSIC_OVERLOAD_TABLE + }; + if (IntrID == 0) + return false; + else + return OTable[IntrID - Intrinsic::num_intrinsics]; +} + +/// This defines the "getAttributes(ID id)" method. +#define GET_INTRINSIC_ATTRIBUTES +#include "BlackfinGenIntrinsics.inc" +#undef GET_INTRINSIC_ATTRIBUTES + +static const FunctionType *getType(LLVMContext &Context, unsigned id) { + const Type *ResultTy = NULL; + std::vector ArgTys; + bool IsVarArg = false; + +#define GET_INTRINSIC_GENERATOR +#include "BlackfinGenIntrinsics.inc" +#undef GET_INTRINSIC_GENERATOR + + return FunctionType::get(ResultTy, ArgTys, IsVarArg); +} + +Function *BlackfinIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID, + const Type **Tys, + unsigned numTy) const { + assert(!isOverloaded(IntrID) && "Blackfin intrinsics are not overloaded"); + AttrListPtr AList = getAttributes((bfinIntrinsic::ID) IntrID); + return cast(M->getOrInsertFunction(getName(IntrID), + getType(M->getContext(), IntrID), + AList)); +} diff --git a/lib/Target/Blackfin/BlackfinIntrinsicInfo.h b/lib/Target/Blackfin/BlackfinIntrinsicInfo.h index 3b59a603ba7..7c4b5a9967d 100644 --- a/lib/Target/Blackfin/BlackfinIntrinsicInfo.h +++ b/lib/Target/Blackfin/BlackfinIntrinsicInfo.h @@ -19,8 +19,12 @@ namespace llvm { class BlackfinIntrinsicInfo : public TargetIntrinsicInfo { public: - const char *getName(unsigned IntrID) const; + std::string getName(unsigned IntrID, const Type **Tys = 0, + unsigned numTys = 0) const; unsigned lookupName(const char *Name, unsigned Len) const; + bool isOverloaded(unsigned IID) const; + Function *getDeclaration(Module *M, unsigned ID, const Type **Tys = 0, + unsigned numTys = 0) const; }; } -- 2.34.1