From 2a0f69b76b5486b338d3f042a7a2a7c04cb646ff Mon Sep 17 00:00:00 2001 From: Yashwant Singh Date: Mon, 4 Mar 2024 13:43:59 +0530 Subject: [PATCH 01/11] get rid of -flto --- ffi/Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffi/Makefile.linux b/ffi/Makefile.linux index bc80d6112..eb5fe0cd6 100644 --- a/ffi/Makefile.linux +++ b/ffi/Makefile.linux @@ -2,7 +2,7 @@ CXX ?= g++ # -flto and --exclude-libs allow us to remove those parts of LLVM we don't use -CXX_FLTO_FLAGS ?= -flto +#CXX_FLTO_FLAGS ?= -flto LD_FLTO_FLAGS ?= -flto -Wl,--exclude-libs=ALL # -fPIC is required when compiling objects for a shared library CXX_FPIC_FLAGS ?= -fPIC From d6957e1eff09c930dcfd11d852ad88ca3a4b0dbf Mon Sep 17 00:00:00 2001 From: Yashwant Singh Date: Wed, 6 Mar 2024 11:00:15 +0530 Subject: [PATCH 02/11] [llvm15] Support llvmlite to building against llvm15 1) Drop 2 passes no longer supported by old PM 2) Update domTree passes to their wrapper passes 3) Update getAddress() api 4) Disable opaque pointer mode 5) Give warning when build with llvm15 All the changes are put inside llvm version check guard so that it builds with both llvm14 and llvm15 --- ffi/assembly.cpp | 1 - ffi/build.py | 21 ++++++++++++++------- ffi/core.cpp | 17 +++++++++++++++-- ffi/core.h | 5 +++++ ffi/orcjit.cpp | 11 ++++++++++- ffi/passmanagers.cpp | 14 ++++++++++++++ ffi/value.cpp | 3 +++ llvmlite/binding/passmanagers.py | 22 +++++++++++++++++----- llvmlite/tests/test_binding.py | 17 +++++++++++------ 9 files changed, 89 insertions(+), 22 deletions(-) diff --git a/ffi/assembly.cpp b/ffi/assembly.cpp index b193d692c..ddaaa1286 100644 --- a/ffi/assembly.cpp +++ b/ffi/assembly.cpp @@ -16,7 +16,6 @@ API_EXPORT(LLVMModuleRef) LLVMPY_ParseAssembly(LLVMContextRef context, const char *ir, const char **outmsg) { using namespace llvm; - SMDiagnostic error; Module *m = parseAssemblyString(ir, error, *unwrap(context)).release(); diff --git a/ffi/build.py b/ffi/build.py index f4f8c69fa..97bdda426 100755 --- a/ffi/build.py +++ b/ffi/build.py @@ -53,6 +53,13 @@ def run_llvm_config(llvm_config, args): return out +def show_warning(message): + header = ' * '.join(("WARNING",) * 8) + blk = '=' * 80 + warning = f'{blk}\n{header}\n{blk}' + print(f"{warning}\n{message}\n{warning}") + + def find_windows_generator(): """ Find a suitable cmake "generator" under Windows. @@ -156,16 +163,16 @@ def main_posix(kind, library_ext): "overridden.\nThis is unsupported behaviour, llvmlite may not " "work as intended.\nRequested LLVM version: {}".format( out.strip())) - warn = ' * '.join(("WARNING",) * 8) - blk = '=' * 80 - warning = '{}\n{}\n{}'.format(blk, warn, blk) - print(warning) - print(msg) - print(warning + '\n') + show_warning(msg) else: (version, _) = out.split('.', 1) version = int(version) - if version != 14: + if version == 15: + msg = ("Building with LLVM 15; note that LLVM 15 support is " + "presently experimental") + show_warning(msg) + elif version != 14: + msg = ("Building llvmlite requires LLVM 14, got " "{!r}. Be sure to set LLVM_CONFIG to the right executable " "path.\nRead the documentation at " diff --git a/ffi/core.cpp b/ffi/core.cpp index 4afc7f7fd..a9436ff67 100644 --- a/ffi/core.cpp +++ b/ffi/core.cpp @@ -21,10 +21,23 @@ API_EXPORT(void) LLVMPY_DisposeString(const char *msg) { free(const_cast(msg)); } API_EXPORT(LLVMContextRef) -LLVMPY_GetGlobalContext() { return LLVMGetGlobalContext(); } +LLVMPY_GetGlobalContext() { + auto context = LLVMGetGlobalContext(); +#if LLVM_VERSION_MAJOR > 14 + LLVMContextSetOpaquePointers(context, false); +#endif + return context; +} + API_EXPORT(LLVMContextRef) -LLVMPY_ContextCreate() { return LLVMContextCreate(); } +LLVMPY_ContextCreate() { + LLVMContextRef context = LLVMContextCreate(); +#if LLVM_VERSION_MAJOR > 14 + LLVMContextSetOpaquePointers(context, false); +#endif + return context; +} API_EXPORT(void) LLVMPY_ContextDispose(LLVMContextRef context) { diff --git a/ffi/core.h b/ffi/core.h index 4888f8001..2d54d4453 100644 --- a/ffi/core.h +++ b/ffi/core.h @@ -2,6 +2,11 @@ #define LLVMPY_CORE_H_ #include "llvm-c/Core.h" + +// Needed for macros that control version-specific behaviour - included here so +// that they are available in all ffi translation units +#include "llvm/Config/llvm-config.h" + #include #include diff --git a/ffi/orcjit.cpp b/ffi/orcjit.cpp index eac3f96b7..fbdfa566c 100644 --- a/ffi/orcjit.cpp +++ b/ffi/orcjit.cpp @@ -158,7 +158,12 @@ LLVMPY_LLJITLookup(std::shared_ptr *lljit, const char *dylib_name, return nullptr; } - *addr = sym->getAddress(); +#if LLVM_VERSION_MAJOR <= 14 + *addr = sym->getAddress(); +#else + *addr = sym->getValue(); +#endif + return new JITDylibTracker(*lljit, *dylib, std::move(dylib->createResourceTracker())); } @@ -334,7 +339,11 @@ LLVMPY_LLJIT_Link(std::shared_ptr *lljit, const char *libraryName, LLVMDisposeErrorMessage(message); return nullptr; } + #if LLVM_VERSION_MAJOR <= 14 exports[export_idx].address = lookup->getAddress(); + #else + exports[export_idx].address = lookup->getValue(); + #endif } return new JITDylibTracker(*lljit, *dylib, std::move(dylib->getDefaultResourceTracker())); diff --git a/ffi/passmanagers.cpp b/ffi/passmanagers.cpp index 1e14660ae..454e36a29 100644 --- a/ffi/passmanagers.cpp +++ b/ffi/passmanagers.cpp @@ -161,8 +161,13 @@ LLVMPY_AddCallGraphDOTPrinterPass(LLVMPassManagerRef PM) { API_EXPORT(void) LLVMPY_AddDotDomPrinterPass(LLVMPassManagerRef PM, bool showBody) { +#if LLVM_VERSION_MAJOR <= 14 unwrap(PM)->add(showBody ? llvm::createDomPrinterPass() : llvm::createDomOnlyPrinterPass()); +#else + unwrap(PM)->add(showBody ? llvm::createDomPrinterWrapperPassPass() + : llvm::createDomOnlyPrinterWrapperPassPass()); +#endif } API_EXPORT(void) @@ -172,8 +177,13 @@ LLVMPY_AddGlobalsModRefAAPass(LLVMPassManagerRef PM) { API_EXPORT(void) LLVMPY_AddDotPostDomPrinterPass(LLVMPassManagerRef PM, bool showBody) { +#if LLVM_VERSION_MAJOR <= 14 unwrap(PM)->add(showBody ? llvm::createPostDomPrinterPass() : llvm::createPostDomOnlyPrinterPass()); +#else + unwrap(PM)->add(showBody ? llvm::createPostDomPrinterWrapperPassPass() + : llvm::createPostDomOnlyPrinterWrapperPassPass()); +#endif } API_EXPORT(void) @@ -244,10 +254,12 @@ LLVMPY_AddAlwaysInlinerPass(LLVMPassManagerRef PM, bool insertLifetime) { unwrap(PM)->add(llvm::createAlwaysInlinerLegacyPass(insertLifetime)); } +#if LLVM_VERSION_MAJOR < 15 API_EXPORT(void) LLVMPY_AddArgPromotionPass(LLVMPassManagerRef PM, unsigned int maxElements) { unwrap(PM)->add(llvm::createArgumentPromotionPass(maxElements)); } +#endif API_EXPORT(void) LLVMPY_AddBreakCriticalEdgesPass(LLVMPassManagerRef PM) { @@ -333,12 +345,14 @@ LLVMPY_AddLoopUnrollAndJamPass(LLVMPassManagerRef PM) { LLVMAddLoopUnrollAndJamPass(PM); } +#if LLVM_VERSION_MAJOR < 15 API_EXPORT(void) LLVMPY_AddLoopUnswitchPass(LLVMPassManagerRef PM, bool optimizeForSize, bool hasBranchDivergence) { unwrap(PM)->add( createLoopUnswitchPass(optimizeForSize, hasBranchDivergence)); } +#endif API_EXPORT(void) LLVMPY_AddLowerAtomicPass(LLVMPassManagerRef PM) { diff --git a/ffi/value.cpp b/ffi/value.cpp index c29606e49..103bd3222 100644 --- a/ffi/value.cpp +++ b/ffi/value.cpp @@ -6,6 +6,9 @@ // the following is needed for WriteGraph() #include "llvm/Analysis/CFGPrinter.h" +#if LLVM_VERSION_MAJOR > 14 +#include "llvm/Support/GraphWriter.h" +#endif /* An iterator around a attribute list, including the stop condition */ struct AttributeListIterator { diff --git a/llvmlite/binding/passmanagers.py b/llvmlite/binding/passmanagers.py index c5fcf919c..583508e28 100644 --- a/llvmlite/binding/passmanagers.py +++ b/llvmlite/binding/passmanagers.py @@ -3,6 +3,7 @@ from collections import namedtuple from enum import IntFlag from llvmlite.binding import ffi +from llvmlite.binding.initfini import llvm_version_info import os from tempfile import mkstemp from llvmlite.binding.common import _encode_string @@ -10,6 +11,7 @@ _prunestats = namedtuple('PruneStats', ('basicblock diamond fanout fanout_raise')) +llvm_version_major = llvm_version_info[0] class PruneStats(_prunestats): """ Holds statistics from reference count pruning. @@ -258,6 +260,8 @@ def add_arg_promotion_pass(self, max_elements=3): LLVM 14: `llvm::createArgumentPromotionPass` """ # noqa E501 + if llvm_version_major > 14: + raise RuntimeError('ArgumentPromotionPass unavailable in LLVM > 14') ffi.lib.LLVMPY_AddArgPromotionPass(self, max_elements) def add_break_critical_edges_pass(self): @@ -467,6 +471,8 @@ def add_loop_unswitch_pass(self, LLVM 14: `llvm::createLoopUnswitchPass` """ # noqa E501 + if llvm_version_major > 14: + raise RuntimeError('LoopUnswitchPass unavailable in LLVM > 14') ffi.lib.LLVMPY_AddLoopUnswitchPass(self, optimize_for_size, has_branch_divergence) @@ -866,7 +872,10 @@ def run_with_remarks(self, function, remarks_format='yaml', ffi.lib.LLVMPY_AddScalarEvolutionAAPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddAggressiveDCEPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddAlwaysInlinerPass.argtypes = [ffi.LLVMPassManagerRef, c_bool] -ffi.lib.LLVMPY_AddArgPromotionPass.argtypes = [ffi.LLVMPassManagerRef, c_uint] + +if llvm_version_major < 15: + ffi.lib.LLVMPY_AddArgPromotionPass.argtypes = [ffi.LLVMPassManagerRef, c_uint] + ffi.lib.LLVMPY_AddBreakCriticalEdgesPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddDeadStoreEliminationPass.argtypes = [ ffi.LLVMPassManagerRef] @@ -883,10 +892,13 @@ def run_with_remarks(self, function, remarks_format='yaml', ffi.lib.LLVMPY_AddLoopSimplificationPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLoopUnrollPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLoopUnrollAndJamPass.argtypes = [ffi.LLVMPassManagerRef] -ffi.lib.LLVMPY_AddLoopUnswitchPass.argtypes = [ - ffi.LLVMPassManagerRef, - c_bool, - c_bool] + +if llvm_version_major < 15: + ffi.lib.LLVMPY_AddLoopUnswitchPass.argtypes = [ + ffi.LLVMPassManagerRef, + c_bool, + c_bool] + ffi.lib.LLVMPY_AddLowerAtomicPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLowerInvokePass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLowerSwitchPass.argtypes = [ffi.LLVMPassManagerRef] diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py index 9583a602c..c5c537994 100644 --- a/llvmlite/tests/test_binding.py +++ b/llvmlite/tests/test_binding.py @@ -18,6 +18,7 @@ from llvmlite.binding import ffi from llvmlite.tests import TestCase +llvm_version_major = llvm.llvm_version_info[0] # arvm7l needs extra ABI symbols to link successfully if platform.machine() == 'armv7l': @@ -653,7 +654,7 @@ def break_up_asm(self, asm): def test_rv32d_ilp32(self): self.check_riscv_target() llmod = self.fpadd_ll_module() - target = self.riscv_target_machine(features="+f,+d") + target = self.riscv_target_machine(features="+f,+d", abiname="ilp32") self.assertEqual(self.break_up_asm(target.emit_assembly(llmod)), riscv_asm_ilp32) @@ -783,12 +784,14 @@ def test_set_option(self): """ subprocess.check_call([sys.executable, "-c", code]) + @unittest.skip('Edit this test to test for both llvm14 and llvm15') def test_version(self): major, minor, patch = llvm.llvm_version_info # one of these can be valid - valid = [(14, )] - self.assertIn((major,), valid) - self.assertIn(patch, range(10)) + valid = (14, 15) + self.assertIn(major, valid) + self.assertIn(patch, range(8)) + def test_check_jit_execution(self): llvm.check_jit_execution() @@ -2176,7 +2179,8 @@ def test_populate(self): pm.add_aggressive_dead_code_elimination_pass() pm.add_aa_eval_pass() pm.add_always_inliner_pass() - pm.add_arg_promotion_pass(42) + if llvm_version_major < 15: + pm.add_arg_promotion_pass(42) pm.add_break_critical_edges_pass() pm.add_dead_store_elimination_pass() pm.add_reverse_post_order_function_attrs_pass() @@ -2191,7 +2195,8 @@ def test_populate(self): pm.add_loop_simplification_pass() pm.add_loop_unroll_pass() pm.add_loop_unroll_and_jam_pass() - pm.add_loop_unswitch_pass() + if llvm_version_major < 15: + pm.add_loop_unswitch_pass() pm.add_lower_atomic_pass() pm.add_lower_invoke_pass() pm.add_lower_switch_pass() From 36ae6cd88147e5a839b3b5845c5a003ce78e11a3 Mon Sep 17 00:00:00 2001 From: Graham Markall <535640+gmarkall@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:04:23 +0000 Subject: [PATCH 03/11] Update ffi/Makefile.linux --- ffi/Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffi/Makefile.linux b/ffi/Makefile.linux index eb5fe0cd6..bc80d6112 100644 --- a/ffi/Makefile.linux +++ b/ffi/Makefile.linux @@ -2,7 +2,7 @@ CXX ?= g++ # -flto and --exclude-libs allow us to remove those parts of LLVM we don't use -#CXX_FLTO_FLAGS ?= -flto +CXX_FLTO_FLAGS ?= -flto LD_FLTO_FLAGS ?= -flto -Wl,--exclude-libs=ALL # -fPIC is required when compiling objects for a shared library CXX_FPIC_FLAGS ?= -fPIC From 34406e8ae0b9cc1af685a477a09ad15102e150fd Mon Sep 17 00:00:00 2001 From: Graham Markall <535640+gmarkall@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:09:01 +0000 Subject: [PATCH 04/11] Update llvmlite/tests/test_binding.py --- llvmlite/tests/test_binding.py | 1 - 1 file changed, 1 deletion(-) diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py index c5c537994..bd679e801 100644 --- a/llvmlite/tests/test_binding.py +++ b/llvmlite/tests/test_binding.py @@ -784,7 +784,6 @@ def test_set_option(self): """ subprocess.check_call([sys.executable, "-c", code]) - @unittest.skip('Edit this test to test for both llvm14 and llvm15') def test_version(self): major, minor, patch = llvm.llvm_version_info # one of these can be valid From 6206a41e0e6d0f782740e88341d1b7f601530c62 Mon Sep 17 00:00:00 2001 From: Graham Markall <535640+gmarkall@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:10:01 +0000 Subject: [PATCH 05/11] Update assembly.cpp --- ffi/assembly.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ffi/assembly.cpp b/ffi/assembly.cpp index ddaaa1286..b193d692c 100644 --- a/ffi/assembly.cpp +++ b/ffi/assembly.cpp @@ -16,6 +16,7 @@ API_EXPORT(LLVMModuleRef) LLVMPY_ParseAssembly(LLVMContextRef context, const char *ir, const char **outmsg) { using namespace llvm; + SMDiagnostic error; Module *m = parseAssemblyString(ir, error, *unwrap(context)).release(); From 247fa1667e05a1fabed6b4e4a8370a5667768006 Mon Sep 17 00:00:00 2001 From: Yashwant Singh Date: Thu, 14 Mar 2024 10:31:56 +0530 Subject: [PATCH 06/11] fix python formatting --- llvmlite/binding/passmanagers.py | 4 +++- llvmlite/tests/test_binding.py | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/llvmlite/binding/passmanagers.py b/llvmlite/binding/passmanagers.py index 583508e28..b84e4bf37 100644 --- a/llvmlite/binding/passmanagers.py +++ b/llvmlite/binding/passmanagers.py @@ -13,6 +13,7 @@ llvm_version_major = llvm_version_info[0] + class PruneStats(_prunestats): """ Holds statistics from reference count pruning. """ @@ -874,7 +875,8 @@ def run_with_remarks(self, function, remarks_format='yaml', ffi.lib.LLVMPY_AddAlwaysInlinerPass.argtypes = [ffi.LLVMPassManagerRef, c_bool] if llvm_version_major < 15: - ffi.lib.LLVMPY_AddArgPromotionPass.argtypes = [ffi.LLVMPassManagerRef, c_uint] + ffi.lib.LLVMPY_AddArgPromotionPass.argtypes = [ + ffi.LLVMPassManagerRef, c_uint] ffi.lib.LLVMPY_AddBreakCriticalEdgesPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddDeadStoreEliminationPass.argtypes = [ diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py index bd679e801..215ee0f41 100644 --- a/llvmlite/tests/test_binding.py +++ b/llvmlite/tests/test_binding.py @@ -791,7 +791,6 @@ def test_version(self): self.assertIn(major, valid) self.assertIn(patch, range(8)) - def test_check_jit_execution(self): llvm.check_jit_execution() From 64bb499fe3351f503678ca450e0cccac46f1d013 Mon Sep 17 00:00:00 2001 From: Yashwant Singh Date: Thu, 14 Mar 2024 10:42:47 +0530 Subject: [PATCH 07/11] run clang format --- ffi/core.cpp | 9 ++++----- ffi/orcjit.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ffi/core.cpp b/ffi/core.cpp index a9436ff67..0a4c5bb10 100644 --- a/ffi/core.cpp +++ b/ffi/core.cpp @@ -22,16 +22,15 @@ LLVMPY_DisposeString(const char *msg) { free(const_cast(msg)); } API_EXPORT(LLVMContextRef) LLVMPY_GetGlobalContext() { - auto context = LLVMGetGlobalContext(); + auto context = LLVMGetGlobalContext(); #if LLVM_VERSION_MAJOR > 14 - LLVMContextSetOpaquePointers(context, false); + LLVMContextSetOpaquePointers(context, false); #endif - return context; + return context; } - API_EXPORT(LLVMContextRef) -LLVMPY_ContextCreate() { +LLVMPY_ContextCreate() { LLVMContextRef context = LLVMContextCreate(); #if LLVM_VERSION_MAJOR > 14 LLVMContextSetOpaquePointers(context, false); diff --git a/ffi/orcjit.cpp b/ffi/orcjit.cpp index fbdfa566c..71488cdf4 100644 --- a/ffi/orcjit.cpp +++ b/ffi/orcjit.cpp @@ -159,9 +159,9 @@ LLVMPY_LLJITLookup(std::shared_ptr *lljit, const char *dylib_name, } #if LLVM_VERSION_MAJOR <= 14 - *addr = sym->getAddress(); + *addr = sym->getAddress(); #else - *addr = sym->getValue(); + *addr = sym->getValue(); #endif return new JITDylibTracker(*lljit, *dylib, @@ -339,11 +339,11 @@ LLVMPY_LLJIT_Link(std::shared_ptr *lljit, const char *libraryName, LLVMDisposeErrorMessage(message); return nullptr; } - #if LLVM_VERSION_MAJOR <= 14 +#if LLVM_VERSION_MAJOR <= 14 exports[export_idx].address = lookup->getAddress(); - #else +#else exports[export_idx].address = lookup->getValue(); - #endif +#endif } return new JITDylibTracker(*lljit, *dylib, std::move(dylib->getDefaultResourceTracker())); From bec8eec576500382e67e2a51908069d1e42da5d6 Mon Sep 17 00:00:00 2001 From: Graham Markall Date: Thu, 14 Mar 2024 09:54:59 +0000 Subject: [PATCH 08/11] Run CI with LLVM 15 on Linux and macOS --- azure-pipelines.yml | 10 ++++++++++ buildscripts/incremental/setup_conda_environment.sh | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c3d72e2c9..160354317 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,6 +18,11 @@ jobs: PYTHON: '3.12' CONDA_ENV: cienv + llvm15: + PYTHON: '3.12' + CONDA_ENV: cienv + LLVM: '15' + - template: buildscripts/azure/azure-linux-macos.yml parameters: name: Linux @@ -67,6 +72,11 @@ jobs: CONDA_ENV: cienv BUILD_DOCS: 'yes' + llvm15: + PYTHON: '3.12' + CONDA_ENV: cienv + LLVM: '15' + - template: buildscripts/azure/azure-windows.yml parameters: name: Windows diff --git a/buildscripts/incremental/setup_conda_environment.sh b/buildscripts/incremental/setup_conda_environment.sh index 20008b264..7dd431848 100755 --- a/buildscripts/incremental/setup_conda_environment.sh +++ b/buildscripts/incremental/setup_conda_environment.sh @@ -27,7 +27,11 @@ source activate $CONDA_ENV set -v # Install llvmdev (separate channel, for now) -$CONDA_INSTALL -c numba/label/dev llvmdev="14.*" +if [ "$LLVM" == "15" ]; then + $CONDA_INSTALL -c conda-forge llvmdev="15" +else + $CONDA_INSTALL -c numba/label/dev llvmdev="14.*" +fi # Install the compiler toolchain, for osx, bootstrapping needed # which happens in build.sh From a5859851fda4230af335d522c44a08241e3d0cf6 Mon Sep 17 00:00:00 2001 From: Graham Markall Date: Thu, 14 Mar 2024 13:42:46 +0000 Subject: [PATCH 09/11] Windows build: work around llvm/llvm-project#83802 --- ffi/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ffi/CMakeLists.txt b/ffi/CMakeLists.txt index 6dce3d152..907b1e1ec 100755 --- a/ffi/CMakeLists.txt +++ b/ffi/CMakeLists.txt @@ -11,6 +11,10 @@ if(NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -g") endif() +# Work around llvm/llvm-project#83802 - LLVM's Findzstd.cmake uses variables +# that require including `GNUInstallDirs`, but it does not include it itself. +include(GNUInstallDirs) + find_package(LLVM REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") From cdd4c5f336e842a9956e527a84ed66ad57e42975 Mon Sep 17 00:00:00 2001 From: Graham Markall Date: Thu, 14 Mar 2024 13:43:56 +0000 Subject: [PATCH 10/11] Run CI with LLVM 15 on Windows This includes changes: - Adding the Windows LLVM 15 config to the Azure setup. - Converting the commands in the Azure pipeline file to a call to the setup_conda_environment.cmd script (it's easier to edit a script rather than individual lines in the Azure file). - Installation of LLVM 15 from conda-forge. - A workaround / supporting change for the conda-forge solution to conda-forge/llvmdev-feedstock#175. --- buildscripts/azure/azure-windows.yml | 10 ++++----- buildscripts/incremental/build.cmd | 19 ++++++++++++++++ .../incremental/setup_conda_environment.cmd | 22 +++++++++---------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/buildscripts/azure/azure-windows.yml b/buildscripts/azure/azure-windows.yml index bfb20e177..fd61bb7a8 100644 --- a/buildscripts/azure/azure-windows.yml +++ b/buildscripts/azure/azure-windows.yml @@ -22,6 +22,10 @@ jobs: PYTHON: '3.12' CONDA_ENV: cienv + llvm15: + PYTHON: '3.12' + CONDA_ENV: cienv + LLVM: '15' steps: @@ -33,11 +37,7 @@ jobs: - script: | call C:\Miniconda3\Scripts\activate.bat - call conda list - call conda remove --all -q -y -n %CONDA_ENV% - call conda create -n %CONDA_ENV% -q -y python=%PYTHON% cmake - call activate %CONDA_ENV% - call conda install -y -q -c numba/label/dev llvmdev="14.*" libxml2 + call buildscripts\\incremental\\setup_conda_environment.cmd displayName: 'Before Install' - script: | diff --git a/buildscripts/incremental/build.cmd b/buildscripts/incremental/build.cmd index 4588d2490..182cdde8f 100644 --- a/buildscripts/incremental/build.cmd +++ b/buildscripts/incremental/build.cmd @@ -1,4 +1,23 @@ call activate %CONDA_ENV% +@rem LLVM derives the location of diaguids.lib from the build-time environment. +@rem Conda-forge packaging works around this by substituting the build-time +@rem location of Visual Studio with $ENV{VSINSTALLDIR}. In order to ensure that +@rem this environment variable is set appropriately, we activate the Visual +@rem Studio Developer Command Prompt prior to running setup.py +@rem +@rem This workaround is required whilst using LLVM from conda-forge; it may also +@rem be necessary to consider a workaround for our own llvmdev packages. +@rem +@rem For more info, see: +@rem +@rem - https://github.com/conda-forge/llvmdev-feedstock/issues/175 +@rem - https://github.com/conda-forge/llvmdev-feedstock/pull/223 +@rem - https://github.com/MicrosoftDocs/visualstudio-docs/issues/7774 +if "%LLVM%"=="15" ( + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" + if %errorlevel% neq 0 exit /b %errorlevel% +) + python setup.py build diff --git a/buildscripts/incremental/setup_conda_environment.cmd b/buildscripts/incremental/setup_conda_environment.cmd index e3b66574e..afd47c5f2 100644 --- a/buildscripts/incremental/setup_conda_environment.cmd +++ b/buildscripts/incremental/setup_conda_environment.cmd @@ -1,24 +1,24 @@ -@rem The cmd /C hack circumvents a regression where conda installs a conda.bat -@rem script in non-root environments. -set CONDA_INSTALL=cmd /C conda install -q -y -set PIP_INSTALL=pip install -q - @echo on -@rem Deactivate any environment -call deactivate @rem Display root environment (for debugging) -conda list +call conda list + @rem Clean up any left-over from a previous build -conda remove --all -q -y -n %CONDA_ENV% +call conda remove --all -q -y -n %CONDA_ENV% @rem Create and populate environment -conda create -n %CONDA_ENV% -q -y python=%PYTHON% cmake +call conda create -n %CONDA_ENV% -q -y python=%PYTHON% cmake if %errorlevel% neq 0 exit /b %errorlevel% call activate %CONDA_ENV% if %errorlevel% neq 0 exit /b %errorlevel% @rem Install llvmdev -%CONDA_INSTALL% -c numba/label/dev llvmdev="14.*" +if "%LLVM%"=="15" ( + set LLVMDEV_CHANNEL="conda-forge" +) else ( + set LLVMDEV_CHANNEL="numba/label/dev" +) + +call conda install -y -q -c %LLVMDEV_CHANNEL% llvmdev="%LLVM%" libxml2 if %errorlevel% neq 0 exit /b %errorlevel% From 2d5d8eef0be94b57543f6c890034fa2d8ea148d1 Mon Sep 17 00:00:00 2001 From: Yashwant Singh Date: Fri, 15 Mar 2024 11:30:01 +0530 Subject: [PATCH 11/11] Use legacysimpleloopunswitch with old PM; more consistency with version checking condtions --- ffi/orcjit.cpp | 12 ++++++------ ffi/passmanagers.cpp | 23 +++++++++++++---------- llvmlite/binding/passmanagers.py | 15 ++++----------- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/ffi/orcjit.cpp b/ffi/orcjit.cpp index 71488cdf4..60a4d8f3a 100644 --- a/ffi/orcjit.cpp +++ b/ffi/orcjit.cpp @@ -158,10 +158,10 @@ LLVMPY_LLJITLookup(std::shared_ptr *lljit, const char *dylib_name, return nullptr; } -#if LLVM_VERSION_MAJOR <= 14 - *addr = sym->getAddress(); -#else +#if LLVM_VERSION_MAJOR > 14 *addr = sym->getValue(); +#else + *addr = sym->getAddress(); #endif return new JITDylibTracker(*lljit, *dylib, @@ -339,10 +339,10 @@ LLVMPY_LLJIT_Link(std::shared_ptr *lljit, const char *libraryName, LLVMDisposeErrorMessage(message); return nullptr; } -#if LLVM_VERSION_MAJOR <= 14 - exports[export_idx].address = lookup->getAddress(); -#else +#if LLVM_VERSION_MAJOR > 14 exports[export_idx].address = lookup->getValue(); +#else + exports[export_idx].address = lookup->getAddress(); #endif } return new JITDylibTracker(*lljit, *dylib, diff --git a/ffi/passmanagers.cpp b/ffi/passmanagers.cpp index 454e36a29..da4a076b4 100644 --- a/ffi/passmanagers.cpp +++ b/ffi/passmanagers.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include using namespace llvm; @@ -161,12 +162,12 @@ LLVMPY_AddCallGraphDOTPrinterPass(LLVMPassManagerRef PM) { API_EXPORT(void) LLVMPY_AddDotDomPrinterPass(LLVMPassManagerRef PM, bool showBody) { -#if LLVM_VERSION_MAJOR <= 14 - unwrap(PM)->add(showBody ? llvm::createDomPrinterPass() - : llvm::createDomOnlyPrinterPass()); -#else +#if LLVM_VERSION_MAJOR > 14 unwrap(PM)->add(showBody ? llvm::createDomPrinterWrapperPassPass() : llvm::createDomOnlyPrinterWrapperPassPass()); +#else + unwrap(PM)->add(showBody ? llvm::createDomPrinterPass() + : llvm::createDomOnlyPrinterPass()); #endif } @@ -177,12 +178,12 @@ LLVMPY_AddGlobalsModRefAAPass(LLVMPassManagerRef PM) { API_EXPORT(void) LLVMPY_AddDotPostDomPrinterPass(LLVMPassManagerRef PM, bool showBody) { -#if LLVM_VERSION_MAJOR <= 14 - unwrap(PM)->add(showBody ? llvm::createPostDomPrinterPass() - : llvm::createPostDomOnlyPrinterPass()); -#else +#if LLVM_VERSION_MAJOR > 14 unwrap(PM)->add(showBody ? llvm::createPostDomPrinterWrapperPassPass() : llvm::createPostDomOnlyPrinterWrapperPassPass()); +#else + unwrap(PM)->add(showBody ? llvm::createPostDomPrinterPass() + : llvm::createPostDomOnlyPrinterPass()); #endif } @@ -345,14 +346,16 @@ LLVMPY_AddLoopUnrollAndJamPass(LLVMPassManagerRef PM) { LLVMAddLoopUnrollAndJamPass(PM); } -#if LLVM_VERSION_MAJOR < 15 API_EXPORT(void) LLVMPY_AddLoopUnswitchPass(LLVMPassManagerRef PM, bool optimizeForSize, bool hasBranchDivergence) { +#if LLVM_VERSION_MAJOR > 14 + unwrap(PM)->add(createSimpleLoopUnswitchLegacyPass(optimizeForSize)); +#else unwrap(PM)->add( createLoopUnswitchPass(optimizeForSize, hasBranchDivergence)); -} #endif +} API_EXPORT(void) LLVMPY_AddLowerAtomicPass(LLVMPassManagerRef PM) { diff --git a/llvmlite/binding/passmanagers.py b/llvmlite/binding/passmanagers.py index b84e4bf37..af6152f63 100644 --- a/llvmlite/binding/passmanagers.py +++ b/llvmlite/binding/passmanagers.py @@ -471,11 +471,9 @@ def add_loop_unswitch_pass(self, See https://llvm.org/docs/Passes.html#loop-unswitch-unswitch-loops LLVM 14: `llvm::createLoopUnswitchPass` + LLVM 15: `llvm::createSimpleLoopUnswitchLegacyPass` """ # noqa E501 - if llvm_version_major > 14: - raise RuntimeError('LoopUnswitchPass unavailable in LLVM > 14') - ffi.lib.LLVMPY_AddLoopUnswitchPass(self, - optimize_for_size, + ffi.lib.LLVMPY_AddLoopUnswitchPass(self, optimize_for_size, has_branch_divergence) def add_lower_atomic_pass(self): @@ -894,13 +892,8 @@ def run_with_remarks(self, function, remarks_format='yaml', ffi.lib.LLVMPY_AddLoopSimplificationPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLoopUnrollPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLoopUnrollAndJamPass.argtypes = [ffi.LLVMPassManagerRef] - -if llvm_version_major < 15: - ffi.lib.LLVMPY_AddLoopUnswitchPass.argtypes = [ - ffi.LLVMPassManagerRef, - c_bool, - c_bool] - +ffi.lib.LLVMPY_AddLoopUnswitchPass.argtypes = [ffi.LLVMPassManagerRef, c_bool, + c_bool] ffi.lib.LLVMPY_AddLowerAtomicPass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLowerInvokePass.argtypes = [ffi.LLVMPassManagerRef] ffi.lib.LLVMPY_AddLowerSwitchPass.argtypes = [ffi.LLVMPassManagerRef]