[llvm] [LLVM] Add `LLVMIntrinsicCopyName` to LLVM C API (PR #112197)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 22 14:39:04 PDT 2024
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/112197
>From b48aa0c101f54ae9ca6dc0a5411dba7294962b57 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Mon, 14 Oct 2024 06:18:36 -0700
Subject: [PATCH] [LLVM] Add `LLVMIntrinsicCopyName` to LLVM C API
Also change `LLVMIntrinsicCopyOverloadedName` and
`LLVMIntrinsicCopyOverloadedName2` to return `char *` instead of
`const char*` since the returned memory is owned by the caller and
we expect that pointer to be passed to `free` to deallocate it.
---
llvm/docs/ReleaseNotes.md | 4 +++
llvm/include/llvm-c/Core.h | 21 ++++++++-----
llvm/lib/IR/Core.cpp | 20 ++++++++-----
llvm/unittests/IR/IntrinsicsTest.cpp | 45 ++++++++++++++++++++++++++++
4 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 0c4cd437dac0b4..f1c6f6b2c3e8a8 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -258,6 +258,10 @@ Changes to the C API
* Added `LLVMAtomicRMWBinOpUSubCond` and `LLVMAtomicRMWBinOpUSubSat` to `LLVMAtomicRMWBinOp` enum for AtomicRMW instructions.
+* Added `LLVMIntrinsicCopyName` and changed `LLVMIntrinsicCopyOverloadedName`
+ and `LLVMIntrinsicCopyOverloadedName2` to return `char *` instead of
+ `const char *`.
+
Changes to the CodeGen infrastructure
-------------------------------------
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 55649d89a6b8f4..a84a247c57200e 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2833,11 +2833,17 @@ LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
*/
const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
+/**
+ * Copies the name of an intrinsic. The caller is responsible for freeing the
+ * returned string.
+ *
+ * @see llvm::Intrinsic::getName()
+ */
+char *LLVMIntrinsicCopyName(unsigned ID, size_t *NameLength);
+
/** Deprecated: Use LLVMIntrinsicCopyOverloadedName2 instead. */
-const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
- LLVMTypeRef *ParamTypes,
- size_t ParamCount,
- size_t *NameLength);
+char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes,
+ size_t ParamCount, size_t *NameLength);
/**
* Copies the name of an overloaded intrinsic identified by a given list of
@@ -2850,10 +2856,9 @@ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
*
* @see llvm::Intrinsic::getName()
*/
-const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
- LLVMTypeRef *ParamTypes,
- size_t ParamCount,
- size_t *NameLength);
+char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
+ LLVMTypeRef *ParamTypes,
+ size_t ParamCount, size_t *NameLength);
/**
* Obtain if the intrinsic identified by the given ID is overloaded.
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 1cf998c6850068..65572116e48ca5 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2478,6 +2478,13 @@ const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) {
return Str.data();
}
+char *LLVMIntrinsicCopyName(unsigned ID, size_t *NameLength) {
+ auto IID = llvm_map_to_intrinsic_id(ID);
+ auto Str = llvm::Intrinsic::getName(IID);
+ *NameLength = Str.size();
+ return strdup(Str.data());
+}
+
LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
LLVMTypeRef *ParamTypes, size_t ParamCount) {
auto IID = llvm_map_to_intrinsic_id(ID);
@@ -2485,10 +2492,8 @@ LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, Tys));
}
-const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
- LLVMTypeRef *ParamTypes,
- size_t ParamCount,
- size_t *NameLength) {
+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::getNameNoUnnamedTypes(IID, Tys);
@@ -2496,10 +2501,9 @@ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
return strdup(Str.c_str());
}
-const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
- LLVMTypeRef *ParamTypes,
- size_t ParamCount,
- size_t *NameLength) {
+char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, 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, unwrap(Mod));
diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp
index b32a1991448595..afba07a12e8cad 100644
--- a/llvm/unittests/IR/IntrinsicsTest.cpp
+++ b/llvm/unittests/IR/IntrinsicsTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/Intrinsics.h"
+#include "llvm-c/Core.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/IRBuilder.h"
@@ -127,6 +128,50 @@ TEST(IntrinsicNameLookup, MSBuiltinLookup) {
EXPECT_EQ(ID, getIntrinsicForMSBuiltin(Target, Builtin));
}
+// Test C API to get/copy LLVM intrinsic name.
+TEST(IntrinsicNameLookup, LLVMIntrinsicGetCopyNameSimple) {
+ static constexpr struct {
+ Intrinsic::ID ID;
+ const char *Name;
+ } Tests[] = {{Intrinsic::not_intrinsic, "not_intrinsic"},
+ {Intrinsic::assume, "llvm.assume"},
+ {Intrinsic::coro_free, "llvm.coro.free"},
+ {Intrinsic::aarch64_break, "llvm.aarch64.break"},
+ {Intrinsic::x86_int, "llvm.x86.int"}};
+
+ for (auto [ID, ExpectedName] : Tests) {
+ size_t NameSize = 0;
+ const char *CName = LLVMIntrinsicGetName(ID, &NameSize);
+ StringRef Name(CName, NameSize);
+
+ // Verify we get correct name.
+ EXPECT_EQ(Name, ExpectedName);
+ const char *CName1 = LLVMIntrinsicGetName(ID, &NameSize);
+
+ // Verify we get the same pointer and length the second time.
+ EXPECT_EQ(CName, CName1);
+ EXPECT_EQ(NameSize, Name.size());
+ }
+
+ // Now test the copy API.
+ for (auto [ID, ExpectedName] : Tests) {
+ size_t NameSize = 0;
+ char *CName = LLVMIntrinsicCopyName(ID, &NameSize);
+ StringRef Name(CName, NameSize);
+
+ // Verify we get correct name.
+ EXPECT_EQ(Name, ExpectedName);
+
+ // Verify we get the different pointer and same length the second time.
+ char *CName1 = LLVMIntrinsicCopyName(ID, &NameSize);
+ EXPECT_NE(CName, CName1);
+ EXPECT_EQ(NameSize, Name.size());
+
+ free(CName);
+ free(CName1);
+ }
+}
+
TEST_F(IntrinsicsTest, InstrProfInheritance) {
auto isInstrProfInstBase = [](const Instruction &I) {
return isa<InstrProfInstBase>(I);
More information about the llvm-commits
mailing list