Reintroduce support for overloading target intrinsics
authorMon P Wang <wangmp@apple.com>
Thu, 5 Nov 2009 03:19:08 +0000 (03:19 +0000)
committerMon P Wang <wangmp@apple.com>
Thu, 5 Nov 2009 03:19:08 +0000 (03:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86114 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetIntrinsicInfo.h
lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp
lib/Target/Blackfin/BlackfinIntrinsicInfo.h

index d70aa7e9fdf7bd97364fa2eac0e8b7101a83ff1b..ad8ac925e930a15703e2550f83b1866164804f33 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef LLVM_TARGET_TARGETINTRINSICINFO_H
 #define LLVM_TARGET_TARGETINTRINSICINFO_H
 
+#include <string>
+
 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
index 544dc6824719920fd36f5beba5fd3518e543ef9e..c8c592539513a9a78b6053bdaea46ea5bc455d02 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #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 @@ 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<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));
+}
index 3b59a603ba74c5fadbf0473f319bb90c18db233f..7c4b5a9967d2a88b060d143af78ec55b8215b93f 100644 (file)
@@ -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;
   };
 
 }