[llvm] c7d95ba - [llvm-c] add LLVMReplaceMDNodeOperandWith
Adrian Prantl via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 31 09:58:09 PST 2023
Author: Davide Bertola
Date: 2023-01-31T09:58:03-08:00
New Revision: c7d95ba051012e2d0d51bc365577777b48dd2093
URL: https://github.com/llvm/llvm-project/commit/c7d95ba051012e2d0d51bc365577777b48dd2093
DIFF: https://github.com/llvm/llvm-project/commit/c7d95ba051012e2d0d51bc365577777b48dd2093.diff
LOG: [llvm-c] add LLVMReplaceMDNodeOperandWith
I'm working on a tool that visits debug info and massages it using the
llvm-c API. I noticed that LLVMGetOperand special cases MDNodes so I
can get their operands, but I can't replace them. This patch adds
LLVMReplaceMDNodeOperandWith which boils down to
MDNode::replaceOperandWith.
The name was chosen for consistency with LLVMGetMDNodeOperands and
LLVMGetMDNodeNumOperands.
Differential Revision: https://reviews.llvm.org/D136637
Added:
llvm/test/Bindings/llvm-c/is_a_value_as_metadata.ll
llvm/test/Bindings/llvm-c/replace_md_operand.ll
Modified:
llvm/include/llvm-c/Core.h
llvm/lib/IR/Core.cpp
llvm/tools/llvm-c-test/llvm-c-test.h
llvm/tools/llvm-c-test/main.c
llvm/tools/llvm-c-test/metadata.c
Removed:
################################################################################
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 21cc1f819a36f..94a25fff98e51 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -1785,6 +1785,7 @@ LLVMBool LLVMIsPoison(LLVMValueRef Val);
LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST)
LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val);
+LLVMValueRef LLVMIsAValueAsMetadata(LLVMValueRef Val);
LLVMValueRef LLVMIsAMDString(LLVMValueRef Val);
/** Deprecated: Use LLVMGetValueName2 instead. */
@@ -2914,6 +2915,14 @@ unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V);
*/
void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest);
+/**
+ * Replace an operand at a specific index in a llvm::MDNode value.
+ *
+ * @see llvm::MDNode::replaceOperandWith()
+ */
+void LLVMReplaceMDNodeOperandWith(LLVMValueRef V, unsigned Index,
+ LLVMMetadataRef Replacement);
+
/** Deprecated: Use LLVMMDStringInContext2 instead. */
LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
unsigned SLen);
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index b12c483cb9490..a93fc85bb784b 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1009,6 +1009,13 @@ LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val) {
return nullptr;
}
+LLVMValueRef LLVMIsAValueAsMetadata(LLVMValueRef Val) {
+ if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val)))
+ if (isa<ValueAsMetadata>(MD->getMetadata()))
+ return Val;
+ return nullptr;
+}
+
LLVMValueRef LLVMIsAMDString(LLVMValueRef Val) {
if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val)))
if (isa<MDString>(MD->getMetadata()))
@@ -1268,6 +1275,13 @@ void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) {
Dest[i] = getMDNodeOperandImpl(Context, N, i);
}
+void LLVMReplaceMDNodeOperandWith(LLVMValueRef V, unsigned Index,
+ LLVMMetadataRef Replacement) {
+ auto *MD = cast<MetadataAsValue>(unwrap(V));
+ auto *N = cast<MDNode>(MD->getMetadata());
+ N->replaceOperandWith(Index, unwrap<Metadata>(Replacement));
+}
+
unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char *Name) {
if (NamedMDNode *N = unwrap(M)->getNamedMetadata(Name)) {
return N->getNumOperands();
diff --git a/llvm/test/Bindings/llvm-c/is_a_value_as_metadata.ll b/llvm/test/Bindings/llvm-c/is_a_value_as_metadata.ll
new file mode 100644
index 0000000000000..f3165e2c2d30f
--- /dev/null
+++ b/llvm/test/Bindings/llvm-c/is_a_value_as_metadata.ll
@@ -0,0 +1,2 @@
+; RUN: llvm-c-test --is-a-value-as-metadata < /dev/null
+; This used to trigger an assertion
diff --git a/llvm/test/Bindings/llvm-c/replace_md_operand.ll b/llvm/test/Bindings/llvm-c/replace_md_operand.ll
new file mode 100644
index 0000000000000..758b05553e7b4
--- /dev/null
+++ b/llvm/test/Bindings/llvm-c/replace_md_operand.ll
@@ -0,0 +1,2 @@
+; RUN: llvm-c-test --replace-md-operand < /dev/null
+; This used to trigger an assertion
diff --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h
index b828a827c55a2..5e5b3551e1cc8 100644
--- a/llvm/tools/llvm-c-test/llvm-c-test.h
+++ b/llvm/tools/llvm-c-test/llvm-c-test.h
@@ -41,6 +41,8 @@ int llvm_test_dibuilder(void);
// metadata.c
int llvm_add_named_metadata_operand(void);
int llvm_set_metadata(void);
+int llvm_replace_md_operand(void);
+int llvm_is_a_value_as_metadata(void);
// object.c
int llvm_object_list_sections(void);
diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c
index 89a43dbe08cdf..79a56f70e00d4 100644
--- a/llvm/tools/llvm-c-test/main.c
+++ b/llvm/tools/llvm-c-test/main.c
@@ -44,6 +44,11 @@ static void print_usage(void) {
fprintf(stderr, " Read lines of triple, hex ascii machine code from stdin "
"- print disassembly\n\n");
fprintf(stderr, " * --calc\n");
+ fprintf(stderr, " * --replace-md-operand\n");
+ fprintf(stderr, " Run test for replacing MDNode operands\n");
+ fprintf(stderr, " * --is-a-value-as-metadata\n");
+ fprintf(stderr,
+ " Run test for checking if LLVMValueRef is a ValueAsMetadata\n");
fprintf(
stderr,
" Read lines of name, rpn from stdin - print generated module\n\n");
@@ -91,6 +96,10 @@ int main(int argc, char **argv) {
return llvm_add_named_metadata_operand();
} else if (argc == 2 && !strcmp(argv[1], "--set-metadata")) {
return llvm_set_metadata();
+ } else if (argc == 2 && !strcmp(argv[1], "--replace-md-operand")) {
+ return llvm_replace_md_operand();
+ } else if (argc == 2 && !strcmp(argv[1], "--is-a-value-as-metadata")) {
+ return llvm_is_a_value_as_metadata();
} else if (argc == 2 && !strcmp(argv[1], "--test-function-attributes")) {
return llvm_test_function_attributes();
} else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) {
diff --git a/llvm/tools/llvm-c-test/metadata.c b/llvm/tools/llvm-c-test/metadata.c
index b1d76083cd727..e8861c3a325da 100644
--- a/llvm/tools/llvm-c-test/metadata.c
+++ b/llvm/tools/llvm-c-test/metadata.c
@@ -14,6 +14,9 @@
#include "llvm-c-test.h"
+#include <assert.h>
+#include <string.h>
+
int llvm_add_named_metadata_operand(void) {
LLVMModuleRef m = LLVMModuleCreateWithName("Mod");
LLVMValueRef values[] = { LLVMConstInt(LLVMInt32Type(), 0, 0) };
@@ -39,3 +42,38 @@ int llvm_set_metadata(void) {
return 0;
}
+
+int llvm_replace_md_operand(void) {
+ LLVMModuleRef m = LLVMModuleCreateWithName("Mod");
+ LLVMContextRef context = LLVMGetModuleContext(m);
+ unsigned int tmp = 0;
+
+ LLVMMetadataRef metas[] = {LLVMMDStringInContext2(context, "foo", 3)};
+ LLVMValueRef md =
+ LLVMMetadataAsValue(context, LLVMMDNodeInContext2(context, metas, 1));
+
+ LLVMReplaceMDNodeOperandWith(md, 0,
+ LLVMMDStringInContext2(context, "bar", 3));
+
+ assert(!strncmp(LLVMGetMDString(LLVMGetOperand(md, 0), &tmp), "bar", 0));
+
+ LLVMDisposeModule(m);
+
+ return 0;
+}
+
+int llvm_is_a_value_as_metadata(void) {
+ LLVMModuleRef m = LLVMModuleCreateWithName("Mod");
+ LLVMContextRef context = LLVMGetModuleContext(m);
+
+ LLVMValueRef values[] = {LLVMConstInt(LLVMInt32Type(), 0, 0)};
+ LLVMValueRef md = LLVMMDNode(values, 1);
+ assert(LLVMIsAValueAsMetadata(md) == md);
+
+ LLVMMetadataRef metas[] = {LLVMMDStringInContext2(context, "foo", 3)};
+ LLVMValueRef md2 =
+ LLVMMetadataAsValue(context, LLVMMDNodeInContext2(context, metas, 1));
+ assert(LLVMIsAValueAsMetadata(md2) == NULL);
+
+ return 0;
+}
More information about the llvm-commits
mailing list