Skip to content

Commit b48aa0c

Browse files
committed
[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.
1 parent 519eef3 commit b48aa0c

File tree

4 files changed

+74
-16
lines changed

4 files changed

+74
-16
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ Changes to the C API
258258

259259
* Added `LLVMAtomicRMWBinOpUSubCond` and `LLVMAtomicRMWBinOpUSubSat` to `LLVMAtomicRMWBinOp` enum for AtomicRMW instructions.
260260

261+
* Added `LLVMIntrinsicCopyName` and changed `LLVMIntrinsicCopyOverloadedName`
262+
and `LLVMIntrinsicCopyOverloadedName2` to return `char *` instead of
263+
`const char *`.
264+
261265
Changes to the CodeGen infrastructure
262266
-------------------------------------
263267

llvm/include/llvm-c/Core.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2833,11 +2833,17 @@ LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
28332833
*/
28342834
const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
28352835

2836+
/**
2837+
* Copies the name of an intrinsic. The caller is responsible for freeing the
2838+
* returned string.
2839+
*
2840+
* @see llvm::Intrinsic::getName()
2841+
*/
2842+
char *LLVMIntrinsicCopyName(unsigned ID, size_t *NameLength);
2843+
28362844
/** Deprecated: Use LLVMIntrinsicCopyOverloadedName2 instead. */
2837-
const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
2838-
LLVMTypeRef *ParamTypes,
2839-
size_t ParamCount,
2840-
size_t *NameLength);
2845+
char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes,
2846+
size_t ParamCount, size_t *NameLength);
28412847

28422848
/**
28432849
* Copies the name of an overloaded intrinsic identified by a given list of
@@ -2850,10 +2856,9 @@ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
28502856
*
28512857
* @see llvm::Intrinsic::getName()
28522858
*/
2853-
const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
2854-
LLVMTypeRef *ParamTypes,
2855-
size_t ParamCount,
2856-
size_t *NameLength);
2859+
char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
2860+
LLVMTypeRef *ParamTypes,
2861+
size_t ParamCount, size_t *NameLength);
28572862

28582863
/**
28592864
* Obtain if the intrinsic identified by the given ID is overloaded.

llvm/lib/IR/Core.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,28 +2478,32 @@ const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) {
24782478
return Str.data();
24792479
}
24802480

2481+
char *LLVMIntrinsicCopyName(unsigned ID, size_t *NameLength) {
2482+
auto IID = llvm_map_to_intrinsic_id(ID);
2483+
auto Str = llvm::Intrinsic::getName(IID);
2484+
*NameLength = Str.size();
2485+
return strdup(Str.data());
2486+
}
2487+
24812488
LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
24822489
LLVMTypeRef *ParamTypes, size_t ParamCount) {
24832490
auto IID = llvm_map_to_intrinsic_id(ID);
24842491
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
24852492
return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, Tys));
24862493
}
24872494

2488-
const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
2489-
LLVMTypeRef *ParamTypes,
2490-
size_t ParamCount,
2491-
size_t *NameLength) {
2495+
char *LLVMIntrinsicCopyOverloadedName(unsigned ID, LLVMTypeRef *ParamTypes,
2496+
size_t ParamCount, size_t *NameLength) {
24922497
auto IID = llvm_map_to_intrinsic_id(ID);
24932498
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
24942499
auto Str = llvm::Intrinsic::getNameNoUnnamedTypes(IID, Tys);
24952500
*NameLength = Str.length();
24962501
return strdup(Str.c_str());
24972502
}
24982503

2499-
const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
2500-
LLVMTypeRef *ParamTypes,
2501-
size_t ParamCount,
2502-
size_t *NameLength) {
2504+
char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
2505+
LLVMTypeRef *ParamTypes,
2506+
size_t ParamCount, size_t *NameLength) {
25032507
auto IID = llvm_map_to_intrinsic_id(ID);
25042508
ArrayRef<Type *> Tys(unwrap(ParamTypes), ParamCount);
25052509
auto Str = llvm::Intrinsic::getName(IID, Tys, unwrap(Mod));

llvm/unittests/IR/IntrinsicsTest.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/IR/Intrinsics.h"
10+
#include "llvm-c/Core.h"
1011
#include "llvm/ADT/SmallVector.h"
1112
#include "llvm/IR/Constant.h"
1213
#include "llvm/IR/IRBuilder.h"
@@ -127,6 +128,50 @@ TEST(IntrinsicNameLookup, MSBuiltinLookup) {
127128
EXPECT_EQ(ID, getIntrinsicForMSBuiltin(Target, Builtin));
128129
}
129130

131+
// Test C API to get/copy LLVM intrinsic name.
132+
TEST(IntrinsicNameLookup, LLVMIntrinsicGetCopyNameSimple) {
133+
static constexpr struct {
134+
Intrinsic::ID ID;
135+
const char *Name;
136+
} Tests[] = {{Intrinsic::not_intrinsic, "not_intrinsic"},
137+
{Intrinsic::assume, "llvm.assume"},
138+
{Intrinsic::coro_free, "llvm.coro.free"},
139+
{Intrinsic::aarch64_break, "llvm.aarch64.break"},
140+
{Intrinsic::x86_int, "llvm.x86.int"}};
141+
142+
for (auto [ID, ExpectedName] : Tests) {
143+
size_t NameSize = 0;
144+
const char *CName = LLVMIntrinsicGetName(ID, &NameSize);
145+
StringRef Name(CName, NameSize);
146+
147+
// Verify we get correct name.
148+
EXPECT_EQ(Name, ExpectedName);
149+
const char *CName1 = LLVMIntrinsicGetName(ID, &NameSize);
150+
151+
// Verify we get the same pointer and length the second time.
152+
EXPECT_EQ(CName, CName1);
153+
EXPECT_EQ(NameSize, Name.size());
154+
}
155+
156+
// Now test the copy API.
157+
for (auto [ID, ExpectedName] : Tests) {
158+
size_t NameSize = 0;
159+
char *CName = LLVMIntrinsicCopyName(ID, &NameSize);
160+
StringRef Name(CName, NameSize);
161+
162+
// Verify we get correct name.
163+
EXPECT_EQ(Name, ExpectedName);
164+
165+
// Verify we get the different pointer and same length the second time.
166+
char *CName1 = LLVMIntrinsicCopyName(ID, &NameSize);
167+
EXPECT_NE(CName, CName1);
168+
EXPECT_EQ(NameSize, Name.size());
169+
170+
free(CName);
171+
free(CName1);
172+
}
173+
}
174+
130175
TEST_F(IntrinsicsTest, InstrProfInheritance) {
131176
auto isInstrProfInstBase = [](const Instruction &I) {
132177
return isa<InstrProfInstBase>(I);

0 commit comments

Comments
 (0)