Reintroduce support for overloading target intrinsics


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86114 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp b/lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp
index 544dc68..c8c5925 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 <cstring>
 
@@ -30,18 +34,21 @@
 
 }
 
-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 @@
 #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<const Type*> 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<Function>(M->getOrInsertFunction(getName(IntrID),
+                                               getType(M->getContext(), IntrID),
+                                               AList));
+}
diff --git a/lib/Target/Blackfin/BlackfinIntrinsicInfo.h b/lib/Target/Blackfin/BlackfinIntrinsicInfo.h
index 3b59a60..7c4b5a9 100644
--- a/lib/Target/Blackfin/BlackfinIntrinsicInfo.h
+++ b/lib/Target/Blackfin/BlackfinIntrinsicInfo.h
@@ -19,8 +19,12 @@
 
   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;
   };
 
 }