[llvm] [C API] Add blockaddress getters to C API (PR #81382)
Benji Smith via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 11 04:53:27 PST 2024
https://github.com/Benjins updated https://github.com/llvm/llvm-project/pull/81382
>From b11bbd790beb281e799f3a1048be9275756c4e69 Mon Sep 17 00:00:00 2001
From: Benji Smith <benjsith at gmail.com>
Date: Sun, 7 Jan 2024 20:43:25 -0500
Subject: [PATCH 1/2] Add LLVMGetBlockAddressFunction and
LLVMGetBlockAddressBasicBlock getters
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
---
llvm/docs/ReleaseNotes.rst | 3 ++
llvm/include/llvm-c/Core.h | 10 ++++++
llvm/lib/IR/Core.cpp | 8 +++++
llvm/test/Bindings/llvm-c/block_address.ll | 39 ++++++++++++++++++++++
llvm/tools/llvm-c-test/llvm-c-test.h | 1 +
llvm/tools/llvm-c-test/main.c | 3 ++
llvm/tools/llvm-c-test/module.c | 28 ++++++++++++++++
7 files changed, 92 insertions(+)
create mode 100644 llvm/test/Bindings/llvm-c/block_address.ll
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;
+}
>From 4a5c13d353fed6ede2c956755a838d9cbffe20b1 Mon Sep 17 00:00:00 2001
From: Benji Smith <6193112+Benjins at users.noreply.github.com>
Date: Sun, 11 Feb 2024 07:46:56 -0500
Subject: [PATCH 2/2] Change blockaddress C API test from llvm-c-test to a unit
test
---
llvm/test/Bindings/llvm-c/block_address.ll | 39 ----------------------
llvm/tools/llvm-c-test/llvm-c-test.h | 1 -
llvm/tools/llvm-c-test/main.c | 3 --
llvm/tools/llvm-c-test/module.c | 28 ----------------
llvm/unittests/IR/ConstantsTest.cpp | 39 ++++++++++++++++++++++
5 files changed, 39 insertions(+), 71 deletions(-)
delete mode 100644 llvm/test/Bindings/llvm-c/block_address.ll
diff --git a/llvm/test/Bindings/llvm-c/block_address.ll b/llvm/test/Bindings/llvm-c/block_address.ll
deleted file mode 100644
index f1284b8839b17a..00000000000000
--- a/llvm/test/Bindings/llvm-c/block_address.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; 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 ad9a63806065e5..00566660257e07 100644
--- a/llvm/tools/llvm-c-test/llvm-c-test.h
+++ b/llvm/tools/llvm-c-test/llvm-c-test.h
@@ -28,7 +28,6 @@ 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 ecef9b34a4c364..badbe4b13b6ba5 100644
--- a/llvm/tools/llvm-c-test/main.c
+++ b/llvm/tools/llvm-c-test/main.c
@@ -111,9 +111,6 @@ 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 989f96b6cf1dee..9fc86cfe5404b3 100644
--- a/llvm/tools/llvm-c-test/module.c
+++ b/llvm/tools/llvm-c-test/module.c
@@ -136,31 +136,3 @@ 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;
-}
diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp
index 314264b77a7101..1d6a92c498b061 100644
--- a/llvm/unittests/IR/ConstantsTest.cpp
+++ b/llvm/unittests/IR/ConstantsTest.cpp
@@ -736,5 +736,44 @@ TEST(ConstantsTest, ComdatUserTracking) {
EXPECT_TRUE(Users.size() == 0);
}
+// Verify that the C API getters for BlockAddress work
+TEST(ConstantsTest, BlockAddressCAPITest) {
+ const char *BlockAddressIR = R"(
+ define void @test_block_address_func() {
+ entry:
+ br label %block_bb_0
+ block_bb_0:
+ ret void
+ }
+ )";
+
+ LLVMContext Context;
+ SMDiagnostic Error;
+ std::unique_ptr<Module> M =
+ parseAssemblyString(BlockAddressIR, Error, Context);
+
+ EXPECT_TRUE(M.get() != nullptr);
+
+ // Get the function
+ auto *Func = M->getFunction("test_block_address_func");
+ EXPECT_TRUE(Func != nullptr);
+
+ // Get the second basic block, since we can't use the entry one
+ const BasicBlock &BB = *(++Func->begin());
+ EXPECT_EQ(BB.getName(), "block_bb_0");
+
+ // Construct the C API values
+ LLVMValueRef BlockAddr = LLVMBlockAddress(wrap(Func), wrap(&BB));
+ EXPECT_TRUE(LLVMIsABlockAddress(BlockAddr));
+
+ // Get the Function/BasicBlock values back out
+ auto *OutFunc = unwrap(LLVMGetBlockAddressFunction(BlockAddr));
+ auto *OutBB = unwrap(LLVMGetBlockAddressBasicBlock(BlockAddr));
+
+ // Verify that they round-tripped properly
+ EXPECT_EQ(Func, OutFunc);
+ EXPECT_EQ(&BB, OutBB);
+}
+
} // end anonymous namespace
} // end namespace llvm
More information about the llvm-commits
mailing list