[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