[llvm] [LLVM] Add C API support for handling global object metadata. (PR #104786)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 19 07:21:04 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Tim Besard (maleadt)
<details>
<summary>Changes</summary>
Upstreaming vendored C API fixes from Julia/LLVM.jl.
---
Full diff: https://github.com/llvm/llvm-project/pull/104786.diff
3 Files Affected:
- (modified) llvm/docs/ReleaseNotes.rst (+3)
- (modified) llvm/lib/IR/Core.cpp (+28-10)
- (modified) llvm/tools/llvm-c-test/metadata.c (+12-2)
``````````diff
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;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/104786
More information about the llvm-commits
mailing list