[llvm] [LLVM] Add C API support for handling global object metadata. (PR #104786)
Tim Besard via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 19 07:20:33 PDT 2024
https://github.com/maleadt created https://github.com/llvm/llvm-project/pull/104786
Upstreaming vendored C API fixes from Julia/LLVM.jl.
>From 5ee20a2cb5e0d62bf084a1df2213dbe54a939f23 Mon Sep 17 00:00:00 2001
From: Tim Besard <tim.besard at gmail.com>
Date: Mon, 19 Aug 2024 16:16:49 +0200
Subject: [PATCH] [LLVM] Add C API support for handling global object metadata.
---
llvm/docs/ReleaseNotes.rst | 3 +++
llvm/lib/IR/Core.cpp | 38 +++++++++++++++++++++++--------
llvm/tools/llvm-c-test/metadata.c | 14 ++++++++++--
3 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index d40bb2682f9ad8..5ebcaa43865633 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -163,6 +163,9 @@ Changes to the C API
* It is now also possible to run the new pass manager on a single function, by calling
``LLVMRunPassesOnFunction`` instead of ``LLVMRunPasses``.
+* Metadata APIs (``LLVMHasMetadata``, ``LLVMGetMetadata``, ``LLVMSetMetadata``) now
+ support global object inputs.
+
Changes to the CodeGen infrastructure
-------------------------------------
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index dcad76ee8491dd..85ca87f273e3bc 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1062,15 +1062,27 @@ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) {
unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal));
}
-int LLVMHasMetadata(LLVMValueRef Inst) {
- return unwrap<Instruction>(Inst)->hasMetadata();
+int LLVMHasMetadata(LLVMValueRef Ref) {
+ Value *Val = unwrap<Value>(Ref);
+ if (auto I = dyn_cast<Instruction>(Val))
+ return I->hasMetadata();
+ else if (auto GO = dyn_cast<GlobalObject>(Val))
+ return GO->hasMetadata();
+ else
+ assert(0 && "Expected an instruction or a global object");
}
-LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) {
- auto *I = unwrap<Instruction>(Inst);
- assert(I && "Expected instruction");
- if (auto *MD = I->getMetadata(KindID))
- return wrap(MetadataAsValue::get(I->getContext(), MD));
+LLVMValueRef LLVMGetMetadata(LLVMValueRef Ref, unsigned KindID) {
+ Value *Val = unwrap<Value>(Ref);
+ if (auto *I = dyn_cast<Instruction>(Val)) {
+ if (auto *MD = I->getMetadata(KindID))
+ return wrap(MetadataAsValue::get(I->getContext(), MD));
+ } else if (auto *GO = dyn_cast<GlobalObject>(Val)) {
+ if (auto *MD = GO->getMetadata(KindID))
+ return wrap(MetadataAsValue::get(GO->getContext(), MD));
+ } else {
+ assert(0 && "Expected an instruction or a global object");
+ }
return nullptr;
}
@@ -1088,10 +1100,16 @@ static MDNode *extractMDNode(MetadataAsValue *MAV) {
return MDNode::get(MAV->getContext(), MD);
}
-void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) {
- MDNode *N = Val ? extractMDNode(unwrap<MetadataAsValue>(Val)) : nullptr;
+void LLVMSetMetadata(LLVMValueRef Ref, unsigned KindID, LLVMValueRef MAV) {
+ Value *Val = unwrap<Value>(Ref);
+ MDNode *N = MAV ? extractMDNode(unwrap<MetadataAsValue>(MAV)) : nullptr;
- unwrap<Instruction>(Inst)->setMetadata(KindID, N);
+ if (auto *I = dyn_cast<Instruction>(Val))
+ I->setMetadata(KindID, N);
+ else if (auto *GO = dyn_cast<GlobalObject>(Val))
+ GO->setMetadata(KindID, N);
+ else
+ assert(0 && "Expected an instruction or a global object");
}
struct LLVMOpaqueValueMetadataEntry {
diff --git a/llvm/tools/llvm-c-test/metadata.c b/llvm/tools/llvm-c-test/metadata.c
index 4fe8c00c57481b..05aaf397a8fb7e 100644
--- a/llvm/tools/llvm-c-test/metadata.c
+++ b/llvm/tools/llvm-c-test/metadata.c
@@ -33,16 +33,26 @@ int llvm_add_named_metadata_operand(void) {
int llvm_set_metadata(void) {
LLVMBuilderRef Builder = LLVMCreateBuilder();
- // This used to trigger an assertion
+ LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
+ LLVMTypeRef FT = LLVMFunctionType(LLVMVoidType(), NULL, 0, 0);
+ LLVMValueRef F = LLVMAddFunction(M, "Fun", FT);
+ LLVMBasicBlockRef BB = LLVMAppendBasicBlock(F, "Entry");
+ LLVMPositionBuilderAtEnd(Builder, BB);
LLVMValueRef Return = LLVMBuildRetVoid(Builder);
+ // This used to trigger an assertion because of MDNode canonicalization
const char Name[] = "kind";
LLVMValueRef Int = LLVMConstInt(LLVMInt32Type(), 0, 0);
LLVMSetMetadata(Return, LLVMGetMDKindID(Name, strlen(Name)),
LLVMMDNode(&Int, 1));
+ // Test support of global objects (e.g., Function)
+ assert(!LLVMHasMetadata(F));
+ LLVMSetMetadata(F, LLVMGetMDKindID(Name, strlen(Name)), LLVMMDNode(&Int, 1));
+ assert(LLVMHasMetadata(F));
+
LLVMDisposeBuilder(Builder);
- LLVMDeleteInstruction(Return);
+ LLVMDisposeModule(M);
return 0;
}
More information about the llvm-commits
mailing list