-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[C API] Add blockaddress getters to C API #81382
Conversation
@llvm/pr-subscribers-llvm-ir Author: Benji Smith (Benjins) ChangesThis 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 #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:
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
+}
+
+
+@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'
+
+@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'
+
+@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'
+
+@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;
+}
|
|
…ters This allows for accessing the function/basic block that a blockaddress constant refers to Due to the difficulties of 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
fc18f86
to
b11bbd7
Compare
llvm/tools/llvm-c-test/module.c
Outdated
LLVMDisposeModule(M); | ||
|
||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have to go through llvm-c-test with IR input, you can also directly add a unit test in https://github.com/llvm/llvm-project/blob/main/llvm/unittests/IR/ConstantsTest.cpp. Basically just call LLVMBlockAddress and then the getter on that and check that the inputs & outputs are the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, I didn't realise there was a specific unit test framework. I've changed the test to that in a new commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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 #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