[llvm] [C API] Add blockaddress getters to C API (PR #81382)

via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 10 13:45:46 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Benji Smith (Benjins)

<details>
<summary>Changes</summary>

This allows for accessing the function/basic block that a blockaddress constant refers to

Due to the difficulties of fully supporting cloning BlockAddress values in echo.cpp, tests are instead done using a unit test as part of llvm-c-test, with a new test file, block_address.ll

This previously was up for review at https://github.com/llvm/llvm-project/pull/77390 . The API changes are the same, but the way of testing it has been changed. Since a full-on cloning of BlockAddress values was considered too difficult, the test instead just verifies that we can access the data as expected using a new function in llvm-c-test

---
Full diff: https://github.com/llvm/llvm-project/pull/81382.diff


7 Files Affected:

- (modified) llvm/docs/ReleaseNotes.rst (+3) 
- (modified) llvm/include/llvm-c/Core.h (+10) 
- (modified) llvm/lib/IR/Core.cpp (+8) 
- (added) llvm/test/Bindings/llvm-c/block_address.ll (+39) 
- (modified) llvm/tools/llvm-c-test/llvm-c-test.h (+1) 
- (modified) llvm/tools/llvm-c-test/main.c (+3) 
- (modified) llvm/tools/llvm-c-test/module.c (+28) 


``````````diff
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 05d8eea3add419..120e8b637136a6 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -122,6 +122,9 @@ Changes to the Python bindings
 Changes to the C API
 --------------------
 
+* Added ``LLVMGetBlockAddressFunction`` and ``LLVMGetBlockAddressBasicBlock``
+  functions for accessing the values in a blockaddress constant.
+
 Changes to the CodeGen infrastructure
 -------------------------------------
 
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 83530ae7b51324..09746bdaf0c94e 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2328,6 +2328,16 @@ LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
                                     LLVMValueRef MaskConstant);
 LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB);
 
+/**
+ * Gets the function associated with a given BlockAddress constant value.
+ */
+LLVMValueRef LLVMGetBlockAddressFunction(LLVMValueRef BlockAddr);
+
+/**
+ * Gets the basic block associated with a given BlockAddress constant value.
+ */
+LLVMBasicBlockRef LLVMGetBlockAddressBasicBlock(LLVMValueRef BlockAddr);
+
 /** Deprecated: Use LLVMGetInlineAsm instead. */
 LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty,
                                 const char *AsmString, const char *Constraints,
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index fb30fbce0ba22e..d6d159ab8b9e83 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -1805,6 +1805,14 @@ LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB) {
   return wrap(BlockAddress::get(unwrap<Function>(F), unwrap(BB)));
 }
 
+LLVMValueRef LLVMGetBlockAddressFunction(LLVMValueRef BlockAddr) {
+  return wrap(unwrap<BlockAddress>(BlockAddr)->getFunction());
+}
+
+LLVMBasicBlockRef LLVMGetBlockAddressBasicBlock(LLVMValueRef BlockAddr) {
+  return wrap(unwrap<BlockAddress>(BlockAddr)->getBasicBlock());
+}
+
 /*--.. Operations on global variables, functions, and aliases (globals) ....--*/
 
 LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global) {
diff --git a/llvm/test/Bindings/llvm-c/block_address.ll b/llvm/test/Bindings/llvm-c/block_address.ll
new file mode 100644
index 00000000000000..f1284b8839b17a
--- /dev/null
+++ b/llvm/test/Bindings/llvm-c/block_address.ll
@@ -0,0 +1,39 @@
+; RUN: llvm-as < %s | llvm-c-test --module-list-global-block-address-values | FileCheck %s
+
+
+define void @test_block_address_01() {
+entry:
+  br label %block_0
+block_0:
+  ret void
+}
+
+define void @test_block_address_02() {
+entry:
+  br label %block_0
+block_0:
+  ret void
+}
+
+define void @test_block_address_03() {
+entry:
+  br label %block_0
+block_0:
+  br label %block_1
+block_1:
+  ret void
+}
+
+
+ at g_block_address_01 = global ptr blockaddress(@test_block_address_01, %block_0)
+;CHECK: BlockAddress 'g_block_address_01' Func 'test_block_address_01' Basic Block 'block_0'
+
+ at g_block_address_02 = global ptr blockaddress(@test_block_address_02, %block_0)
+;CHECK: BlockAddress 'g_block_address_02' Func 'test_block_address_02' Basic Block 'block_0'
+
+ at g_block_address_03 = global ptr blockaddress(@test_block_address_03, %block_0)
+;CHECK: BlockAddress 'g_block_address_03' Func 'test_block_address_03' Basic Block 'block_0'
+
+ at g_block_address_04 = global ptr blockaddress(@test_block_address_03, %block_1)
+;CHECK: BlockAddress 'g_block_address_04' Func 'test_block_address_03' Basic Block 'block_1'
+
diff --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h
index 00566660257e07..ad9a63806065e5 100644
--- a/llvm/tools/llvm-c-test/llvm-c-test.h
+++ b/llvm/tools/llvm-c-test/llvm-c-test.h
@@ -28,6 +28,7 @@ LLVMModuleRef llvm_load_module(bool Lazy, bool New);
 int llvm_module_dump(bool Lazy, bool New);
 int llvm_module_list_functions(void);
 int llvm_module_list_globals(void);
+int llvm_module_list_global_block_address_values(void);
 
 // calc.c
 int llvm_calc(void);
diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c
index badbe4b13b6ba5..ecef9b34a4c364 100644
--- a/llvm/tools/llvm-c-test/main.c
+++ b/llvm/tools/llvm-c-test/main.c
@@ -111,6 +111,9 @@ int main(int argc, char **argv) {
     return llvm_test_diagnostic_handler();
   } else if (argc == 2 && !strcmp(argv[1], "--test-dibuilder")) {
     return llvm_test_dibuilder();
+  } else if (argc == 2 &&
+             !strcmp(argv[1], "--module-list-global-block-address-values")) {
+    return llvm_module_list_global_block_address_values();
   } else {
     print_usage();
   }
diff --git a/llvm/tools/llvm-c-test/module.c b/llvm/tools/llvm-c-test/module.c
index 9fc86cfe5404b3..989f96b6cf1dee 100644
--- a/llvm/tools/llvm-c-test/module.c
+++ b/llvm/tools/llvm-c-test/module.c
@@ -136,3 +136,31 @@ int llvm_module_list_globals(void) {
 
   return 0;
 }
+
+int llvm_module_list_global_block_address_values(void) {
+  LLVMModuleRef M = llvm_load_module(false, false);
+  LLVMValueRef g;
+
+  g = LLVMGetFirstGlobal(M);
+  while (g) {
+    LLVMValueRef GInit = LLVMGetInitializer(g);
+
+    if (GInit && LLVMIsABlockAddress(GInit)) {
+      const char *GlobalName = LLVMGetValueName(g);
+      LLVMValueRef Func = LLVMGetBlockAddressFunction(GInit);
+      LLVMBasicBlockRef BB = LLVMGetBlockAddressBasicBlock(GInit);
+
+      const char *FuncName = LLVMGetValueName(Func);
+      const char *BBName = LLVMGetBasicBlockName(BB);
+
+      printf("BlockAddress '%s' Func '%s' Basic Block '%s'\n", GlobalName,
+             FuncName, BBName);
+    }
+
+    g = LLVMGetNextGlobal(g);
+  }
+
+  LLVMDisposeModule(M);
+
+  return 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/81382


More information about the llvm-commits mailing list