summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm-c/Core.h48
-rw-r--r--llvm/lib/IR/Core.cpp44
-rw-r--r--llvm/test/Bindings/llvm-c/echo.ll16
-rw-r--r--llvm/tools/llvm-c-test/echo.cpp12
4 files changed, 119 insertions, 1 deletions
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index c905cfbb08d..c093c0906ce 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2382,6 +2382,54 @@ void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn);
unsigned LLVMGetIntrinsicID(LLVMValueRef Fn);
/**
+ * Create or insert the declaration of an intrinsic. For overloaded intrinsics,
+ * parameter types must be provided to uniquely identify an overload.
+ *
+ * @see llvm::Intrinsic::getDeclaration()
+ */
+LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod,
+ unsigned ID,
+ LLVMTypeRef *ParamTypes,
+ size_t ParamCount);
+
+/**
+ * Retrieves the type of an intrinsic. For overloaded intrinsics, parameter
+ * types must be provided to uniquely identify an overload.
+ *
+ * @see llvm::Intrinsic::getType()
+ */
+LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
+ LLVMTypeRef *ParamTypes, size_t ParamCount);
+
+/**
+ * Retrieves the name of an intrinsic.
+ *
+ * @see llvm::Intrinsic::getName()
+ */
+const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
+
+/**
+ * Copies the name of an overloaded intrinsic identified by a given list of
+ * parameter types.
+ *
+ * Unlike LLVMIntrinsicGetName, the caller is responsible for freeing the
+ * returned string.
+ *
+ * @see llvm::Intrinsic::getName()
+ */
+const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
+ LLVMTypeRef *ParamTypes,
+ size_t ParamCount,
+ size_t *NameLength);
+
+/**
+ * Obtain if the intrinsic identified by the given ID is overloaded.
+ *
+ * @see llvm::Intrinsic::isOverloaded()
+ */
+LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID);
+
+/**
* Obtain the calling function of a function.
*
* The returned value corresponds to the LLVMCallConv enumeration.
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 028f9e6199d..f94b8a04738 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2280,6 +2280,50 @@ unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) {
return 0;
}
+static Intrinsic::ID llvm_map_to_intrinsic_id(unsigned ID) {
+ assert(ID < llvm::Intrinsic::num_intrinsics && "Intrinsic ID out of range");
+ return llvm::Intrinsic::ID(ID);
+}
+
+LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod,
+ unsigned ID,
+ LLVMTypeRef *ParamTypes,
+ size_t ParamCount) {
+ ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
+ auto IID = llvm_map_to_intrinsic_id(ID);
+ return wrap(llvm::Intrinsic::getDeclaration(unwrap(Mod), IID, Tys));
+}
+
+const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) {
+ auto IID = llvm_map_to_intrinsic_id(ID);
+ auto Str = llvm::Intrinsic::getName(IID);
+ *NameLength = Str.size();
+ return Str.data();
+}
+
+LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
+ LLVMTypeRef *ParamTypes, size_t ParamCount) {
+ auto IID = llvm_map_to_intrinsic_id(ID);
+ ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
+ return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, Tys));
+}
+
+const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
+ LLVMTypeRef *ParamTypes,
+ size_t ParamCount,
+ size_t *NameLength) {
+ auto IID = llvm_map_to_intrinsic_id(ID);
+ ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
+ auto Str = llvm::Intrinsic::getName(IID, Tys);
+ *NameLength = Str.length();
+ return strndup(Str.c_str(), Str.length());
+}
+
+LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID) {
+ auto IID = llvm_map_to_intrinsic_id(ID);
+ return llvm::Intrinsic::isOverloaded(IID);
+}
+
unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) {
return unwrap<Function>(Fn)->getCallingConv();
}
diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll
index 580293b3d04..118f822e432 100644
--- a/llvm/test/Bindings/llvm-c/echo.ll
+++ b/llvm/test/Bindings/llvm-c/echo.ll
@@ -170,6 +170,22 @@ define void @with_debuginfo() !dbg !4 {
ret void, !dbg !7
}
+declare i8* @llvm.stacksave()
+declare void @llvm.stackrestore(i8*)
+declare void @llvm.lifetime.start.p0i8(i64, i8*)
+declare void @llvm.lifetime.end.p0i8(i64, i8*)
+
+define void @test_intrinsics() {
+entry:
+ %sp = call i8* @llvm.stacksave()
+ %x = alloca i32
+ %0 = bitcast i32* %x to i8*
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* %0)
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* %0)
+ call void @llvm.stackrestore(i8* %sp)
+ ret void
+}
+
!llvm.dbg.cu = !{!0, !2}
!llvm.module.flags = !{!3}
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index d4c61e2d13c..db926e8acea 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -240,7 +240,17 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
// Try function
if (LLVMIsAFunction(Cst)) {
check_value_kind(Cst, LLVMFunctionValueKind);
- LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
+
+ LLVMValueRef Dst = nullptr;
+ // Try an intrinsic
+ unsigned ID = LLVMGetIntrinsicID(Cst);
+ if (ID > 0 && !LLVMIntrinsicIsOverloaded(ID)) {
+ Dst = LLVMGetIntrinsicDeclaration(M, ID, nullptr, 0);
+ } else {
+ // Try a normal function
+ Dst = LLVMGetNamedFunction(M, Name);
+ }
+
if (Dst)
return Dst;
report_fatal_error("Could not find function");
OpenPOWER on IntegriCloud