[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