Bug#1127005: llvmlite: Diff for NMU upload to experimental 0.46.0-0.1

Stuart Prescott stuart at debian.org
Thu Feb 5 01:47:03 GMT 2026


Source: llvmlite
Version: 0.44.0-1
Severity: normal
X-Debbugs-Cc: stuart at debian.org

Dear Maintainer,

As foreshadowed, here's a debdiff (restricted to the debian directory)
for the upload of 0.46.0-0.1.

This is also in MR!7

  https://salsa.debian.org/pkg-llvm-team/llvmlite/-/merge_requests/7

And the upstream/pristine-tar branches are also in my fork of llvmlite
(I did not make 3 separate MRs for the extra upstream update). I'm happy
to do that integration into the llvmlite repository on salsa if you give
me access (requested a few weeks ago via salsa).

I've dealt with some other open (and related) bugs at the same time.

Summary:

 debian/changelog                                          |   19 +
 debian/clean                                              |    3 +-
 debian/control                                            |    8 +-
 debian/patches/0002-Support-llvm-21.patch                 |  140 +
 debian/patches/0003-Skip-llvm-version-test.patch          |   20 +
 debian/patches/0004-Skip-failing-tests-with-llvm-21.patch |   20 +
 debian/patches/llvm-14-compat.patch                       |   12 -
 debian/patches/llvm-19-support-pr1182.patch               | 6562 ---------------------------
 debian/patches/recognize-default-buildflags.patch         |   21 -
 debian/patches/series                                     |    6 +-
 debian/patches/skip-llvm-19-broken-tests.patch            |   19 -
 debian/patches/use-local-objectsinv.patch                 |   20 +-
 debian/rules                                              |   11 +-
 debian/watch                                              |   11 +-
 14 files changed, 240 insertions(+), 6632 deletions(-)

regards
Stuart
-------------- next part --------------
diff --git a/debian/changelog b/debian/changelog
index 0e7ad42..95c08d4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,22 @@
+llvmlite (0.46.0-0.1) experimental; urgency=medium
+
+  * Non-maintainer upload for Python 3.14 transition.
+  * New upstream release.
+    - Fix FTBFS with Python 3.14 (Closes: #1122961).
+    - upload to experimental to build against llvm-20
+    - add new build-dependencies
+    - refresh patches (dropping most of them as they are applied upstream)
+  * Add experimental patches for compatibility with llvm-21
+    (Closes: #1124062).
+  * Disable dwz as it causes FTBFS on arm64 (see #1016936).
+  * Drop usage of older llvm including llvm-14 (Closes: #1061108).
+  * Fix FTBFS by allowing tests to fail on loong64 (Closes: #1120659).
+  * Fix FTBFS by allowing tests to fail on riscv64 (Closes: #1071569).
+  * Update d/watch, leaving comment to enable dev releases if needed
+    (Closes: #1069786).
+
+ -- Stuart Prescott <stuart at debian.org>  Mon, 15 Dec 2025 17:29:15 +1100
+
 llvmlite (0.44.0-1) unstable; urgency=medium
 
   [ Diane Trout ]
diff --git a/debian/clean b/debian/clean
index 7a41e69..56ef5f3 100644
--- a/debian/clean
+++ b/debian/clean
@@ -1,3 +1,4 @@
 ffi/libllvmlite.so
 ffi/*.dwo
-llvmlite/binding/libllvmlite.so
\ No newline at end of file
+llvmlite/binding/libllvmlite.so
+ffi/build/
diff --git a/debian/control b/debian/control
index 2e3b948..d250675 100644
--- a/debian/control
+++ b/debian/control
@@ -4,14 +4,18 @@ Priority: optional
 Maintainer: LLVM Packaging Team <pkg-llvm-team at lists.alioth.debian.org>
 Uploaders: Mo Zhou <lumin at debian.org>
 Build-Depends:
+ cmake,
  debhelper-compat (= 13),
  dh-python,
+ libcurl4-gnutls-dev,
+ libedit-dev,
+ libzstd-dev,
  python3-doc <!nodoc>,
  python3:any | python3-all:any,
  python3-all-dev,
  python3-setuptools,
- llvm-19-dev,
- llvm-19-doc <!nodoc>,
+ llvm-21-dev,
+ llvm-21-doc <!nodoc>,
 Build-Depends-Indep:
  dh-sequence-sphinxdoc,
  python3-sphinx,
diff --git a/debian/patches/0002-Support-llvm-21.patch b/debian/patches/0002-Support-llvm-21.patch
new file mode 100644
index 0000000..9451828
--- /dev/null
+++ b/debian/patches/0002-Support-llvm-21.patch
@@ -0,0 +1,140 @@
+From: Stuart Prescott <stuart at debian.org>
+Date: Mon, 15 Dec 2025 18:52:48 +1100
+Subject: Support llvm-21
+
+---
+ ffi/CMakeLists.txt      |  2 +-
+ ffi/PASSREGISTRY.def    |  8 +++++++-
+ ffi/newpassmanagers.cpp | 14 ++++++++++++--
+ ffi/orcjit.cpp          | 27 ++++++++++++++++-----------
+ 4 files changed, 36 insertions(+), 15 deletions(-)
+
+diff --git a/ffi/CMakeLists.txt b/ffi/CMakeLists.txt
+index 205dccc..665ac29 100755
+--- a/ffi/CMakeLists.txt
++++ b/ffi/CMakeLists.txt
+@@ -18,7 +18,7 @@ set(CMAKE_CXX_STANDARD 17)
+ set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
+ set(CMAKE_C_VISIBILITY_PRESET "hidden")
+ 
+-find_package(LLVM REQUIRED CONFIG)
++find_package(LLVM REQUIRED CONFIG 21.1)
+ 
+ message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
+ message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
+diff --git a/ffi/PASSREGISTRY.def b/ffi/PASSREGISTRY.def
+index 9aaffd4..cb04565 100644
+--- a/ffi/PASSREGISTRY.def
++++ b/ffi/PASSREGISTRY.def
+@@ -41,7 +41,6 @@ FUNCTION_PASS(DomViewer)
+ FUNCTION_PASS(DomOnlyViewer)
+ FUNCTION_PASS(PostDomViewer)
+ FUNCTION_PASS(PostDomOnlyViewer)
+-FUNCTION_PASS(LintPass)
+ FUNCTION_PASS(ADCEPass)
+ FUNCTION_PASS(BreakCriticalEdgesPass)
+ FUNCTION_PASS(DSEPass)
+@@ -63,9 +62,16 @@ FUNCTION_PASS(TailCallElimPass)
+ FUNCTION_PASS(InstructionNamerPass)
+ #undef FUNCTION_PASS
+ 
++#ifndef FUNCTION_PASS_WITH_PARAMS
++#define FUNCTION_PASS_WITH_PARAMS(NAME, ...)
++#endif
+ // TODO: Add them if needed
+ // FUNCTION_PASS_WITH_PARAMS(SimplifyCFGPass)
+ // FUNCTION_PASS_WITH_PARAMS(LoopUnrollPass)
++FUNCTION_PASS_WITH_PARAMS(LintPass, (bool AbortOnError), (AbortOnError))
++#undef FUNCTION_PASS_WITH_PARAMS
++#undef UNPAREN
++#undef UNPAREN_IMPL
+ 
+ #ifndef LOOP_PASS
+ #define LOOP_PASS(NAME)
+diff --git a/ffi/newpassmanagers.cpp b/ffi/newpassmanagers.cpp
+index 06116a1..704603d 100644
+--- a/ffi/newpassmanagers.cpp
++++ b/ffi/newpassmanagers.cpp
+@@ -106,9 +106,7 @@
+ #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
+ #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
+ #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
+-#include "llvm/Transforms/Instrumentation/InstrOrderFile.h"
+ #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
+-#include "llvm/Transforms/Instrumentation/MemProfiler.h"
+ #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
+ #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
+ #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
+@@ -639,6 +637,18 @@ LLVMPY_module_AddModuleDebugInfoPrinterPass(LLVMModulePassManagerRef MPM) {
+     }
+ #include "PASSREGISTRY.def"
+ 
++#define UNPAREN(X) UNPAREN_IMPL X
++#define UNPAREN_IMPL(...) __VA_ARGS__
++#define FUNCTION_PASS_WITH_PARAMS(NAME, PARAM_DECLS, ARG_LIST)                                      \
++    API_EXPORT(void) LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM, UNPAREN(PARAM_DECLS)) {  \
++        llvm::unwrap(MPM)->addPass(createModuleToFunctionPassAdaptor(NAME(ARG_LIST)));              \
++    }                                                                                               \
++    API_EXPORT(void)                                                                                \
++    LLVMPY_function_Add##NAME(LLVMFunctionPassManagerRef FPM, UNPAREN(PARAM_DECLS)) {               \
++        llvm::unwrap(FPM)->addPass(NAME(ARG_LIST));                                                 \
++    }
++#include "PASSREGISTRY.def"
++
+ #define LOOP_PASS(NAME)                                                        \
+     API_EXPORT(void) LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {   \
+         llvm::unwrap(MPM)->addPass(createModuleToFunctionPassAdaptor(          \
+diff --git a/ffi/orcjit.cpp b/ffi/orcjit.cpp
+index bf624ba..cbcf814 100644
+--- a/ffi/orcjit.cpp
++++ b/ffi/orcjit.cpp
+@@ -15,6 +15,11 @@
+ #include "llvm/Support/MemoryBuffer.h"
+ #include "llvm/Support/SourceMgr.h"
+ 
++#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
++
++extern "C" void
++llvm_orc_registerJITLoaderGDBWrapper(void);
++
+ using namespace llvm;
+ using namespace llvm::orc;
+ 
+@@ -73,18 +78,18 @@ LLVMPY_CreateLLJITCompiler(LLVMTargetMachineRef tm, bool suppressErrors,
+         // / shared with other objects on the Python side.
+         auto *template_tm = unwrap(tm);
+ 
+-        builder.setJITTargetMachineBuilder(
+-            JITTargetMachineBuilder(template_tm->getTargetTriple())
+-                .setCPU(template_tm->getTargetCPU().str())
+-                .setRelocationModel(template_tm->getRelocationModel())
+-                .setCodeModel(template_tm->getCodeModel())
+-                .setCodeGenOptLevel(template_tm->getOptLevel())
+-                .setFeatures(template_tm->getTargetFeatureString())
+-                .setOptions(template_tm->Options));
++        auto JTMB = JITTargetMachineBuilder(template_tm->getTargetTriple());\
++        JTMB.setCPU(template_tm->getTargetCPU().str())\
++            .setRelocationModel(template_tm->getRelocationModel())\
++            .setCodeModel(template_tm->getCodeModel())\
++            .setCodeGenOptLevel(template_tm->getOptLevel())\
++            .setFeatures(template_tm->getTargetFeatureString())\
++            .setOptions(template_tm->Options);\
++        builder.setJITTargetMachineBuilder(std::move(JTMB));
+     }
++    auto triple = builder.getJITTargetMachineBuilder()->getTargetTriple();
+     builder.setObjectLinkingLayerCreator(
+-        [=](llvm::orc::ExecutionSession &session, const llvm::Triple &triple)
+-            -> std::unique_ptr<llvm::orc::ObjectLayer> {
++        [=](llvm::orc::ExecutionSession &session) -> Expected<std::unique_ptr<llvm::orc::ObjectLayer>> {
+             if (useJitLink) {
+                 auto linkingLayer =
+                     std::make_unique<llvm::orc::ObjectLinkingLayer>(session);
+@@ -108,7 +113,7 @@ LLVMPY_CreateLLJITCompiler(LLVMTargetMachineRef tm, bool suppressErrors,
+                 return linkingLayer;
+             } else {
+                 auto linkingLayer = std::make_unique<
+-                    llvm::orc::RTDyldObjectLinkingLayer>(session, []() {
++                    llvm::orc::RTDyldObjectLinkingLayer>(session, [](const llvm::MemoryBuffer &ObjBuffer) {
+                     return std::make_unique<llvm::SectionMemoryManager>();
+                 });
+                 if (triple.isOSBinFormatCOFF()) {
diff --git a/debian/patches/0003-Skip-llvm-version-test.patch b/debian/patches/0003-Skip-llvm-version-test.patch
new file mode 100644
index 0000000..40214b1
--- /dev/null
+++ b/debian/patches/0003-Skip-llvm-version-test.patch
@@ -0,0 +1,20 @@
+From: Stuart Prescott <stuart at debian.org>
+Date: Mon, 15 Dec 2025 20:37:16 +1100
+Subject: Skip llvm version test
+
+---
+ llvmlite/tests/test_binding.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py
+index a4d777c..9e15c97 100644
+--- a/llvmlite/tests/test_binding.py
++++ b/llvmlite/tests/test_binding.py
+@@ -937,6 +937,7 @@ class TestMisc(BaseTest):
+             """
+         subprocess.check_call([sys.executable, "-c", code])
+ 
++    @unittest.skip("Debian package built with Debian llvm version")
+     def test_version(self):
+         major, minor, patch = llvm.llvm_version_info
+         # one of these can be valid
diff --git a/debian/patches/0004-Skip-failing-tests-with-llvm-21.patch b/debian/patches/0004-Skip-failing-tests-with-llvm-21.patch
new file mode 100644
index 0000000..98e7e20
--- /dev/null
+++ b/debian/patches/0004-Skip-failing-tests-with-llvm-21.patch
@@ -0,0 +1,20 @@
+From: Stuart Prescott <stuart at debian.org>
+Date: Mon, 15 Dec 2025 20:37:37 +1100
+Subject: Skip failing tests with llvm-21
+
+---
+ llvmlite/tests/test_binding.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py
+index 9e15c97..60582b3 100644
+--- a/llvmlite/tests/test_binding.py
++++ b/llvmlite/tests/test_binding.py
+@@ -1634,6 +1634,7 @@ class TestValueRef(BaseTest):
+             self.assertIsInstance(glob.storage_class, llvm.StorageClass)
+             self.assertEqual(glob.storage_class.name, storage_class)
+ 
++    @unittest.skip("'nocapture' attribute test broken with llvm-21?")
+     def test_add_function_attribute(self):
+         mod = self.module()
+         fn = mod.get_function("sum")
diff --git a/debian/patches/llvm-14-compat.patch b/debian/patches/llvm-14-compat.patch
deleted file mode 100644
index 1ca83b7..0000000
--- a/debian/patches/llvm-14-compat.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: llvmlite/ffi/passmanagers.cpp
-===================================================================
---- llvmlite.orig/ffi/passmanagers.cpp
-+++ llvmlite/ffi/passmanagers.cpp
-@@ -22,6 +22,7 @@
- #include "llvm/Transforms/IPO.h"
- #include "llvm/Transforms/Scalar.h"
- 
-+#include "llvm/Pass.h"
- #include <llvm/IR/PassTimingInfo.h>
- 
- #include <llvm/Analysis/AliasAnalysisEvaluator.h>
diff --git a/debian/patches/llvm-19-support-pr1182.patch b/debian/patches/llvm-19-support-pr1182.patch
deleted file mode 100644
index 4d24173..0000000
--- a/debian/patches/llvm-19-support-pr1182.patch
+++ /dev/null
@@ -1,6562 +0,0 @@
-From af8cd11af4798f7411c1a9ca814de28eedbffa2c Mon Sep 17 00:00:00 2001
-From: Ricardo Jesus <rjj at nvidia.com>
-Date: Tue, 25 Mar 2025 11:29:25 +0000
-Subject: [PATCH 1/5] Apply #1159
-
----
- buildscripts/incremental/test.cmd      |  6 +-
- buildscripts/incremental/test.sh       |  6 +-
- docs/source/user-guide/deprecation.rst | 33 +++++++--
- docs/source/user-guide/ir/types.rst    | 18 ++---
- examples/opaque_pointers/llvmir.py     |  2 +-
- examples/opaque_pointers/sum.py        |  2 +-
- llvmlite/__init__.py                   | 12 ++--
- llvmlite/ir/types.py                   | 19 +----
- llvmlite/tests/test_ir.py              | 99 +++++++++-----------------
- 9 files changed, 86 insertions(+), 111 deletions(-)
-
-diff --git a/buildscripts/incremental/test.cmd b/buildscripts/incremental/test.cmd
-index 7e3ab5c0a..c32424a5a 100644
---- a/buildscripts/incremental/test.cmd
-+++ b/buildscripts/incremental/test.cmd
-@@ -2,10 +2,10 @@
- call activate %CONDA_ENV%
- 
- if "%OPAQUE_POINTERS%"=="yes" (
--  set LLVMLITE_ENABLE_OPAQUE_POINTERS=1
--  echo "Testing with opaque pointers enabled"
-+  set LLVMLITE_ENABLE_IR_LAYER_TYPED_POINTERS=0
-+  echo "Testing with IR layer opaque pointers enabled"
- ) else (
--  echo "Testing with opaque pointers disabled"
-+  echo "Testing with IR layer opaque pointers disabled"
- )
- 
- python runtests.py -v
-diff --git a/buildscripts/incremental/test.sh b/buildscripts/incremental/test.sh
-index 70f3d3906..ea8816c44 100755
---- a/buildscripts/incremental/test.sh
-+++ b/buildscripts/incremental/test.sh
-@@ -10,10 +10,10 @@ set -v -e
- python --version
- 
- if [ "$OPAQUE_POINTERS" == "yes" ]; then
--    export LLVMLITE_ENABLE_OPAQUE_POINTERS=1
--    echo "Testing with opaque pointers enabled"
-+    export LLVMLITE_ENABLE_IR_LAYER_TYPED_POINTERS=0
-+    echo "Testing with IR layer opaque pointers enabled"
- else
--    echo "Testing with opaque pointers disabled"
-+    echo "Testing with IR layer opaque pointers disabled"
- fi
- 
- if [ "$WHEEL" == "yes" ]; then
-diff --git a/docs/source/user-guide/deprecation.rst b/docs/source/user-guide/deprecation.rst
-index cb0c36f2c..5167970e7 100644
---- a/docs/source/user-guide/deprecation.rst
-+++ b/docs/source/user-guide/deprecation.rst
-@@ -30,20 +30,38 @@ switching to `Opaque Pointers <https://llvm.org/docs/OpaquePointers.html>`_:
-   therefore may have bugs that go unfixed).
- - In LLVM 17, support for Typed Pointers is removed.
- 
--Although Opaque Pointers are already the default in LLVM 15, llvmlite still uses
--Typed Pointers by default with LLVM 15.
-+Although Opaque Pointers are already the default in LLVM 15, llvmlite still used
-+Typed Pointers by default with LLVM 15 in llvmlite 0.44.
-+
-+The binding layer will move to using Opaque Pointers. The IR layer will still
-+support both Typed and Opaque Pointers, defaulting to Typed Pointers when
-+pointee types are provided. This allows llvmlite to continue being used with
-+LLVM-based projects that use an older LLVM version, such as `NVVM
-+<https://docs.nvidia.com/cuda/nvvm-ir-spec/>`_.
- 
- Examples(s) of the impact
- -------------------------
- 
--Code that uses llvmlite to work with pointers or to parse assembly that uses
--pointers will break if not modified to use opaque pointers.
-+In a future release, code that uses llvmlite to work with Typed Pointers or
-+generate IR with Typed Pointers will break if not modified to use Opaque
-+Pointers.
-+
-+In the meantime, IR generated by the IR layer and parsed by the binding layer
-+will be auto-upgraded to use Opaque Pointers transparently; no action is
-+required by the user.
- 
- Schedule
- --------
- 
--- In llvmlite 0.44, Opaque Pointers will be the default pointer kind.
--- In llvmlite 0.45, support for Typed Pointers will be removed.
-+- In llvmlite 0.45, support for Typed Pointers in the binding layer will be
-+  removed. The IR layer will still use Typed Pointers by default.
-+- In a future version of llvmlite (>= 0.46), the IR layer will use Opaque
-+  Pointers by default.
-+- In a subsequent version of llvmlite (>= 0.47), support for Typed Pointers at
-+  the IR layer will be removed.
-+
-+This schedule may be updated to push out the deprecation / removal of Typed
-+Pointer support to still later versions of llvmlite.
- 
- Recommendations
- ---------------
-@@ -127,7 +145,8 @@ When working with global variables and functions (which will be :class:`ValueRef
- 
- When passing assembly to :func:`llvmlite.binding.parse_assembly`:
- 
--- Ensure that any IR passed to ``parse_assembly()`` uses Opaque Pointers.
-+- IR passed to ``parse_assembly()`` is free to use either Typed or Opaque
-+  Pointers.
- 
- 
- Deprecation of `llvmlite.llvmpy` module
-diff --git a/docs/source/user-guide/ir/types.rst b/docs/source/user-guide/ir/types.rst
-index 220b8fcd1..be2765ea1 100644
---- a/docs/source/user-guide/ir/types.rst
-+++ b/docs/source/user-guide/ir/types.rst
-@@ -100,15 +100,14 @@ Atomic types
- Pointer Types
- =============
- 
--llvmlite presently supports both *Typed Pointers* and *Opaque Pointers*. Typed
--Pointers are currently the default; Opaque Pointers will become the default in
--future, and support for Typed Pointers will be eventually be removed.
-+The IR layer presently supports both *Typed Pointers* and *Opaque Pointers*.
-+Support for Typed Pointers will eventually be removed.
- 
- .. note::
-    Further details of the migration to Opaque Pointers are outlined in the
-    section on :ref:`deprecation-of-typed-pointers`.
- 
--When Typed Pointers are enabled, the pointer type is represented using:
-+Typed Pointers are created using:
- 
- .. class:: PointerType(pointee, addrspace=0)
- 
-@@ -126,23 +125,24 @@ When Typed Pointers are enabled, the pointer type is represented using:
- 
-         The type pointed to.
- 
--Opaque pointers can be enabled by setting the environment variable:
-+Printing of Typed Pointers as Opaque Pointers can be enabled by setting the
-+environment variable:
- 
- .. code:: bash
- 
--   LLVMLITE_ENABLE_OPAQUE_POINTERS=1
-+   LLVMLITE_ENABLE_IR_LAYER_TYPED_POINTERS=0
- 
--or by setting the ``opaque_pointers_enabled`` attribute after importing
-+or by setting the ``ir_layer_typed_pointers_enabled`` attribute after importing
- llvmlite, but prior to using any of its functionality. For example:
- 
- .. code:: python
- 
-    import llvmlite
--   llvmlite.opaque_pointers_enabled = True
-+   llvmlite.ir_layer_typed_pointers_enabled = False
- 
-    # ... continue using llvmlite ...
- 
--When Opaque Pointers are enabled, the pointer type is represented using:
-+Opaque Pointers can be created by using:
- 
- .. class:: PointerType(addrspace=0)
-    :no-index:
-diff --git a/examples/opaque_pointers/llvmir.py b/examples/opaque_pointers/llvmir.py
-index d25f0f2a5..875a2616d 100644
---- a/examples/opaque_pointers/llvmir.py
-+++ b/examples/opaque_pointers/llvmir.py
-@@ -1,5 +1,5 @@
- import llvmlite
--llvmlite.opaque_pointers_enabled = True
-+llvmlite.ir_layer_typed_pointers_enabled = False
- 
- import llvmlite.ir as ll
- 
-diff --git a/examples/opaque_pointers/sum.py b/examples/opaque_pointers/sum.py
-index f1c525c94..421c0be71 100644
---- a/examples/opaque_pointers/sum.py
-+++ b/examples/opaque_pointers/sum.py
-@@ -15,7 +15,7 @@
-     pass
- 
- import llvmlite
--llvmlite.opaque_pointers_enabled = True
-+llvmlite.ir_layer_typed_pointers_enabled = False
- 
- import llvmlite.ir as ll
- import llvmlite.binding as llvm
-diff --git a/llvmlite/__init__.py b/llvmlite/__init__.py
-index f830f73f9..d53654370 100644
---- a/llvmlite/__init__.py
-+++ b/llvmlite/__init__.py
-@@ -3,8 +3,12 @@
- del get_versions
- 
- # FIXME: Remove me once typed pointers are no longer supported.
--def _opaque_pointers_enabled():
-+# Opaque pointers unconditionally required for later LLVM versions
-+opaque_pointers_enabled = True
-+# We default to IR layer typed pointers being enabled, since they're needed in
-+# the most common usage scenarios with later LLVMs.
-+def _ir_layer_typed_pointers_enabled():
-   import os
--  return os.environ.get('LLVMLITE_ENABLE_OPAQUE_POINTERS', '0') == '1'
--opaque_pointers_enabled = _opaque_pointers_enabled()
--del _opaque_pointers_enabled
-+  return os.environ.get('LLVMLITE_ENABLE_IR_LAYER_TYPED_POINTERS', '1') == '1'
-+ir_layer_typed_pointers_enabled = _ir_layer_typed_pointers_enabled()
-+del _ir_layer_typed_pointers_enabled
-diff --git a/llvmlite/ir/types.py b/llvmlite/ir/types.py
-index eac3ada7a..9a6ba0943 100644
---- a/llvmlite/ir/types.py
-+++ b/llvmlite/ir/types.py
-@@ -4,11 +4,9 @@
- 
- import struct
- 
-+from llvmlite import ir_layer_typed_pointers_enabled
- from llvmlite.ir._utils import _StrCaching
- 
--# FIXME: Remove me once typed pointers are no longer supported.
--from llvmlite import opaque_pointers_enabled
--
- 
- def _wrapname(x):
-     return '"{0}"'.format(x.replace('\\', '\\5c').replace('"', '\\22'))
-@@ -145,8 +143,6 @@ def from_llvm(cls, typeref, ir_ctx):
-         """
-         Create from a llvmlite.binding.TypeRef
-         """
--        if not opaque_pointers_enabled:
--            return _TypedPointerType.from_llvm(typeref, ir_ctx)
-         return cls()
- 
- 
-@@ -163,7 +159,7 @@ def __init__(self, pointee, addrspace=0):
-         self.is_opaque = False
- 
-     def _to_string(self):
--        if not opaque_pointers_enabled:
-+        if ir_layer_typed_pointers_enabled:
-             return "{0}*".format(self.pointee) if self.addrspace == 0 else \
-                    "{0} addrspace({1})*".format(self.pointee, self.addrspace)
-         return super(_TypedPointerType, self)._to_string()
-@@ -190,17 +186,6 @@ def gep(self, i):
-     def intrinsic_name(self):
-         return 'p%d%s' % (self.addrspace, self.pointee.intrinsic_name)
- 
--    @classmethod
--    def from_llvm(cls, typeref, ir_ctx):
--        """
--        Create from a llvmlite.binding.TypeRef
--        """
--        assert not opaque_pointers_enabled
--        # opaque pointer will change this
--        [pointee] = typeref.elements
--        # addrspace is not handled
--        return cls(pointee.as_ir(ir_ctx=ir_ctx))
--
- 
- class VoidType(Type):
-     """
-diff --git a/llvmlite/tests/test_ir.py b/llvmlite/tests/test_ir.py
-index 5b29aa82f..410b3b235 100644
---- a/llvmlite/tests/test_ir.py
-+++ b/llvmlite/tests/test_ir.py
-@@ -12,9 +12,7 @@
- from . import TestCase
- from llvmlite import ir
- from llvmlite import binding as llvm
--
--# FIXME: Remove me once typed pointers are no longer supported.
--from llvmlite import opaque_pointers_enabled
-+from llvmlite import ir_layer_typed_pointers_enabled
- 
- 
- int1 = ir.IntType(1)
-@@ -123,10 +121,9 @@ def check_func_body(self, func, asm):
- 
- class TestFunction(TestBase):
- 
--    # FIXME: Remove `else' once TP are no longer supported.
-     proto = \
-         """i32 @"my_func"(i32 %".1", i32 %".2", double %".3", ptr %".4")""" \
--        if opaque_pointers_enabled else \
-+        if not ir_layer_typed_pointers_enabled else \
-         """i32 @"my_func"(i32 %".1", i32 %".2", double %".3", i32* %".4")"""
- 
-     def test_declare(self):
-@@ -146,8 +143,7 @@ def test_declare_attributes(self):
-         pers = ir.Function(self.module(), tp_pers, '__gxx_personality_v0')
-         func.attributes.personality = pers
-         asm = self.descr(func).strip()
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(asm,
-                              ("declare %s alwaysinline convergent optsize "
-                               "alignstack(16) "
-@@ -172,8 +168,7 @@ def test_function_attributes(self):
-         func.args[3].add_attribute("nonnull")
-         func.return_value.add_attribute("noalias")
-         asm = self.descr(func).strip()
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(asm,
-                              """declare noalias i32 @"my_func"(i32 zeroext %".1", i32 dereferenceable(5) dereferenceable_or_null(10) %".2", double %".3", ptr nonnull align 4 %".4")"""  # noqa E501
-                              )
-@@ -284,8 +279,7 @@ def test_declare_intrinsics(self):
-         assume = module.declare_intrinsic('llvm.assume')
-         self.check_descr(self.descr(powi).strip(), """\
-             declare double @"llvm.powi.f64"(double %".1", i32 %".2")""")
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_descr(self.descr(memset).strip(), """\
-                 declare void @"llvm.memset.p0i8.i32"(ptr %".1", i8 %".2", i32 %".3", i1 %".4")""")  # noqa E501
-             self.check_descr(self.descr(memcpy).strip(), """\
-@@ -402,8 +396,7 @@ def test_metadata_null(self):
-         # A null metadata (typed) value
-         mod = self.module()
-         mod.add_metadata([int32.as_pointer()(None)])
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assert_ir_line("!0 = !{ ptr null }", mod)
-         else:
-             self.assert_ir_line("!0 = !{ i32* null }", mod)
-@@ -623,8 +616,7 @@ def test_globals_access(self):
-         with self.assertRaises(KeyError):
-             mod.get_global('kkk')
-         # Globals should have a useful repr()
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(repr(globdouble),
-                              "<ir.GlobalVariable 'globdouble' of type 'ptr'>")
-         else:
-@@ -1027,7 +1019,7 @@ def test_mem_ops(self):
-         self.assertEqual(j.type, ir.VoidType())
-         k = builder.load_atomic(c, ordering="seq_cst", align=4, name='k')
-         self.assertEqual(k.type, int32)
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             ptr = ir.Constant(ir.PointerType(), None)
-         else:
-             ptr = ir.Constant(ir.PointerType(int32), None)
-@@ -1041,8 +1033,7 @@ def test_mem_ops(self):
-         with self.assertRaises(TypeError) as cm:
-             builder.store(b, e)
- 
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(cm.exception),
-                              "cannot store i32 to ptr: mismatching types")
-             self.check_block(block, """\
-@@ -1084,8 +1075,7 @@ def test_gep(self):
-         c = builder.alloca(ir.PointerType(int32), name='c')
-         d = builder.gep(c, [ir.Constant(int32, 5), a], name='d')
-         self.assertEqual(d.type, ir.PointerType(int32))
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"c" = alloca ptr
-@@ -1110,8 +1100,7 @@ def test_gep_castinstr(self):
-         d = builder.bitcast(a, ls.as_pointer(), name='d')
-         e = builder.gep(d, [ir.Constant(int32, x) for x in [0, 3]], name='e')
-         self.assertEqual(e.type, ir.PointerType(int8ptr))
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"d" = bitcast i32 %".1" to ptr
-@@ -1137,8 +1126,7 @@ def test_gep_castinstr_addrspace(self):
-         e = builder.gep(d, [ir.Constant(int32, x) for x in [0, 3]], name='e')
-         self.assertEqual(e.type.addrspace, addrspace)
-         self.assertEqual(e.type, ir.PointerType(int8ptr, addrspace=addrspace))
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"d" = bitcast i32 %".1" to ptr addrspace(4)
-@@ -1157,8 +1145,7 @@ def test_gep_addrspace(self):
-         a, b = builder.function.args[:2]
-         addrspace = 4
-         c = builder.alloca(ir.PointerType(int32, addrspace=addrspace), name='c')
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c.type), 'ptr')
-         else:
-             self.assertEqual(str(c.type), 'i32 addrspace(4)**')
-@@ -1167,8 +1154,7 @@ def test_gep_addrspace(self):
-         self.assertEqual(d.type.addrspace, addrspace)
-         e = builder.gep(d, [ir.Constant(int32, 10)], name='e')
-         self.assertEqual(e.type.addrspace, addrspace)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"c" = alloca ptr addrspace(4)
-@@ -1229,8 +1215,7 @@ def test_extract_insert_value(self):
-             # Replacement value has the wrong type
-             builder.insert_value(c_inner, a, 1)
- 
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"c" = extractvalue {i32, i1} {i32 4, i1 true}, 0
-@@ -1278,8 +1263,7 @@ def test_cast_ops(self):
-         j = builder.inttoptr(i, ir.PointerType(int8), 'j')  # noqa F841
-         k = builder.bitcast(a, flt, "k")  # noqa F841
-         self.assertFalse(block.is_terminated)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"c" = trunc i32 %".1" to i8
-@@ -1319,8 +1303,7 @@ def test_atomicrmw(self):
-         c = builder.alloca(int32, name='c')
-         d = builder.atomic_rmw('add', c, a, 'monotonic', 'd')
-         self.assertEqual(d.type, int32)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"c" = alloca i32
-@@ -1382,8 +1365,7 @@ def test_branch_indirect(self):
-         indirectbr.add_destination(bb_1)
-         indirectbr.add_destination(bb_2)
-         self.assertTrue(block.is_terminated)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     indirectbr ptr blockaddress(@"my_func", %"b_1"), [label %"b_1", label %"b_2"]
-@@ -1505,8 +1487,7 @@ def test_call_metadata(self):
-         a = builder.alloca(int32, name="a")
-         b = builder.module.add_metadata(())
-         builder.call(dbg_declare, (a, b, b))
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"a" = alloca i32
-@@ -1536,8 +1517,7 @@ def test_call_attributes(self):
-                 2: 'noalias'
-             }
-         )
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block_regex(block, """\
-             my_block:
-                 %"retval" = alloca i32
-@@ -1628,8 +1608,7 @@ def test_invoke_attributes(self):
-                 2: 'noalias'
-             }
-         )
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block_regex(block, """\
-             my_block:
-                 %"retval" = alloca i32
-@@ -1658,8 +1637,7 @@ def test_landingpad(self):
-         lp.add_clause(ir.FilterClause(ir.Constant(ir.ArrayType(
-             int_typeinfo.type, 1), [int_typeinfo])))
-         builder.resume(lp)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"lp" = landingpad {i32, ptr}
-@@ -2346,8 +2324,7 @@ def test_metadata(self):
-         builder = ir.IRBuilder(block)
-         builder.debug_metadata = builder.module.add_metadata([])
-         builder.alloca(ir.PointerType(int32), name='c')
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.check_block(block, """\
-                 my_block:
-                     %"c" = alloca ptr, !dbg !0
-@@ -2431,8 +2408,7 @@ def test_str(self):
-                          'i1 (float, ...)')
-         self.assertEqual(str(ir.FunctionType(int1, (flt, dbl), var_arg=True)),
-                          'i1 (float, double, ...)')
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(ir.PointerType(int32)), 'ptr')
-             self.assertEqual(str(ir.PointerType(ir.PointerType(int32))), 'ptr')
-         else:
-@@ -2440,8 +2416,7 @@ def test_str(self):
-             self.assertEqual(str(ir.PointerType(ir.PointerType(int32))),
-                              'i32**')
-         self.assertEqual(str(ir.ArrayType(int1, 5)), '[5 x i1]')
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(ir.ArrayType(ir.PointerType(int1), 5)),
-                              '[5 x ptr]')
-             self.assertEqual(str(ir.PointerType(ir.ArrayType(int1, 5))), 'ptr')
-@@ -2452,8 +2427,7 @@ def test_str(self):
-                              '[5 x i1]*')
-         self.assertEqual(str(ir.LiteralStructType((int1,))), '{i1}')
-         self.assertEqual(str(ir.LiteralStructType((int1, flt))), '{i1, float}')
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(ir.LiteralStructType((
-                 ir.PointerType(int1), ir.LiteralStructType((int32, int8))))),
-                 '{ptr, {i32, i8}}')
-@@ -2751,8 +2725,7 @@ def test_gep(self):
-         tp = ir.LiteralStructType((flt, int1))
-         gv = ir.GlobalVariable(m, tp, "myconstant")
-         c = gv.gep([ir.Constant(int32, x) for x in (0, 1)])
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c),
-                              'getelementptr ({float, i1}, ptr @"myconstant", i32 0, i32 1)')  # noqa E501
-         else:
-@@ -2766,8 +2739,7 @@ def test_gep(self):
- 
-         const_ptr = ir.Constant(tp.as_pointer(), None)
-         c2 = const_ptr.gep([ir.Constant(int32, 0)])
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c2),
-                              'getelementptr ({float, i1}, ptr null, i32 0)')  # noqa E501
-         else:
-@@ -2784,8 +2756,7 @@ def test_gep_addrspace_globalvar(self):
-         self.assertEqual(gv.addrspace, addrspace)
-         c = gv.gep([ir.Constant(int32, x) for x in (0, 1)])
-         self.assertEqual(c.type.addrspace, addrspace)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c),
-                              ('getelementptr ({float, i1}, ptr '
-                               'addrspace(4) @"myconstant", i32 0, i32 1)'))
-@@ -2819,8 +2790,7 @@ def test_bitcast(self):
-         m = self.module()
-         gv = ir.GlobalVariable(m, int32, "myconstant")
-         c = gv.bitcast(int64.as_pointer())
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c), 'bitcast (ptr @"myconstant" to ptr)')
-         else:
-             self.assertEqual(str(c), 'bitcast (i32* @"myconstant" to i64*)')
-@@ -2848,8 +2818,7 @@ def test_ptrtoint_1(self):
- 
-         self.assertRaises(TypeError, one.ptrtoint, int64)
-         self.assertRaises(TypeError, ptr.ptrtoint, flt)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c), 'ptrtoint (ptr null to i32)')
-         else:
-             self.assertEqual(str(c), 'ptrtoint (i64* null to i32)')
-@@ -2858,8 +2827,7 @@ def test_ptrtoint_2(self):
-         m = self.module()
-         gv = ir.GlobalVariable(m, int32, "myconstant")
-         c = gv.ptrtoint(int64)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c), 'ptrtoint (ptr @"myconstant" to i64)')
- 
-             self.assertRaisesRegex(
-@@ -2890,8 +2858,7 @@ def test_inttoptr(self):
- 
-         self.assertRaises(TypeError, one.inttoptr, int64)
-         self.assertRaises(TypeError, pi.inttoptr, int64.as_pointer())
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
-+        if not ir_layer_typed_pointers_enabled:
-             self.assertEqual(str(c), 'inttoptr (i32 1 to ptr)')
-         else:
-             self.assertEqual(str(c), 'inttoptr (i32 1 to i64*)')
-
-From ac40dfabaa06431860192676d5a9e4c986748316 Mon Sep 17 00:00:00 2001
-From: Ricardo Jesus <rjj at nvidia.com>
-Date: Tue, 25 Mar 2025 11:30:00 +0000
-Subject: [PATCH 2/5] Apply #1158
-
----
- llvmlite/ir/types.py      | 11 ++++++-
- llvmlite/tests/test_ir.py | 66 +++++++++++++++++++++++++++++++++++++++
- 2 files changed, 76 insertions(+), 1 deletion(-)
-
-diff --git a/llvmlite/ir/types.py b/llvmlite/ir/types.py
-index 9a6ba0943..0a5f24eac 100644
---- a/llvmlite/ir/types.py
-+++ b/llvmlite/ir/types.py
-@@ -135,9 +135,17 @@ def _to_string(self):
-         else:
-             return "ptr"
- 
-+    def __eq__(self, other):
-+        return (isinstance(other, PointerType) and
-+                self.addrspace == other.addrspace)
-+
-     def __hash__(self):
-         return hash(PointerType)
- 
-+    @property
-+    def intrinsic_name(self):
-+        return 'p%d' % self.addrspace
-+
-     @classmethod
-     def from_llvm(cls, typeref, ir_ctx):
-         """
-@@ -169,7 +177,8 @@ def __eq__(self, other):
-         if isinstance(other, _TypedPointerType):
-             return (self.pointee, self.addrspace) == (other.pointee,
-                                                       other.addrspace)
--        return isinstance(other, PointerType)
-+        return (isinstance(other, PointerType) and
-+                self.addrspace == other.addrspace)
- 
-     def __hash__(self):
-         return hash(_TypedPointerType)
-diff --git a/llvmlite/tests/test_ir.py b/llvmlite/tests/test_ir.py
-index 410b3b235..9b9b4e1e8 100644
---- a/llvmlite/tests/test_ir.py
-+++ b/llvmlite/tests/test_ir.py
-@@ -2389,6 +2389,72 @@ def test_comparisons(self):
-                 self.assertFalse(tp == other, (tp, other))
-                 self.assertTrue(tp != other, (tp, other))
- 
-+    def test_ptr_comparisons(self):
-+        # Create instances of:
-+        #   * Opaque pointers.
-+        #   * Typed pointers of i1's.
-+        #   * Typed pointers of i8's.
-+        # The choice of types for the typed pointers are not consequential -
-+        # they just need to differ. Each pointer class has two instances, one
-+        # in address space 0, another in address space 1.
-+        ptrs = {
-+            'op_a0': ir.PointerType(),
-+            'op_a1': ir.PointerType(addrspace=1),
-+            'tp_i1_a0': ir.PointerType(int1),
-+            'tp_i1_a1': ir.PointerType(int1, addrspace=1),
-+            'tp_i8_a0': ir.PointerType(int8),
-+            'tp_i8_a1': ir.PointerType(int8, addrspace=1),
-+        }
-+
-+        def assert_eq(ptr1, ptr2):
-+            self.assertTrue(ptr1 == ptr2, (ptr1, ptr2))
-+            self.assertTrue(ptr2 == ptr1, (ptr2, ptr1))
-+
-+            self.assertFalse(ptr1 != ptr2, (ptr1, ptr2))
-+            self.assertFalse(ptr2 != ptr1, (ptr2, ptr1))
-+
-+        def assert_ne(ptr1, ptr2):
-+            self.assertFalse(ptr1 == ptr2, (ptr1, ptr2))
-+            self.assertFalse(ptr2 == ptr1, (ptr2, ptr1))
-+
-+            self.assertTrue(ptr1 != ptr2, (ptr1, ptr2))
-+            self.assertTrue(ptr2 != ptr1, (ptr2, ptr1))
-+
-+        for ptr in ptrs.values():
-+            # Compare the pointers against any non-pointer type.
-+            for other in self.assorted_types():
-+                if not isinstance(other, ir.PointerType):
-+                    assert_ne(ptr, other)
-+            # Compare the pointers against themselves.
-+            assert_eq(ptr, ptr)
-+
-+        # Compare the pointers against each other.
-+        # Opaque pointers are always equal, unless their address space differs.
-+        # Typed pointers always differ, unless their pointee type and address
-+        # space match.
-+        assert_ne(ptrs['op_a0'], ptrs['op_a1'])
-+        assert_eq(ptrs['op_a0'], ptrs['tp_i1_a0'])
-+        assert_ne(ptrs['op_a0'], ptrs['tp_i1_a1'])
-+        assert_eq(ptrs['op_a0'], ptrs['tp_i8_a0'])
-+        assert_ne(ptrs['op_a0'], ptrs['tp_i8_a1'])
-+        assert_ne(ptrs['op_a1'], ptrs['tp_i1_a0'])
-+        assert_eq(ptrs['op_a1'], ptrs['tp_i1_a1'])
-+        assert_ne(ptrs['op_a1'], ptrs['tp_i8_a0'])
-+        assert_eq(ptrs['op_a1'], ptrs['tp_i8_a1'])
-+        assert_ne(ptrs['tp_i1_a0'], ptrs['tp_i1_a1'])
-+        assert_ne(ptrs['tp_i1_a0'], ptrs['tp_i8_a0'])
-+        assert_ne(ptrs['tp_i1_a0'], ptrs['tp_i8_a1'])
-+        assert_ne(ptrs['tp_i1_a1'], ptrs['tp_i8_a0'])
-+        assert_ne(ptrs['tp_i1_a1'], ptrs['tp_i8_a1'])
-+        assert_ne(ptrs['tp_i8_a0'], ptrs['tp_i8_a1'])
-+
-+    def test_ptr_intrinsic_name(self):
-+        self.assertEqual(ir.PointerType().intrinsic_name, 'p0')
-+        self.assertEqual(ir.PointerType(addrspace=1).intrinsic_name, 'p1')
-+        # Note: Should this be adjusted based on the pointer mode?
-+        self.assertEqual(ir.PointerType(int1).intrinsic_name, 'p0i1')
-+        self.assertEqual(ir.PointerType(int1, 1).intrinsic_name, 'p1i1')
-+
-     def test_str(self):
-         """
-         Test the string representation of types.
-
-From 4faac9686c0d8eb6df5ad7fb31ee7cfa26a872cf Mon Sep 17 00:00:00 2001
-From: Ricardo Jesus <rjj at nvidia.com>
-Date: Tue, 25 Mar 2025 11:30:25 +0000
-Subject: [PATCH 3/5] Apply #1160
-
----
- ffi/core.cpp                    | 12 +++----
- ffi/core.h                      |  6 ++--
- ffi/targets.cpp                 | 20 ------------
- ffi/type.cpp                    | 17 +---------
- llvmlite/__init__.py            |  3 --
- llvmlite/binding/context.py     | 12 ++-----
- llvmlite/binding/targets.py     | 38 ----------------------
- llvmlite/binding/typeref.py     |  9 +-----
- llvmlite/ir/types.py            |  4 ++-
- llvmlite/tests/test_binding.py  | 23 ++-----------
- llvmlite/tests/test_ir.py       | 13 +++++---
- llvmlite/tests/test_refprune.py | 57 ++++-----------------------------
- 12 files changed, 32 insertions(+), 182 deletions(-)
-
-diff --git a/ffi/core.cpp b/ffi/core.cpp
-index 9746b7cdf..fbed1a7b7 100644
---- a/ffi/core.cpp
-+++ b/ffi/core.cpp
-@@ -20,19 +20,19 @@ LLVMPY_CreateByteString(const char *buf, size_t len) {
- API_EXPORT(void)
- LLVMPY_DisposeString(const char *msg) { free(const_cast<char *>(msg)); }
- 
--// FIXME: Remove `enableOpaquePointers' once typed pointers are removed.
- API_EXPORT(LLVMContextRef)
--LLVMPY_GetGlobalContext(bool enableOpaquePointers) {
-+LLVMPY_GetGlobalContext() {
-     auto context = LLVMGetGlobalContext();
--    LLVMContextSetOpaquePointers(context, enableOpaquePointers);
-+    // FIXME: Remove with LLVM >= 17.
-+    LLVMContextSetOpaquePointers(context, true);
-     return context;
- }
- 
--// FIXME: Remove `enableOpaquePointers' once typed pointers are removed.
- API_EXPORT(LLVMContextRef)
--LLVMPY_ContextCreate(bool enableOpaquePointers) {
-+LLVMPY_ContextCreate() {
-     LLVMContextRef context = LLVMContextCreate();
--    LLVMContextSetOpaquePointers(context, enableOpaquePointers);
-+    // FIXME: Remove with LLVM >= 17.
-+    LLVMContextSetOpaquePointers(context, true);
-     return context;
- }
- 
-diff --git a/ffi/core.h b/ffi/core.h
-index 73d799fc6..2d54d4453 100644
---- a/ffi/core.h
-+++ b/ffi/core.h
-@@ -31,13 +31,11 @@ LLVMPY_CreateByteString(const char *buf, size_t len);
- API_EXPORT(void)
- LLVMPY_DisposeString(const char *msg);
- 
--// FIXME: Remove `enableOpaquePointers' once typed pointers are removed.
- API_EXPORT(LLVMContextRef)
--LLVMPY_GetGlobalContext(bool enableOpaquePointers);
-+LLVMPY_GetGlobalContext();
- 
--// FIXME: Remove `enableOpaquePointers' once typed pointers are removed.
- API_EXPORT(LLVMContextRef)
--LLVMPY_ContextCreate(bool enableOpaquePointers);
-+LLVMPY_ContextCreate();
- 
- } /* end extern "C" */
- 
-diff --git a/ffi/targets.cpp b/ffi/targets.cpp
-index 6f75726c6..36b920adb 100644
---- a/ffi/targets.cpp
-+++ b/ffi/targets.cpp
-@@ -121,26 +121,6 @@ LLVMPY_ABIAlignmentOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
-     return (long long)LLVMABIAlignmentOfType(TD, Ty);
- }
- 
--// FIXME: Remove me once typed pointers are no longer supported.
--API_EXPORT(long long)
--LLVMPY_ABISizeOfElementType(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
--    llvm::Type *tp = llvm::unwrap(Ty);
--    if (!tp->isPointerTy())
--        return -1;
--    tp = tp->getPointerElementType();
--    return (long long)LLVMABISizeOfType(TD, llvm::wrap(tp));
--}
--
--// FIXME: Remove me once typed pointers are no longer supported.
--API_EXPORT(long long)
--LLVMPY_ABIAlignmentOfElementType(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
--    llvm::Type *tp = llvm::unwrap(Ty);
--    if (!tp->isPointerTy())
--        return -1;
--    tp = tp->getPointerElementType();
--    return (long long)LLVMABIAlignmentOfType(TD, llvm::wrap(tp));
--}
--
- API_EXPORT(LLVMTargetRef)
- LLVMPY_GetTargetFromTriple(const char *Triple, const char **ErrOut) {
-     char *ErrorMessage;
-diff --git a/ffi/type.cpp b/ffi/type.cpp
-index 235719913..031c199e9 100644
---- a/ffi/type.cpp
-+++ b/ffi/type.cpp
-@@ -144,22 +144,7 @@ API_EXPORT(uint64_t)
- LLVMPY_GetTypeBitWidth(LLVMTypeRef type) {
-     llvm::Type *unwrapped = llvm::unwrap(type);
-     auto size = unwrapped->getPrimitiveSizeInBits();
--    return size.getFixedSize();
--}
--
--// FIXME: Remove me once typed pointers support is removed.
--API_EXPORT(LLVMTypeRef)
--LLVMPY_GetElementType(LLVMTypeRef type) {
--    llvm::Type *unwrapped = llvm::unwrap(type);
--    llvm::PointerType *ty = llvm::dyn_cast<llvm::PointerType>(unwrapped);
--    if (ty != nullptr) {
--#if LLVM_VERSION_MAJOR < 14
--        return llvm::wrap(ty->getElementType());
--#else
--        return llvm::wrap(ty->getPointerElementType());
--#endif
--    }
--    return nullptr;
-+    return size.getFixedValue();
- }
- 
- API_EXPORT(LLVMTypeRef)
-diff --git a/llvmlite/__init__.py b/llvmlite/__init__.py
-index d53654370..e1d8c35a4 100644
---- a/llvmlite/__init__.py
-+++ b/llvmlite/__init__.py
-@@ -2,9 +2,6 @@
- __version__ = get_versions()['version']
- del get_versions
- 
--# FIXME: Remove me once typed pointers are no longer supported.
--# Opaque pointers unconditionally required for later LLVM versions
--opaque_pointers_enabled = True
- # We default to IR layer typed pointers being enabled, since they're needed in
- # the most common usage scenarios with later LLVMs.
- def _ir_layer_typed_pointers_enabled():
-diff --git a/llvmlite/binding/context.py b/llvmlite/binding/context.py
-index 192ebd837..85a256dd1 100644
---- a/llvmlite/binding/context.py
-+++ b/llvmlite/binding/context.py
-@@ -1,18 +1,14 @@
- from llvmlite.binding import ffi
- 
--# FIXME: Remove me once typed pointers are no longer supported.
--from llvmlite import opaque_pointers_enabled
--from ctypes import c_bool
--
- 
- def create_context():
-     return ContextRef(
--        ffi.lib.LLVMPY_ContextCreate(opaque_pointers_enabled))
-+        ffi.lib.LLVMPY_ContextCreate())
- 
- 
- def get_global_context():
-     return GlobalContextRef(
--        ffi.lib.LLVMPY_GetGlobalContext(opaque_pointers_enabled))
-+        ffi.lib.LLVMPY_GetGlobalContext())
- 
- 
- class ContextRef(ffi.ObjectRef):
-@@ -28,12 +24,8 @@ def _dispose(self):
-         pass
- 
- 
--# FIXME: Remove argtypes once typed pointers are no longer supported.
--ffi.lib.LLVMPY_GetGlobalContext.argtypes = [c_bool]
- ffi.lib.LLVMPY_GetGlobalContext.restype = ffi.LLVMContextRef
- 
--# FIXME: Remove argtypes once typed pointers are no longer supported.
--ffi.lib.LLVMPY_ContextCreate.argtypes = [c_bool]
- ffi.lib.LLVMPY_ContextCreate.restype = ffi.LLVMContextRef
- 
- ffi.lib.LLVMPY_ContextDispose.argtypes = [ffi.LLVMContextRef]
-diff --git a/llvmlite/binding/targets.py b/llvmlite/binding/targets.py
-index 8f2d7c317..353eb3b26 100644
---- a/llvmlite/binding/targets.py
-+++ b/llvmlite/binding/targets.py
-@@ -7,10 +7,6 @@
- from llvmlite.binding.common import _decode_string, _encode_string
- from collections import namedtuple
- 
--# FIXME: Remove `opaque_pointers_enabled` once typed pointers are no longer
--# supported.
--from llvmlite import opaque_pointers_enabled
--
- Triple = namedtuple('Triple', ['Arch', 'SubArch', 'Vendor',
-                                'OS', 'Env', 'ObjectFormat'])
- 
-@@ -202,30 +198,6 @@ def get_abi_alignment(self, ty):
-         """
-         return ffi.lib.LLVMPY_ABIAlignmentOfType(self, ty)
- 
--    def get_pointee_abi_size(self, ty):
--        """
--        Get ABI size of pointee type of LLVM pointer type *ty*.
--        """
--        if opaque_pointers_enabled:
--            raise RuntimeError("Cannot get pointee type in opaque pointer "
--                               "mode.")
--        size = ffi.lib.LLVMPY_ABISizeOfElementType(self, ty)
--        if size == -1:
--            raise RuntimeError("Not a pointer type: %s" % (ty,))
--        return size
--
--    def get_pointee_abi_alignment(self, ty):
--        """
--        Get minimum ABI alignment of pointee type of LLVM pointer type *ty*.
--        """
--        if opaque_pointers_enabled:
--            raise RuntimeError("Cannot get pointee type in opaque pointer "
--                               "mode.")
--        size = ffi.lib.LLVMPY_ABIAlignmentOfElementType(self, ty)
--        if size == -1:
--            raise RuntimeError("Not a pointer type: %s" % (ty,))
--        return size
--
- 
- RELOC = frozenset(['default', 'static', 'pic', 'dynamicnopic'])
- CODEMODEL = frozenset(['default', 'jitdefault', 'small', 'kernel', 'medium',
-@@ -440,16 +412,6 @@ def has_svml():
-                                               ffi.LLVMTypeRef]
- ffi.lib.LLVMPY_ABIAlignmentOfType.restype = c_longlong
- 
--# FIXME: Remove me once typed pointers are no longer supported.
--ffi.lib.LLVMPY_ABISizeOfElementType.argtypes = [ffi.LLVMTargetDataRef,
--                                                ffi.LLVMTypeRef]
--ffi.lib.LLVMPY_ABISizeOfElementType.restype = c_longlong
--
--# FIXME: Remove me once typed pointers are no longer supported.
--ffi.lib.LLVMPY_ABIAlignmentOfElementType.argtypes = [ffi.LLVMTargetDataRef,
--                                                     ffi.LLVMTypeRef]
--ffi.lib.LLVMPY_ABIAlignmentOfElementType.restype = c_longlong
--
- ffi.lib.LLVMPY_GetTargetFromTriple.argtypes = [c_char_p, POINTER(c_char_p)]
- ffi.lib.LLVMPY_GetTargetFromTriple.restype = ffi.LLVMTargetRef
- 
-diff --git a/llvmlite/binding/typeref.py b/llvmlite/binding/typeref.py
-index 7f93599db..f34baff94 100644
---- a/llvmlite/binding/typeref.py
-+++ b/llvmlite/binding/typeref.py
-@@ -4,9 +4,6 @@
- from llvmlite import ir
- from llvmlite.binding import ffi
- 
--# FIXME: Remove `opaque_pointers_enabled' when TP's are removed.
--from llvmlite import opaque_pointers_enabled
--
- 
- class TypeKind(enum.IntEnum):
-     # The LLVMTypeKind enum from llvm-c/Core.h
-@@ -108,7 +105,7 @@ def elements(self):
-         """
-         Returns iterator over enclosing types
-         """
--        if self.is_pointer and opaque_pointers_enabled:
-+        if self.is_pointer:
-             raise ValueError("Type {} doesn't contain elements.".format(self))
-         return _TypeListIterator(ffi.lib.LLVMPY_ElementIter(self))
- 
-@@ -226,10 +223,6 @@ def _next(self):
- ffi.lib.LLVMPY_PrintType.argtypes = [ffi.LLVMTypeRef]
- ffi.lib.LLVMPY_PrintType.restype = c_void_p
- 
--# FIXME: Remove me once typed pointers support is removed.
--ffi.lib.LLVMPY_GetElementType.argtypes = [ffi.LLVMTypeRef]
--ffi.lib.LLVMPY_GetElementType.restype = ffi.LLVMTypeRef
--
- ffi.lib.LLVMPY_TypeIsPointer.argtypes = [ffi.LLVMTypeRef]
- ffi.lib.LLVMPY_TypeIsPointer.restype = c_bool
- 
-diff --git a/llvmlite/ir/types.py b/llvmlite/ir/types.py
-index 0a5f24eac..abf5e9a1b 100644
---- a/llvmlite/ir/types.py
-+++ b/llvmlite/ir/types.py
-@@ -193,7 +193,9 @@ def gep(self, i):
- 
-     @property
-     def intrinsic_name(self):
--        return 'p%d%s' % (self.addrspace, self.pointee.intrinsic_name)
-+        if ir_layer_typed_pointers_enabled:
-+            return 'p%d%s' % (self.addrspace, self.pointee.intrinsic_name)
-+        return super(_TypedPointerType, self).intrinsic_name
- 
- 
- class VoidType(Type):
-diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py
-index a6b01ab86..7a43a80fe 100644
---- a/llvmlite/tests/test_binding.py
-+++ b/llvmlite/tests/test_binding.py
-@@ -18,9 +18,6 @@
- from llvmlite.binding import ffi
- from llvmlite.tests import TestCase
- 
--# FIXME: Remove me once typed pointers are no longer supported.
--from llvmlite import opaque_pointers_enabled
--
- # arvm7l needs extra ABI symbols to link successfully
- if platform.machine() == 'armv7l':
-     llvm.load_library_permanently('libgcc_s.so.1')
-@@ -1647,12 +1644,7 @@ def test_type_printing_struct(self):
-         mod = self.module()
-         st = mod.get_global_variable("glob_struct")
-         self.assertTrue(st.type.is_pointer)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIsNotNone(re.match(r'ptr', str(st.type)))
--        else:
--            self.assertIsNotNone(re.match(r'%struct\.glob_type(\.[\d]+)?\*',
--                                          str(st.type)))
-+        self.assertIsNotNone(re.match(r'ptr', str(st.type)))
-         self.assertIsNotNone(re.match(
-             r"%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }",
-             str(st.global_value_type)))
-@@ -1841,11 +1833,7 @@ def test_constant_as_string(self):
-         inst = list(list(func.blocks)[0].instructions)[0]
-         arg = list(inst.operands)[0]
-         self.assertTrue(arg.is_constant)
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertEqual(arg.get_constant_value(), 'ptr null')
--        else:
--            self.assertEqual(arg.get_constant_value(), 'i64* null')
-+        self.assertEqual(arg.get_constant_value(), 'ptr null')
- 
-     def test_incoming_phi_blocks(self):
-         mod = self.module(asm_phi_blocks)
-@@ -1950,12 +1938,7 @@ def test_vararg_function(self):
-         self.assertTrue(func.type.is_pointer)
-         with self.assertRaises(ValueError) as raises:
-             func.type.is_function_vararg
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIn("Type ptr is not a function", str(raises.exception))
--        else:
--            self.assertIn("Type i32 (i32, i32)* is not a function",
--                          str(raises.exception))
-+        self.assertIn("Type ptr is not a function", str(raises.exception))
- 
-     def test_function_typeref_as_ir(self):
-         mod = self.module()
-diff --git a/llvmlite/tests/test_ir.py b/llvmlite/tests/test_ir.py
-index 9b9b4e1e8..165ba4de5 100644
---- a/llvmlite/tests/test_ir.py
-+++ b/llvmlite/tests/test_ir.py
-@@ -281,9 +281,9 @@ def test_declare_intrinsics(self):
-             declare double @"llvm.powi.f64"(double %".1", i32 %".2")""")
-         if not ir_layer_typed_pointers_enabled:
-             self.check_descr(self.descr(memset).strip(), """\
--                declare void @"llvm.memset.p0i8.i32"(ptr %".1", i8 %".2", i32 %".3", i1 %".4")""")  # noqa E501
-+                declare void @"llvm.memset.p0.i32"(ptr %".1", i8 %".2", i32 %".3", i1 %".4")""")  # noqa E501
-             self.check_descr(self.descr(memcpy).strip(), """\
--                declare void @"llvm.memcpy.p0i8.p0i8.i32"(ptr %".1", ptr %".2", i32 %".3", i1 %".4")""")  # noqa E501
-+                declare void @"llvm.memcpy.p0.p0.i32"(ptr %".1", ptr %".2", i32 %".3", i1 %".4")""")  # noqa E501
-         else:
-             self.check_descr(self.descr(memset).strip(), """\
-                 declare void @"llvm.memset.p0i8.i32"(i8* %".1", i8 %".2", i32 %".3", i1 %".4")""")  # noqa E501
-@@ -2451,9 +2451,12 @@ def assert_ne(ptr1, ptr2):
-     def test_ptr_intrinsic_name(self):
-         self.assertEqual(ir.PointerType().intrinsic_name, 'p0')
-         self.assertEqual(ir.PointerType(addrspace=1).intrinsic_name, 'p1')
--        # Note: Should this be adjusted based on the pointer mode?
--        self.assertEqual(ir.PointerType(int1).intrinsic_name, 'p0i1')
--        self.assertEqual(ir.PointerType(int1, 1).intrinsic_name, 'p1i1')
-+        if not ir_layer_typed_pointers_enabled:
-+            self.assertEqual(ir.PointerType(int1).intrinsic_name, 'p0')
-+            self.assertEqual(ir.PointerType(int1, 1).intrinsic_name, 'p1')
-+        else:
-+            self.assertEqual(ir.PointerType(int1).intrinsic_name, 'p0i1')
-+            self.assertEqual(ir.PointerType(int1, 1).intrinsic_name, 'p1i1')
- 
-     def test_str(self):
-         """
-diff --git a/llvmlite/tests/test_refprune.py b/llvmlite/tests/test_refprune.py
-index 299852001..ab82c74cd 100644
---- a/llvmlite/tests/test_refprune.py
-+++ b/llvmlite/tests/test_refprune.py
-@@ -7,9 +7,6 @@
- 
- # TODO:: Get rid of Legacy tests once completely transitioned to NewPassManager
- 
--# FIXME: Remove me once typed pointers are no longer supported.
--from llvmlite import opaque_pointers_enabled
--
- 
- def _iterate_cases(generate_test):
-     def wrap(fn):
-@@ -259,21 +256,13 @@ def test_per_bb_2(self):
-         mod, stats = self.check(self.per_bb_ir_2)
-         self.assertEqual(stats.basicblock, 4)
-         # not pruned
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIn("call void @NRT_incref(ptr %ptr)", str(mod))
--        else:
--            self.assertIn("call void @NRT_incref(i8* %ptr)", str(mod))
-+        self.assertIn("call void @NRT_incref(ptr %ptr)", str(mod))
- 
-     def test_per_bb_2_legacy(self):
-         mod, stats = self.check_legacy(self.per_bb_ir_2)
-         self.assertEqual(stats.basicblock, 4)
-         # not pruned
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIn("call void @NRT_incref(ptr %ptr)", str(mod))
--        else:
--            self.assertIn("call void @NRT_incref(i8* %ptr)", str(mod))
-+        self.assertIn("call void @NRT_incref(ptr %ptr)", str(mod))
- 
-     per_bb_ir_3 = r"""
- define void @main(ptr %ptr, ptr %other) {
-@@ -283,35 +272,19 @@ def test_per_bb_2_legacy(self):
-     call void @NRT_decref(ptr %other)
-     ret void
- }
--""" if opaque_pointers_enabled else r"""
--define void @main(i8* %ptr, i8* %other) {
--    call void @NRT_incref(i8* %ptr)
--    call void @NRT_incref(i8* %ptr)
--    call void @NRT_decref(i8* %ptr)
--    call void @NRT_decref(i8* %other)
--    ret void
--}
- """
- 
-     def test_per_bb_3(self):
-         mod, stats = self.check(self.per_bb_ir_3)
-         self.assertEqual(stats.basicblock, 2)
-         # not pruned
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
--        else:
--            self.assertIn("call void @NRT_decref(i8* %other)", str(mod))
-+        self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
- 
-     def test_per_bb_3_legacy(self):
-         mod, stats = self.check_legacy(self.per_bb_ir_3)
-         self.assertEqual(stats.basicblock, 2)
-         # not pruned
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
--        else:
--            self.assertIn("call void @NRT_decref(i8* %other)", str(mod))
-+        self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
- 
-     per_bb_ir_4 = r"""
- ; reordered
-@@ -323,37 +296,19 @@ def test_per_bb_3_legacy(self):
-     call void @NRT_incref(ptr %ptr)
-     ret void
- }
--""" if opaque_pointers_enabled else r"""
--; reordered
--define void @main(i8* %ptr, i8* %other) {
--    call void @NRT_incref(i8* %ptr)
--    call void @NRT_decref(i8* %ptr)
--    call void @NRT_decref(i8* %ptr)
--    call void @NRT_decref(i8* %other)
--    call void @NRT_incref(i8* %ptr)
--    ret void
--}
- """
- 
-     def test_per_bb_4(self):
-         mod, stats = self.check(self.per_bb_ir_4)
-         self.assertEqual(stats.basicblock, 4)
-         # not pruned
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
--        else:
--            self.assertIn("call void @NRT_decref(i8* %other)", str(mod))
-+        self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
- 
-     def test_per_bb_4_legacy(self):
-         mod, stats = self.check_legacy(self.per_bb_ir_4)
-         self.assertEqual(stats.basicblock, 4)
-         # not pruned
--        # FIXME: Remove `else' once TP are no longer supported.
--        if opaque_pointers_enabled:
--            self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
--        else:
--            self.assertIn("call void @NRT_decref(i8* %other)", str(mod))
-+        self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
- 
- 
- class TestDiamond(BaseTestByIR):
-
-From 3b6fb0d00a0486c65dddc13bd49271f017385c07 Mon Sep 17 00:00:00 2001
-From: Yashwant Singh <yashwants at nvidia.com>
-Date: Tue, 25 Mar 2025 21:26:43 -0700
-Subject: [PATCH 4/5] Apply #1163
-
----
- .../binding/optimization-passes.rst           |  8 +++
- .../user-guide/binding/pass_timings.rst       | 12 ++++
- ffi/newpassmanagers.cpp                       | 54 +++++++++++++--
- llvmlite/binding/ffi.py                       |  2 +-
- llvmlite/binding/newpassmanagers.py           | 65 ++++++++++++++++++-
- llvmlite/tests/test_binding.py                | 50 ++++++++++++++
- 6 files changed, 180 insertions(+), 11 deletions(-)
-
-diff --git a/docs/source/user-guide/binding/optimization-passes.rst b/docs/source/user-guide/binding/optimization-passes.rst
-index a0a6f5eaa..9da332c89 100644
---- a/docs/source/user-guide/binding/optimization-passes.rst
-+++ b/docs/source/user-guide/binding/optimization-passes.rst
-@@ -88,6 +88,14 @@ and module pass managers:
-       Return a populated :class:`FunctionPassManager` object based on PTO
-       settings.
- 
-+   .. method:: start_pass_timing()
-+
-+      Enable the pass timers.
-+
-+   .. method:: finish_pass_timing()
-+
-+      Returns a string containing the LLVM-generated timing report and disables
-+      the pass timers.
- 
- The :class:`ModulePassManager` and :class:`FunctionPassManager` classes
- implement the module and function pass managers:
-diff --git a/docs/source/user-guide/binding/pass_timings.rst b/docs/source/user-guide/binding/pass_timings.rst
-index 4b70de9f9..a64292d23 100644
---- a/docs/source/user-guide/binding/pass_timings.rst
-+++ b/docs/source/user-guide/binding/pass_timings.rst
-@@ -4,6 +4,18 @@ Pass Timings
- 
- .. currentmodule:: llvmlite.binding
- 
-+LLVM provides functionality to time optimization and analysis passes.
-+
-+New Pass Manager APIs
-+=====================
-+
-+See :meth:`PassBuilder.start_pass_timing` and
-+:meth:`PassBuilder.finish_pass_timing` in :doc:`optimization-passes`.
-+
-+Legacy Pass Manager APIs
-+========================
-+
-+
- .. function:: set_time_passes(enable)
- 
-     Enable or disable the pass timers.
-diff --git a/ffi/newpassmanagers.cpp b/ffi/newpassmanagers.cpp
-index 3643bac46..c5819e851 100644
---- a/ffi/newpassmanagers.cpp
-+++ b/ffi/newpassmanagers.cpp
-@@ -37,6 +37,10 @@ typedef OpaquePipelineTuningOptions *LLVMPipelineTuningOptionsRef;
- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PipelineTuningOptions,
-                                    LLVMPipelineTuningOptionsRef)
- 
-+struct OpaqueTimePassesHandler;
-+typedef OpaqueTimePassesHandler *LLVMTimePassesHandlerRef;
-+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TimePassesHandler, LLVMTimePassesHandlerRef)
-+
- static TargetMachine *unwrap(LLVMTargetMachineRef P) {
-     return reinterpret_cast<TargetMachine *>(P);
- }
-@@ -281,21 +285,57 @@ LLVMPY_DisposePipelineTuningOptions(LLVMPipelineTuningOptionsRef PTO) {
- 
- // PB
- 
-+API_EXPORT(LLVMTimePassesHandlerRef)
-+LLVMPY_CreateTimePassesHandler() {
-+    bool enabled = true;
-+    return llvm::wrap(new TimePassesHandler(enabled));
-+}
-+
-+API_EXPORT(void)
-+LLVMPY_DisposeTimePassesHandler(LLVMTimePassesHandlerRef TimePassesRef) {
-+    delete llvm::unwrap(TimePassesRef);
-+}
-+
-+API_EXPORT(void)
-+LLVMPY_EnableTimePasses(LLVMPassBuilderRef PBRef,
-+                        LLVMTimePassesHandlerRef TimePassesRef) {
-+    TimePassesHandler *TP = llvm::unwrap(TimePassesRef);
-+    TimePassesIsEnabled = true;
-+    PassBuilder *PB = llvm::unwrap(PBRef);
-+    PassInstrumentationCallbacks *PIC = PB->getPassInstrumentationCallbacks();
-+    TP->registerCallbacks(*PIC);
-+}
-+
-+API_EXPORT(void)
-+LLVMPY_ReportAndDisableTimePasses(LLVMTimePassesHandlerRef TimePassesRef,
-+                                  const char **outmsg) {
-+    std::string osbuf;
-+    raw_string_ostream os(osbuf);
-+    TimePassesHandler *TP = llvm::unwrap(TimePassesRef);
-+    TP->setOutStream(os);
-+    TP->print();
-+    os.flush();
-+    *outmsg = LLVMPY_CreateString(os.str().c_str());
-+    TimePassesIsEnabled = false;
-+}
-+
- API_EXPORT(LLVMPassBuilderRef)
--LLVMPY_CreatePassBuilder(LLVMTargetMachineRef TM,
--                         LLVMPipelineTuningOptionsRef PTO) {
--    TargetMachine *target = llvm::unwrap(TM);
--    PipelineTuningOptions *pt = llvm::unwrap(PTO);
-+LLVMPY_CreatePassBuilder(LLVMTargetMachineRef TMRef,
-+                         LLVMPipelineTuningOptionsRef PTORef) {
-+    TargetMachine *TM = llvm::unwrap(TMRef);
-+    PipelineTuningOptions *PTO = llvm::unwrap(PTORef);
-     PassInstrumentationCallbacks *PIC = new PassInstrumentationCallbacks();
- #if LLVM_VERSION_MAJOR < 16
--    return llvm::wrap(new PassBuilder(target, *pt, None, PIC));
-+    return llvm::wrap(new PassBuilder(TM, *PTO, None, PIC));
- #else
--    return llvm::wrap(new PassBuilder(target, *pt, std::nullopt, PIC));
-+    return llvm::wrap(new PassBuilder(TM, *PTO, std::nullopt, PIC));
- #endif
- }
- 
- API_EXPORT(void)
--LLVMPY_DisposePassBuilder(LLVMPassBuilderRef PB) { delete llvm::unwrap(PB); }
-+LLVMPY_DisposePassBuilder(LLVMPassBuilderRef PBRef) {
-+    delete llvm::unwrap(PBRef);
-+}
- 
- static OptimizationLevel mapLevel(int speed_level, int size_level) {
-     switch (size_level) {
-diff --git a/llvmlite/binding/ffi.py b/llvmlite/binding/ffi.py
-index 3464cb9c7..a0008ae44 100644
---- a/llvmlite/binding/ffi.py
-+++ b/llvmlite/binding/ffi.py
-@@ -40,7 +40,7 @@ def _make_opaque_ref(name):
- LLVMSectionIteratorRef = _make_opaque_ref("LLVMSectionIterator")
- LLVMOrcLLJITRef = _make_opaque_ref("LLVMOrcLLJITRef")
- LLVMOrcDylibTrackerRef = _make_opaque_ref("LLVMOrcDylibTrackerRef")
--
-+LLVMTimePassesHandlerRef = _make_opaque_ref("LLVMTimePassesHandler")
- LLVMPipelineTuningOptionsRef = _make_opaque_ref("LLVMPipeLineTuningOptions")
- LLVMModulePassManagerRef = _make_opaque_ref("LLVMModulePassManager")
- LLVMFunctionPassManagerRef = _make_opaque_ref("LLVMFunctionPassManager")
-diff --git a/llvmlite/binding/newpassmanagers.py b/llvmlite/binding/newpassmanagers.py
-index c7082965e..1f886924c 100644
---- a/llvmlite/binding/newpassmanagers.py
-+++ b/llvmlite/binding/newpassmanagers.py
-@@ -1,4 +1,4 @@
--from ctypes import c_bool, c_int, c_size_t
-+from ctypes import c_bool, c_int, c_size_t, c_char_p, POINTER
- from enum import IntFlag
- from llvmlite.binding import ffi
- 
-@@ -208,12 +208,21 @@ def _dispose(self):
-         ffi.lib.LLVMPY_DisposePipelineTuningOptions(self)
- 
- 
-+class TimePassesHandler(ffi.ObjectRef):
-+    def __init__(self):
-+        super().__init__(ffi.lib.LLVMPY_CreateTimePassesHandler())
-+
-+    def _dispose(self):
-+        ffi.lib.LLVMPY_DisposeTimePassesHandler(self)
-+
-+
- class PassBuilder(ffi.ObjectRef):
- 
-     def __init__(self, tm, pto):
-         super().__init__(ffi.lib.LLVMPY_CreatePassBuilder(tm, pto))
-         self._pto = pto
-         self._tm = tm
-+        self._time_passes_handler = None
- 
-     def getModulePassManager(self):
-         return ModulePassManager(
-@@ -227,6 +236,38 @@ def getFunctionPassManager(self):
-                 self, self._pto.speed_level, self._pto.size_level)
-         )
- 
-+    def start_pass_timing(self):
-+        """Enable the pass timers.
-+
-+        Raises
-+        ------
-+        RuntimeError
-+            If pass timing is already enabled.
-+        """
-+        if self._time_passes_handler:
-+            raise RuntimeError("Pass timing can only be done once")
-+        self._time_passes_handler = TimePassesHandler()
-+        ffi.lib.LLVMPY_EnableTimePasses(self, self._time_passes_handler)
-+
-+    def finish_pass_timing(self):
-+        """Returns the pass timings report and disables the LLVM internal
-+        timers. Pass timers are enabled by ``start_pass_timing()``. If the
-+        timers are not enabled, this function will return an empty string.
-+
-+        Returns
-+        -------
-+        res : str
-+            LLVM generated timing report.
-+        """
-+
-+        if not self._time_passes_handler:
-+            raise RuntimeError("Pass timing is not enabled")
-+
-+        with ffi.OutputString() as buf:
-+            ffi.lib.LLVMPY_ReportAndDisableTimePasses(
-+                self._time_passes_handler, buf)
-+            return str(buf)
-+
-     def _dispose(self):
-         ffi.lib.LLVMPY_DisposePassBuilder(self)
- 
-@@ -339,11 +380,29 @@ def _dispose(self):
- # PassBuilder
- 
- ffi.lib.LLVMPY_CreatePassBuilder.restype = ffi.LLVMPassBuilderRef
--ffi.lib.LLVMPY_CreatePassBuilder.argtypes = [ffi.LLVMTargetMachineRef,
--                                             ffi.LLVMPipelineTuningOptionsRef,]
-+ffi.lib.LLVMPY_CreatePassBuilder.argtypes = [
-+    ffi.LLVMTargetMachineRef,
-+    ffi.LLVMPipelineTuningOptionsRef,
-+]
- 
- ffi.lib.LLVMPY_DisposePassBuilder.argtypes = [ffi.LLVMPassBuilderRef,]
- 
-+ffi.lib.LLVMPY_CreateTimePassesHandler.restype = \
-+    ffi.LLVMTimePassesHandlerRef
-+
-+ffi.lib.LLVMPY_DisposeTimePassesHandler.argtypes = [
-+    ffi.LLVMTimePassesHandlerRef,]
-+
-+ffi.lib.LLVMPY_EnableTimePasses.argtypes = [
-+    ffi.LLVMPassBuilderRef,
-+    ffi.LLVMTimePassesHandlerRef,
-+]
-+
-+ffi.lib.LLVMPY_ReportAndDisableTimePasses.argtypes = [
-+    ffi.LLVMTimePassesHandlerRef,
-+    POINTER(c_char_p),
-+]
-+
- # Pipeline builders
- 
- ffi.lib.LLVMPY_buildPerModuleDefaultPipeline.restype = \
-diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py
-index 7a43a80fe..a5cf72c08 100644
---- a/llvmlite/tests/test_binding.py
-+++ b/llvmlite/tests/test_binding.py
-@@ -3041,6 +3041,56 @@ def test_get_function_pass_manager(self):
-         fpm.run(self.module().get_function("sum"), pb)
-         pb.close()
- 
-+    def test_time_passes(self):
-+        """Test pass timing reports for O3 and O0 optimization levels"""
-+        def run_with_timing(speed_level):
-+            mod = self.module()
-+            pb = self.pb(speed_level=speed_level, size_level=0)
-+            pb.start_pass_timing()
-+            mpm = pb.getModulePassManager()
-+            mpm.run(mod, pb)
-+            report = pb.finish_pass_timing()
-+            pb.close()
-+            return report
-+
-+        report_O3 = run_with_timing(3)
-+        report_O0 = run_with_timing(0)
-+
-+        self.assertIsInstance(report_O3, str)
-+        self.assertIsInstance(report_O0, str)
-+        self.assertEqual(report_O3.count("Pass execution timing report"), 1)
-+        self.assertEqual(report_O0.count("Pass execution timing report"), 1)
-+
-+    def test_empty_report(self):
-+        mod = self.module()
-+        pb = self.pb()
-+        mpm = pb.getModulePassManager()
-+        mpm.run(mod, pb)
-+        pb.start_pass_timing()
-+        report = pb.finish_pass_timing()
-+        pb.close()
-+        self.assertFalse(report)
-+
-+    def test_multiple_timers_error(self):
-+        mod = self.module()
-+        pb = self.pb()
-+        pb.start_pass_timing()
-+        mpm = pb.getModulePassManager()
-+        mpm.run(mod, pb)
-+        pb.finish_pass_timing()
-+        with self.assertRaisesRegex(RuntimeError, "only be done once"):
-+            pb.start_pass_timing()
-+        pb.close()
-+
-+    def test_empty_report_error(self):
-+        mod = self.module()
-+        pb = self.pb()
-+        mpm = pb.getModulePassManager()
-+        mpm.run(mod, pb)
-+        with self.assertRaisesRegex(RuntimeError, "not enabled"):
-+            pb.finish_pass_timing()
-+        pb.close()
-+
- 
- class TestNewModulePassManager(BaseTest, NewPassManagerMixin):
-     def pm(self):
-
-From b910270a94922d325a3be62d7488ecf8adfd25e9 Mon Sep 17 00:00:00 2001
-From: Yashwant Singh <yashwants at nvidia.com>
-Date: Tue, 25 Mar 2025 22:16:53 -0700
-Subject: [PATCH 5/5] Apply #1092
-
----
- docs/source/user-guide/examples/ll_fpadd.py |   1 -
- docs/source/user-guide/examples/parseasm.py |   1 -
- docs/source/user-guide/examples/sum.py      |   1 -
- examples/ll_fpadd.py                        |   1 -
- examples/lljit.py                           |   1 -
- examples/npm_passes.py                      |   1 -
- examples/npm_pipeline.py                    |   1 -
- examples/opaque_pointers/sum.py             |   1 -
- examples/parseasm.py                        |   1 -
- examples/printer-passes-npm.py              |  88 ++
- examples/sum.py                             |   1 -
- ffi/CMakeLists.txt                          |   4 +-
- ffi/Makefile.freebsd                        |   2 +-
- ffi/Makefile.linux                          |   2 +-
- ffi/Makefile.osx                            |   2 +-
- ffi/PASSREGISTRY.def                        | 286 ++++++
- ffi/build.py                                |  11 +-
- ffi/core.cpp                                |   4 -
- ffi/custom_passes.cpp                       |  88 +-
- ffi/initfini.cpp                            |  24 +-
- ffi/memorymanager.cpp                       |   4 -
- ffi/memorymanager.h                         |   5 -
- ffi/newpassmanagers.cpp                     | 384 ++++++--
- ffi/orcjit.cpp                              |   9 +-
- ffi/passmanagers.cpp                        | 467 ----------
- ffi/targets.cpp                             |  25 +-
- ffi/transforms.cpp                          |  96 --
- ffi/value.cpp                               |   1 +
- llvmlite/binding/__init__.py                |   2 -
- llvmlite/binding/initfini.py                |   7 -
- llvmlite/binding/newpassmanagers.py         | 748 ++++++++++++++--
- llvmlite/binding/passmanagers.py            | 946 --------------------
- llvmlite/binding/targets.py                 |  33 +-
- llvmlite/binding/transforms.py              | 151 ----
- llvmlite/binding/typeref.py                 |  11 -
- llvmlite/tests/refprune_proto.py            |   1 +
- llvmlite/tests/test_binding.py              | 526 +++--------
- llvmlite/tests/test_refprune.py             | 124 +--
- 38 files changed, 1537 insertions(+), 2524 deletions(-)
- create mode 100644 examples/printer-passes-npm.py
- create mode 100644 ffi/PASSREGISTRY.def
- delete mode 100644 ffi/passmanagers.cpp
- delete mode 100644 ffi/transforms.cpp
- delete mode 100644 llvmlite/binding/passmanagers.py
- delete mode 100644 llvmlite/binding/transforms.py
-
-diff --git a/docs/source/user-guide/examples/ll_fpadd.py b/docs/source/user-guide/examples/ll_fpadd.py
-index 6a97ae43f..fc1e004ee 100644
---- a/docs/source/user-guide/examples/ll_fpadd.py
-+++ b/docs/source/user-guide/examples/ll_fpadd.py
-@@ -6,7 +6,6 @@
- 
- 
- # All these initializations are required for code generation!
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()  # yes, even this one
- 
-diff --git a/docs/source/user-guide/examples/parseasm.py b/docs/source/user-guide/examples/parseasm.py
-index 78e4a2d43..7d24e9468 100644
---- a/docs/source/user-guide/examples/parseasm.py
-+++ b/docs/source/user-guide/examples/parseasm.py
-@@ -1,7 +1,6 @@
- from llvmlite import binding as llvm
- from llvmlite import ir as lc
- 
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()
- 
-diff --git a/docs/source/user-guide/examples/sum.py b/docs/source/user-guide/examples/sum.py
-index 4f7ddb66f..fdd996fe4 100644
---- a/docs/source/user-guide/examples/sum.py
-+++ b/docs/source/user-guide/examples/sum.py
-@@ -18,7 +18,6 @@
- import llvmlite.binding as llvm
- 
- 
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()
- 
-diff --git a/examples/ll_fpadd.py b/examples/ll_fpadd.py
-index 7d5854c88..91f718448 100644
---- a/examples/ll_fpadd.py
-+++ b/examples/ll_fpadd.py
-@@ -6,7 +6,6 @@
- 
- 
- # All these initializations are required for code generation!
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()  # yes, even this one
- 
-diff --git a/examples/lljit.py b/examples/lljit.py
-index 3a3a63d1f..e19a99359 100644
---- a/examples/lljit.py
-+++ b/examples/lljit.py
-@@ -10,7 +10,6 @@
- import llvmlite.binding as llvm
- import numpy as np
- 
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()  # yes, even this one
- 
-diff --git a/examples/npm_passes.py b/examples/npm_passes.py
-index 44dec9148..d10b0e4e2 100644
---- a/examples/npm_passes.py
-+++ b/examples/npm_passes.py
-@@ -10,7 +10,6 @@
- faulthandler.enable()
- 
- # All are required to initialize LLVM
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()
- 
-diff --git a/examples/npm_pipeline.py b/examples/npm_pipeline.py
-index 6cd12e52b..9d7a4fed7 100644
---- a/examples/npm_pipeline.py
-+++ b/examples/npm_pipeline.py
-@@ -15,7 +15,6 @@
- faulthandler.enable()
- 
- # All are required to initialize LLVM
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()
- 
-diff --git a/examples/opaque_pointers/sum.py b/examples/opaque_pointers/sum.py
-index 421c0be71..2a09ad981 100644
---- a/examples/opaque_pointers/sum.py
-+++ b/examples/opaque_pointers/sum.py
-@@ -21,7 +21,6 @@
- import llvmlite.binding as llvm
- 
- 
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()
- 
-diff --git a/examples/parseasm.py b/examples/parseasm.py
-index 78e4a2d43..7d24e9468 100644
---- a/examples/parseasm.py
-+++ b/examples/parseasm.py
-@@ -1,7 +1,6 @@
- from llvmlite import binding as llvm
- from llvmlite import ir as lc
- 
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()
- 
-diff --git a/examples/printer-passes-npm.py b/examples/printer-passes-npm.py
-new file mode 100644
-index 000000000..6f9c14e09
---- /dev/null
-+++ b/examples/printer-passes-npm.py
-@@ -0,0 +1,88 @@
-+try:
-+    import faulthandler; faulthandler.enable()
-+except ImportError:
-+    pass
-+
-+import llvmlite.ir as ll
-+import llvmlite.binding as llvm
-+
-+
-+llvm.initialize()
-+llvm.initialize_native_target()
-+llvm.initialize_native_asmprinter()
-+
-+strmod = """
-+define i32 @foo3(i32* noalias nocapture readonly %src) {
-+entry:
-+  br label %loop.header
-+
-+loop.header:
-+  %iv = phi i64 [ 0, %entry ], [ %inc, %loop.latch ]
-+  %r1  = phi i32 [ 0, %entry ], [ %r3, %loop.latch ]
-+  %arrayidx = getelementptr inbounds i32, i32* %src, i64 %iv
-+  %src_element = load i32, i32* %arrayidx, align 4
-+  %cmp = icmp eq i32 0, %src_element
-+  br i1 %cmp, label %loop.if, label %loop.latch
-+
-+loop.if:
-+  %r2 = add i32 %r1, 1
-+  br label %loop.latch
-+loop.latch:
-+  %r3 = phi i32 [%r1, %loop.header], [%r2, %loop.if]
-+  %inc = add nuw nsw i64 %iv, 1
-+  %exitcond = icmp eq i64 %inc, 9
-+  br i1 %exitcond, label %loop.end, label %loop.header
-+loop.end:
-+  %r.lcssa = phi i32 [ %r3, %loop.latch ]
-+  ret i32 %r.lcssa
-+}
-+"""
-+
-+dbgmodstr = """
-+define void @f() !dbg !4 {
-+  ret void, !dbg !15
-+}
-+
-+!llvm.dbg.cu = !{!0, !8}
-+!llvm.module.flags = !{!13, !16}
-+
-+!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (192092)", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
-+!1 = !DIFile(filename: "test1.c", directory: "/tmp")
-+!2 = !{}
-+!4 = distinct !DISubprogram(name: "f", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !5, type: !6, retainedNodes: !2)
-+!5 = !DIFile(filename: "test1.c", directory: "/tmp")
-+!6 = !DISubroutineType(types: !7)
-+!7 = !{null}
-+!8 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (192092)", isOptimized: false, emissionKind: FullDebug, file: !9, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
-+!9 = !DIFile(filename: "test2.c", directory: "/tmp")
-+!11 = distinct !DISubprogram(name: "g", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !8, scopeLine: 1, file: !9, scope: !12, type: !6, retainedNodes: !2)
-+!12 = !DIFile(filename: "test2.c", directory: "/tmp")
-+!13 = !{i32 2, !"Dwarf Version", i32 4}
-+!14 = !DILocation(line: 1, scope: !4)
-+!15 = !DILocation(line: 1, scope: !11, inlinedAt: !14)
-+!16 = !{i32 1, !"Debug Info Version", i32 3}
-+"""
-+
-+
-+llmod = llvm.parse_assembly(strmod)
-+dbgmod = llvm.parse_assembly(dbgmodstr)
-+
-+target_machine = llvm.Target.from_default_triple().create_target_machine()
-+pto = llvm.create_pipeline_tuning_options(speed_level=0)
-+pb = llvm.create_pass_builder(target_machine, pto)
-+pm = llvm.create_new_module_pass_manager()
-+
-+pm.add_module_debug_info_pass()
-+pm.add_cfg_printer_pass()
-+pm.add_cfg_only_printer_pass()
-+pm.add_dom_printer_pass()
-+pm.add_dom_only_printer_pass()
-+pm.add_post_dom_printer_pass()
-+pm.add_post_dom_only_printer_pass()
-+pm.add_dom_only_printer_pass()
-+# pm.add_post_dom_viewer_pass()
-+# pm.add_dom_viewer_pass()
-+# pm.add_post_dom_only_viewer_pass()
-+
-+pm.run(llmod, pb)
-+pm.run(dbgmod, pb)
-diff --git a/examples/sum.py b/examples/sum.py
-index 4f7ddb66f..fdd996fe4 100644
---- a/examples/sum.py
-+++ b/examples/sum.py
-@@ -18,7 +18,6 @@
- import llvmlite.binding as llvm
- 
- 
--llvm.initialize()
- llvm.initialize_native_target()
- llvm.initialize_native_asmprinter()
- 
-diff --git a/ffi/CMakeLists.txt b/ffi/CMakeLists.txt
-index ab8ba04eb..0b2c762cc 100755
---- a/ffi/CMakeLists.txt
-+++ b/ffi/CMakeLists.txt
-@@ -44,8 +44,8 @@ endif()
- 
- # Define our shared library
- add_library(llvmlite SHARED assembly.cpp bitcode.cpp core.cpp initfini.cpp
--            module.cpp value.cpp executionengine.cpp transforms.cpp type.cpp
--            passmanagers.cpp targets.cpp dylib.cpp linker.cpp object_file.cpp
-+            module.cpp value.cpp executionengine.cpp type.cpp
-+            targets.cpp dylib.cpp linker.cpp object_file.cpp
-             custom_passes.cpp orcjit.cpp memorymanager.cpp newpassmanagers.cpp)
- 
- # Find the libraries that correspond to the LLVM components
-diff --git a/ffi/Makefile.freebsd b/ffi/Makefile.freebsd
-index f4a4ad400..66af972e3 100644
---- a/ffi/Makefile.freebsd
-+++ b/ffi/Makefile.freebsd
-@@ -10,7 +10,7 @@ LDFLAGS := $(LDFLAGS) $(LLVM_LDFLAGS) $(LD_FLTO_FLAGS)
- LIBS = $(LLVM_LIBS)
- INCLUDE = core.h
- SRC = assembly.cpp bitcode.cpp core.cpp initfini.cpp module.cpp value.cpp \
--	executionengine.cpp transforms.cpp passmanagers.cpp type.cpp targets.cpp \
-+	executionengine.cpp type.cpp targets.cpp \
- 	dylib.cpp linker.cpp object_file.cpp orcjit.cpp custom_passes.cpp \
- 	memorymanager.cpp newpassmanagers.cpp
- OUTPUT = libllvmlite.so
-diff --git a/ffi/Makefile.linux b/ffi/Makefile.linux
-index 448a920f9..94b2d774e 100644
---- a/ffi/Makefile.linux
-+++ b/ffi/Makefile.linux
-@@ -12,7 +12,7 @@ LDFLAGS := $(LDFLAGS) $(LLVM_LDFLAGS) $(LD_FLTO_FLAGS)
- LIBS = $(LLVM_LIBS)
- INCLUDE = core.h
- OBJ = assembly.o bitcode.o core.o initfini.o module.o value.o \
--	  executionengine.o transforms.o passmanagers.o targets.o type.o dylib.o \
-+	  executionengine.o targets.o type.o dylib.o \
- 	  linker.o object_file.o custom_passes.o orcjit.o memorymanager.o newpassmanagers.o
- OUTPUT = libllvmlite.so
- 
-diff --git a/ffi/Makefile.osx b/ffi/Makefile.osx
-index 321a14a16..21a99629f 100644
---- a/ffi/Makefile.osx
-+++ b/ffi/Makefile.osx
-@@ -7,7 +7,7 @@ LDFLAGS :=  $(LDFLAGS) $(EXPORT) $(LLVM_LDFLAGS)
- LIBS = $(LLVM_LIBS)
- INCLUDE = core.h
- SRC = assembly.cpp bitcode.cpp core.cpp initfini.cpp module.cpp value.cpp \
--	  executionengine.cpp transforms.cpp passmanagers.cpp targets.cpp type.cpp \
-+	  executionengine.cpp targets.cpp type.cpp \
- 	  dylib.cpp linker.cpp object_file.cpp custom_passes.cpp orcjit.cpp \
- 	  memorymanager.cpp newpassmanagers.cpp
- OUTPUT = libllvmlite.dylib
-diff --git a/ffi/PASSREGISTRY.def b/ffi/PASSREGISTRY.def
-new file mode 100644
-index 000000000..cb4f19c0f
---- /dev/null
-+++ b/ffi/PASSREGISTRY.def
-@@ -0,0 +1,286 @@
-+// Use this file to register/de-register llvm optimization passes in llvmlite
-+
-+#ifndef MODULE_PASS
-+#define MODULE_PASS(NAME)
-+#endif
-+MODULE_PASS(VerifierPass)
-+MODULE_PASS(ConstantMergePass)
-+MODULE_PASS(DeadArgumentEliminationPass)
-+MODULE_PASS(CallGraphDOTPrinterPass)
-+MODULE_PASS(AlwaysInlinerPass)
-+MODULE_PASS(ReversePostOrderFunctionAttrsPass)
-+MODULE_PASS(GlobalDCEPass)
-+MODULE_PASS(GlobalOptPass)
-+MODULE_PASS(IPSCCPPass)
-+MODULE_PASS(InternalizePass)
-+MODULE_PASS(MergeFunctionsPass)
-+MODULE_PASS(PartialInlinerPass)
-+MODULE_PASS(StripSymbolsPass)
-+MODULE_PASS(StripDeadDebugInfoPass)
-+MODULE_PASS(StripDeadPrototypesPass)
-+MODULE_PASS(StripDebugDeclarePass)
-+MODULE_PASS(StripNonDebugSymbolsPass)
-+#undef MODULE_PASS
-+
-+#ifndef FUNCTION_PASS
-+#define FUNCTION_PASS(NAME)
-+#endif
-+FUNCTION_PASS(AAEvaluator)
-+FUNCTION_PASS(SimplifyCFGPass)
-+FUNCTION_PASS(LoopUnrollPass)
-+FUNCTION_PASS(InstCombinePass)
-+FUNCTION_PASS(JumpThreadingPass)
-+FUNCTION_PASS(CFGPrinterPass)
-+FUNCTION_PASS(CFGOnlyPrinterPass)
-+FUNCTION_PASS(DomPrinter)
-+FUNCTION_PASS(DomOnlyPrinter)
-+FUNCTION_PASS(PostDomPrinter)
-+FUNCTION_PASS(PostDomOnlyPrinter)
-+FUNCTION_PASS(DomViewer)
-+FUNCTION_PASS(DomOnlyViewer)
-+FUNCTION_PASS(PostDomViewer)
-+FUNCTION_PASS(PostDomOnlyViewer)
-+FUNCTION_PASS(LintPass)
-+FUNCTION_PASS(ADCEPass)
-+FUNCTION_PASS(BreakCriticalEdgesPass)
-+FUNCTION_PASS(DSEPass)
-+FUNCTION_PASS(DCEPass)
-+FUNCTION_PASS(AggressiveInstCombinePass)
-+FUNCTION_PASS(LCSSAPass)
-+FUNCTION_PASS(NewGVNPass)
-+FUNCTION_PASS(LoopSimplifyPass)
-+FUNCTION_PASS(SCCPPass)
-+FUNCTION_PASS(LowerAtomicPass)
-+FUNCTION_PASS(LowerInvokePass)
-+FUNCTION_PASS(LowerSwitchPass)
-+FUNCTION_PASS(MemCpyOptPass)
-+FUNCTION_PASS(UnifyFunctionExitNodesPass)
-+FUNCTION_PASS(ReassociatePass)
-+FUNCTION_PASS(RegToMemPass)
-+// FIXME: FUNCTION_PASS(SROAPass)
-+FUNCTION_PASS(SinkingPass)
-+FUNCTION_PASS(TailCallElimPass)
-+FUNCTION_PASS(InstructionNamerPass)
-+#undef FUNCTION_PASS
-+
-+// TODO: Add them if needed
-+// FUNCTION_PASS_WITH_PARAMS(SimplifyCFGPass)
-+// FUNCTION_PASS_WITH_PARAMS(LoopUnrollPass)
-+
-+#ifndef LOOP_PASS
-+#define LOOP_PASS(NAME)
-+#endif
-+LOOP_PASS(LoopRotatePass)
-+LOOP_PASS(LoopDeletionPass)
-+LOOP_PASS(LoopStrengthReducePass)
-+#undef LOOP_PASS
-+
-+#ifndef CGSCC_PASS
-+#define CGSCC_PASS(NAME)
-+#endif
-+CGSCC_PASS(ArgumentPromotionPass)
-+CGSCC_PASS(PostOrderFunctionAttrsPass)
-+#undef CGSCC_PASS
-+
-+// TODO: Add them if needed
-+/**
-+MODULE_PASS("attributor", AttributorPass())
-+MODULE_PASS("annotation2metadata", Annotation2MetadataPass())
-+MODULE_PASS("openmp-opt", OpenMPOptPass())
-+MODULE_PASS("called-value-propagation", CalledValuePropagationPass())
-+MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass())
-+MODULE_PASS("cg-profile", CGProfilePass())
-+MODULE_PASS("check-debugify", NewPMCheckDebugifyPass())
-+MODULE_PASS("coro-early", CoroEarlyPass())
-+MODULE_PASS("coro-cleanup", CoroCleanupPass())
-+MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
-+MODULE_PASS("debugify", NewPMDebugifyPass())
-+MODULE_PASS("dot-callgraph", CallGraphDOTPrinterPass())
-+MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass())
-+MODULE_PASS("extract-blocks", BlockExtractorPass())
-+MODULE_PASS("forceattrs", ForceFunctionAttrsPass())
-+MODULE_PASS("function-import", FunctionImportPass())
-+MODULE_PASS("function-specialization", FunctionSpecializationPass())
-+MODULE_PASS("globalsplit", GlobalSplitPass())
-+MODULE_PASS("hotcoldsplit", HotColdSplittingPass())
-+MODULE_PASS("inferattrs", InferFunctionAttrsPass())
-+MODULE_PASS("inliner-wrapper", ModuleInlinerWrapperPass())
-+MODULE_PASS("inliner-ml-advisor-release", ModuleInlinerWrapperPass(getInlineParams(), true, {}, InliningAdvisorMode::Release, 0))
-+MODULE_PASS("print<inline-advisor>", InlineAdvisorAnalysisPrinterPass(dbgs()))
-+MODULE_PASS("inliner-wrapper-no-mandatory-first", ModuleInlinerWrapperPass(getInlineParams(),false))
-+MODULE_PASS("insert-gcov-profiling", GCOVProfilerPass())
-+MODULE_PASS("instrorderfile", InstrOrderFilePass())
-+MODULE_PASS("instrprof", InstrProfiling())
-+MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
-+MODULE_PASS("iroutliner", IROutlinerPass())
-+MODULE_PASS("print-ir-similarity", IRSimilarityAnalysisPrinterPass(dbgs()))
-+MODULE_PASS("lower-global-dtors", LowerGlobalDtorsPass())
-+MODULE_PASS("lowertypetests", LowerTypeTestsPass())
-+MODULE_PASS("metarenamer", MetaRenamerPass())
-+MODULE_PASS("name-anon-globals", NameAnonGlobalPass())
-+MODULE_PASS("no-op-module", NoOpModulePass())
-+MODULE_PASS("objc-arc-apelim", ObjCARCAPElimPass())
-+MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion())
-+MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())
-+MODULE_PASS("pgo-instr-use", PGOInstrumentationUse())
-+MODULE_PASS("print-profile-summary", ProfileSummaryPrinterPass(dbgs()))
-+MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
-+MODULE_PASS("print", PrintModulePass(dbgs()))
-+MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
-+MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs()))
-+MODULE_PASS("print-must-be-executed-contexts", MustBeExecutedContextPrinterPass(dbgs()))
-+MODULE_PASS("print-stack-safety", StackSafetyGlobalPrinterPass(dbgs()))
-+MODULE_PASS("print<module-debuginfo>", ModuleDebugInfoPrinterPass(dbgs()))
-+MODULE_PASS("recompute-globalsaa", RecomputeGlobalsAAPass())
-+MODULE_PASS("rel-lookup-table-converter", RelLookupTableConverterPass())
-+MODULE_PASS("rewrite-statepoints-for-gc", RewriteStatepointsForGC())
-+MODULE_PASS("rewrite-symbols", RewriteSymbolPass())
-+MODULE_PASS("sample-profile", SampleProfileLoaderPass())
-+MODULE_PASS("scc-oz-module-inliner",buildInlinerPipeline(OptimizationLevel::Oz, ThinOrFullLTOPhase::None))
-+MODULE_PASS("pseudo-probe", SampleProfileProbePass(TM))
-+MODULE_PASS("strip-nonlinetable-debuginfo", StripNonLineTableDebugInfoPass())
-+MODULE_PASS("synthetic-counts-propagation", SyntheticCountsPropagation())
-+MODULE_PASS("trigger-crash", TriggerCrashPass())
-+MODULE_PASS("verify", VerifierPass())
-+MODULE_PASS("view-callgraph", CallGraphViewerPass())
-+MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass())
-+MODULE_PASS("dfsan", DataFlowSanitizerPass())
-+MODULE_PASS("msan-module", ModuleMemorySanitizerPass({}))
-+MODULE_PASS("module-inline", ModuleInlinerPass())
-+MODULE_PASS("tsan-module", ModuleThreadSanitizerPass())
-+MODULE_PASS("sancov-module", ModuleSanitizerCoveragePass())
-+MODULE_PASS("memprof-module", ModuleMemProfilerPass())
-+MODULE_PASS("poison-checking", PoisonCheckingPass())
-+MODULE_PASS("pseudo-probe-update", PseudoProbeUpdatePass())
-+
-+CGSCC_PASS("argpromotion", ArgumentPromotionPass())
-+CGSCC_PASS("invalidate<all>", InvalidateAllAnalysesPass())
-+CGSCC_PASS("attributor-cgscc", AttributorCGSCCPass())
-+CGSCC_PASS("openmp-opt-cgscc", OpenMPOptCGSCCPass())
-+CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
-+
-+FUNCTION_PASS("add-discriminators", AddDiscriminatorsPass())
-+FUNCTION_PASS("assume-builder", AssumeBuilderPass())
-+FUNCTION_PASS("assume-simplify", AssumeSimplifyPass())
-+FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass())
-+FUNCTION_PASS("annotation-remarks", AnnotationRemarksPass())
-+FUNCTION_PASS("bdce", BDCEPass())
-+FUNCTION_PASS("bounds-checking", BoundsCheckingPass())
-+FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass())
-+FUNCTION_PASS("consthoist", ConstantHoistingPass())
-+FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass())
-+FUNCTION_PASS("chr", ControlHeightReductionPass())
-+FUNCTION_PASS("coro-elide", CoroElidePass())
-+FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass())
-+FUNCTION_PASS("dfa-jump-threading", DFAJumpThreadingPass())
-+FUNCTION_PASS("div-rem-pairs", DivRemPairsPass())
-+FUNCTION_PASS("fix-irreducible", FixIrreduciblePass())
-+FUNCTION_PASS("flattencfg", FlattenCFGPass())
-+FUNCTION_PASS("make-guards-explicit", MakeGuardsExplicitPass())
-+FUNCTION_PASS("gvn-hoist", GVNHoistPass())
-+FUNCTION_PASS("gvn-sink", GVNSinkPass())
-+FUNCTION_PASS("helloworld", HelloWorldPass())
-+FUNCTION_PASS("infer-address-spaces", InferAddressSpacesPass())
-+FUNCTION_PASS("instcombine", InstCombinePass())
-+FUNCTION_PASS("instcount", InstCountPass())
-+FUNCTION_PASS("instsimplify", InstSimplifyPass())
-+FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass())
-+FUNCTION_PASS("irce", IRCEPass())
-+FUNCTION_PASS("float2int", Float2IntPass())
-+FUNCTION_PASS("no-op-function", NoOpFunctionPass())
-+FUNCTION_PASS("libcalls-shrinkwrap", LibCallsShrinkWrapPass())
-+FUNCTION_PASS("inject-tli-mappings", InjectTLIMappings())
-+FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
-+FUNCTION_PASS("lower-guard-intrinsic", LowerGuardIntrinsicPass())
-+FUNCTION_PASS("lower-constant-intrinsics", LowerConstantIntrinsicsPass())
-+FUNCTION_PASS("lower-widenable-condition", LowerWidenableConditionPass())
-+FUNCTION_PASS("guard-widening", GuardWideningPass())
-+FUNCTION_PASS("load-store-vectorizer", LoadStoreVectorizerPass())
-+FUNCTION_PASS("loop-sink", LoopSinkPass())
-+FUNCTION_PASS("mem2reg", PromotePass())
-+FUNCTION_PASS("mergeicmps", MergeICmpsPass())
-+FUNCTION_PASS("nary-reassociate", NaryReassociatePass())
-+FUNCTION_PASS("jump-threading", JumpThreadingPass())
-+FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass())
-+FUNCTION_PASS("loop-data-prefetch", LoopDataPrefetchPass())
-+FUNCTION_PASS("loop-load-elim", LoopLoadEliminationPass())
-+FUNCTION_PASS("loop-fusion", LoopFusePass())
-+FUNCTION_PASS("loop-distribute", LoopDistributePass())
-+FUNCTION_PASS("loop-versioning", LoopVersioningPass())
-+FUNCTION_PASS("objc-arc", ObjCARCOptPass())
-+FUNCTION_PASS("objc-arc-contract", ObjCARCContractPass())
-+FUNCTION_PASS("objc-arc-expand", ObjCARCExpandPass())
-+FUNCTION_PASS("pgo-memop-opt", PGOMemOPSizeOpt())
-+FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
-+FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs()))
-+FUNCTION_PASS("print<block-freq>", BlockFrequencyPrinterPass(dbgs()))
-+FUNCTION_PASS("print<branch-prob>", BranchProbabilityPrinterPass(dbgs()))
-+FUNCTION_PASS("print<cost-model>", CostModelPrinterPass(dbgs()))
-+FUNCTION_PASS("print<cycles>", CycleInfoPrinterPass(dbgs()))
-+FUNCTION_PASS("print<da>", DependenceAnalysisPrinterPass(dbgs()))
-+FUNCTION_PASS("print<divergence>", DivergenceAnalysisPrinterPass(dbgs()))
-+FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
-+FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(dbgs()))
-+FUNCTION_PASS("print<delinearization>", DelinearizationPrinterPass(dbgs()))
-+FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs()))
-+FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs()))
-+FUNCTION_PASS("print<func-properties>", FunctionPropertiesPrinterPass(dbgs()))
-+FUNCTION_PASS("print<inline-cost>", InlineCostAnnotationPrinterPass(dbgs()))
-+FUNCTION_PASS("print<inliner-size-estimator>",InlineSizeEstimatorAnalysisPrinterPass(dbgs()))
-+FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))
-+FUNCTION_PASS("print<memoryssa>", MemorySSAPrinterPass(dbgs()))
-+FUNCTION_PASS("print<memoryssa-walker>", MemorySSAWalkerPrinterPass(dbgs()))
-+FUNCTION_PASS("print<phi-values>", PhiValuesPrinterPass(dbgs()))
-+FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(dbgs()))
-+FUNCTION_PASS("print<scalar-evolution>", ScalarEvolutionPrinterPass(dbgs()))
-+FUNCTION_PASS("print<stack-safety-local>", StackSafetyPrinterPass(dbgs()))
-+FUNCTION_PASS("print-alias-sets", AliasSetsPrinterPass(dbgs()))
-+FUNCTION_PASS("print-predicateinfo", PredicateInfoPrinterPass(dbgs()))
-+FUNCTION_PASS("print-mustexecute", MustExecutePrinterPass(dbgs()))
-+FUNCTION_PASS("print-memderefs", MemDerefPrinterPass(dbgs()))
-+FUNCTION_PASS("redundant-dbg-inst-elim", RedundantDbgInstEliminationPass())
-+FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass())
-+FUNCTION_PASS("scalarizer", ScalarizerPass())
-+FUNCTION_PASS("separate-const-offset-from-gep", SeparateConstOffsetFromGEPPass())
-+FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass())
-+FUNCTION_PASS("slsr", StraightLineStrengthReducePass())
-+FUNCTION_PASS("speculative-execution", SpeculativeExecutionPass())
-+FUNCTION_PASS("strip-gc-relocates", StripGCRelocates())
-+FUNCTION_PASS("structurizecfg", StructurizeCFGPass())
-+FUNCTION_PASS("unify-loop-exits", UnifyLoopExitsPass())
-+FUNCTION_PASS("vector-combine", VectorCombinePass())
-+FUNCTION_PASS("verify", VerifierPass())
-+FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
-+FUNCTION_PASS("verify<loops>", LoopVerifierPass())
-+FUNCTION_PASS("verify<memoryssa>", MemorySSAVerifierPass())
-+FUNCTION_PASS("verify<regions>", RegionInfoVerifierPass())
-+FUNCTION_PASS("verify<safepoint-ir>", SafepointIRVerifierPass())
-+FUNCTION_PASS("verify<scalar-evolution>", ScalarEvolutionVerifierPass())
-+FUNCTION_PASS("view-cfg", CFGViewerPass())
-+FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass())
-+FUNCTION_PASS("tlshoist", TLSVariableHoistPass())
-+FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass())
-+FUNCTION_PASS("tsan", ThreadSanitizerPass())
-+FUNCTION_PASS("memprof", MemProfilerPass())
-+
-+LOOP_PASS("canon-freeze", CanonicalizeFreezeInLoopsPass())
-+LOOP_PASS("dot-ddg", DDGDotPrinterPass())
-+LOOP_PASS("invalidate<all>", InvalidateAllAnalysesPass())
-+LOOP_PASS("loop-idiom", LoopIdiomRecognizePass())
-+LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass())
-+LOOP_PASS("no-op-loop", NoOpLoopPass())
-+LOOP_PASS("print", PrintLoopPass(dbgs()))
-+LOOP_PASS("loop-simplifycfg", LoopSimplifyCFGPass())
-+LOOP_PASS("indvars", IndVarSimplifyPass())
-+LOOP_PASS("loop-unroll-full", LoopFullUnrollPass())
-+LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs()))
-+LOOP_PASS("print<ddg>", DDGAnalysisPrinterPass(dbgs()))
-+LOOP_PASS("print<iv-users>", IVUsersPrinterPass(dbgs()))
-+LOOP_PASS("print<loopnest>", LoopNestPrinterPass(dbgs()))
-+LOOP_PASS("print<loop-cache-cost>", LoopCachePrinterPass(dbgs()))
-+LOOP_PASS("loop-predication", LoopPredicationPass())
-+LOOP_PASS("guard-widening", GuardWideningPass())
-+LOOP_PASS("loop-bound-split", LoopBoundSplitPass())
-+LOOP_PASS("loop-reroll", LoopRerollPass())
-+LOOP_PASS("loop-versioning-licm", LoopVersioningLICMPass())
-+**/
-diff --git a/ffi/build.py b/ffi/build.py
-index 7f0a69b60..9e235d858 100755
---- a/ffi/build.py
-+++ b/ffi/build.py
-@@ -188,17 +188,12 @@ def main_posix(kind, library_ext):
-     else:
-         (version, _) = out.split('.', 1)
-         version = int(version)
--        if version == 16:
--            msg = ("Building with LLVM 16; note that LLVM 16 support is "
--                   "presently experimental")
--            show_warning(msg)
--        elif version != 15:
--
--            msg = ("Building llvmlite requires LLVM 15, got "
-+        if version not in (17, 18, 19):
-+            msg = ("Building llvmlite requires LLVM {0}, got "
-                    "{!r}. Be sure to set LLVM_CONFIG to the right executable "
-                    "path.\nRead the documentation at "
-                    "http://llvmlite.pydata.org/ for more information about "
--                   "building llvmlite.\n".format(out.strip()))
-+                   "building llvmlite.\n".format(version, out.strip()))
-             raise RuntimeError(msg)
- 
-     # Get LLVM information for building
-diff --git a/ffi/core.cpp b/ffi/core.cpp
-index fbed1a7b7..1f69b55dd 100644
---- a/ffi/core.cpp
-+++ b/ffi/core.cpp
-@@ -23,16 +23,12 @@ LLVMPY_DisposeString(const char *msg) { free(const_cast<char *>(msg)); }
- API_EXPORT(LLVMContextRef)
- LLVMPY_GetGlobalContext() {
-     auto context = LLVMGetGlobalContext();
--    // FIXME: Remove with LLVM >= 17.
--    LLVMContextSetOpaquePointers(context, true);
-     return context;
- }
- 
- API_EXPORT(LLVMContextRef)
- LLVMPY_ContextCreate() {
-     LLVMContextRef context = LLVMContextCreate();
--    // FIXME: Remove with LLVM >= 17.
--    LLVMContextSetOpaquePointers(context, true);
-     return context;
- }
- 
-diff --git a/ffi/custom_passes.cpp b/ffi/custom_passes.cpp
-index a7906617b..e22bc6479 100644
---- a/ffi/custom_passes.cpp
-+++ b/ffi/custom_passes.cpp
-@@ -12,8 +12,6 @@
- #include "llvm/Analysis/PostDominators.h"
- #include "llvm/Support/raw_ostream.h"
- 
--#include "llvm/IR/LegacyPassManager.h"
--
- #include "llvm/InitializePasses.h"
- #include "llvm/LinkAllPasses.h"
- 
-@@ -25,11 +23,6 @@
- 
- using namespace llvm;
- 
--namespace llvm {
--void initializeRefNormalizeLegacyPassPass(PassRegistry &Registry);
--void initializeRefPruneLegacyPassPass(PassRegistry &Registry);
--} // namespace llvm
--
- namespace llvm {
- struct OpaqueModulePassManager;
- typedef OpaqueModulePassManager *LLVMModulePassManagerRef;
-@@ -960,7 +953,7 @@ struct RefPrune {
-                 auto name = dyn_cast<StoreInst>(&instruction)
-                                 ->getPointerOperand()
-                                 ->getName();
--                if (name.equals("excinfo") &&
-+                if (name.compare("excinfo") == 0 &&
-                     instruction.hasMetadata("numba_exception_output")) {
-                     return true;
-                 }
-@@ -1192,84 +1185,21 @@ class RefNormalizePass : public PassInfoMixin<RefNormalizePass> {
-     RefNormalizePass() = default;
- 
-     PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
--        RefNormalize().runOnFunction(F);
-+        if (RefNormalize().runOnFunction(F)) {
-+            return PreservedAnalyses::none();
-+        }
- 
-         return PreservedAnalyses::all();
-     }
- };
- 
--class RefNormalizeLegacyPass : public FunctionPass {
--  public:
--    static char ID;
--    RefNormalizeLegacyPass() : FunctionPass(ID) {
--        initializeRefNormalizeLegacyPassPass(*PassRegistry::getPassRegistry());
--    }
--
--    bool runOnFunction(Function &F) override {
--        return RefNormalize().runOnFunction(F);
--    };
--};
--
--class RefPruneLegacyPass : public FunctionPass {
--
--  public:
--    static char ID; // Pass identification, replacement for typeid
--    // The maximum number of nodes that the fanout pruners will look at.
--    size_t subgraph_limit;
--    Subpasses flags;
--    RefPruneLegacyPass(Subpasses flags = Subpasses::All,
--                       size_t subgraph_limit = -1)
--        : FunctionPass(ID), flags(flags), subgraph_limit(subgraph_limit) {
--        initializeRefPruneLegacyPassPass(*PassRegistry::getPassRegistry());
--    }
--
--    bool runOnFunction(Function &F) override {
--        auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
--
--        auto &PDT =
--            getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
--
--        return RefPrune(DT, PDT, flags, subgraph_limit).runOnFunction(F);
--    };
--
--    /**
--     * getAnalysisUsage() LLVM plumbing for the pass
--     */
--    void getAnalysisUsage(AnalysisUsage &Info) const override {
--        Info.addRequired<DominatorTreeWrapperPass>();
--        Info.addRequired<PostDominatorTreeWrapperPass>();
--    }
--};
--
--char RefNormalizeLegacyPass::ID = 0;
--char RefPruneLegacyPass::ID = 0;
--
- size_t RefPrune::stats_per_bb = 0;
- size_t RefPrune::stats_diamond = 0;
- size_t RefPrune::stats_fanout = 0;
- size_t RefPrune::stats_fanout_raise = 0;
- 
--INITIALIZE_PASS(RefNormalizeLegacyPass, "nrtRefNormalize",
--                "Normalize NRT refops", false, false)
--
--INITIALIZE_PASS_BEGIN(RefPruneLegacyPass, "nrtRefPruneLegacyPass",
--                      "Prune NRT refops", false, false)
--INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
--INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
--
--INITIALIZE_PASS_END(RefPruneLegacyPass, "RefPruneLegacyPass",
--                    "Prune NRT refops", false, false)
--
- extern "C" {
- 
--API_EXPORT(void)
--LLVMPY_AddLegacyRefPrunePass(LLVMPassManagerRef PM, int subpasses,
--                             size_t subgraph_limit) {
--    unwrap(PM)->add(new RefNormalizeLegacyPass());
--    unwrap(PM)->add(
--        new RefPruneLegacyPass((Subpasses)subpasses, subgraph_limit));
--}
--
- API_EXPORT(void)
- LLVMPY_AddRefPrunePass_module(LLVMModulePassManagerRef MPM, int subpasses,
-                               size_t subgraph_limit) {
-@@ -1307,12 +1237,10 @@ LLVMPY_DumpRefPruneStats(PRUNESTATS *buf, bool do_print) {
-      * do_print if set will print the stats to stderr.
-      */
-     if (do_print) {
--        errs() << "refprune stats "
--               << "per-BB " << RefPrune::stats_per_bb << " "
--               << "diamond " << RefPrune::stats_diamond << " "
--               << "fanout " << RefPrune::stats_fanout << " "
--               << "fanout+raise " << RefPrune::stats_fanout_raise << " "
--               << "\n";
-+        errs() << "refprune stats " << "per-BB " << RefPrune::stats_per_bb
-+               << " " << "diamond " << RefPrune::stats_diamond << " "
-+               << "fanout " << RefPrune::stats_fanout << " " << "fanout+raise "
-+               << RefPrune::stats_fanout_raise << " " << "\n";
-     };
- 
-     buf->basicblock = RefPrune::stats_per_bb;
-diff --git a/ffi/initfini.cpp b/ffi/initfini.cpp
-index dc05e6724..001172510 100644
---- a/ffi/initfini.cpp
-+++ b/ffi/initfini.cpp
-@@ -1,5 +1,4 @@
- #include "llvm-c/Core.h"
--#include "llvm-c/Initialization.h"
- #include "llvm-c/Target.h"
- 
- #include "core.h"
-@@ -7,27 +6,8 @@
- 
- extern "C" {
- 
--#define INIT(F)                                                                \
--    API_EXPORT(void) LLVMPY_Initialize##F() {                                  \
--        LLVMInitialize##F(LLVMGetGlobalPassRegistry());                        \
--    }
--
--INIT(Core)
--INIT(TransformUtils)
--INIT(ScalarOpts)
--#if LLVM_VERSION_MAJOR < 16
--INIT(ObjCARCOpts)
--#endif
--INIT(Vectorization)
--INIT(InstCombine)
--INIT(IPO)
--// INIT(Instrumentation)
--INIT(Analysis)
--INIT(IPA)
--INIT(CodeGen)
--INIT(Target)
--
--#undef INIT
-+// Pass registry and initialization APIs support dropped
-+// https://reviews.llvm.org/D145043 
- 
- API_EXPORT(void)
- LLVMPY_Shutdown() { LLVMShutdown(); }
-diff --git a/ffi/memorymanager.cpp b/ffi/memorymanager.cpp
-index 3f3ee79c7..abb681146 100644
---- a/ffi/memorymanager.cpp
-+++ b/ffi/memorymanager.cpp
-@@ -155,11 +155,7 @@ void LlvmliteMemoryManager::reserveAllocationSpace(uintptr_t CodeSize,
-     // Code alignment needs to be at least the stub alignment - however, we
-     // don't have an easy way to get that here so as a workaround, we assume
-     // it's 8, which is the largest value I observed across all platforms.
--#if LLVM_VERSION_MAJOR < 16
--    constexpr uint32_t StubAlign = 8;
--#else
-     constexpr uint64_t StubAlign = 8;
--#endif
- 
-     CodeAlign = LLVMLITE_ALIGN(std::max(GET_ALIGN_VALUE(CodeAlign), StubAlign));
- 
-diff --git a/ffi/memorymanager.h b/ffi/memorymanager.h
-index c0bdddaab..881a54d08 100644
---- a/ffi/memorymanager.h
-+++ b/ffi/memorymanager.h
-@@ -42,13 +42,8 @@ class __attribute__((visibility("default"))) ErrorInfoBase;
- #include <string>
- #include <system_error>
- 
--#if LLVM_VERSION_MAJOR < 16
--#define LLVMLITE_ALIGN uint32_t
--#define GET_ALIGN_VALUE(align) align
--#else
- #define LLVMLITE_ALIGN Align
- #define GET_ALIGN_VALUE(align) align.value()
--#endif
- 
- namespace llvm {
- 
-diff --git a/ffi/newpassmanagers.cpp b/ffi/newpassmanagers.cpp
-index c5819e851..a7a53d0f8 100644
---- a/ffi/newpassmanagers.cpp
-+++ b/ffi/newpassmanagers.cpp
-@@ -1,18 +1,233 @@
- #include "core.h"
- #include "llvm-c/TargetMachine.h"
- #include "llvm/Analysis/AliasAnalysisEvaluator.h"
-+#include "llvm/Analysis/AliasSetTracker.h"
-+#include "llvm/Analysis/AssumptionCache.h"
-+#include "llvm/Analysis/BasicAliasAnalysis.h"
-+#include "llvm/Analysis/BlockFrequencyInfo.h"
-+#include "llvm/Analysis/BranchProbabilityInfo.h"
-+#include "llvm/Analysis/CFGPrinter.h"
-+#include "llvm/Analysis/CGSCCPassManager.h"
-+#include "llvm/Analysis/CallGraph.h"
-+#include "llvm/Analysis/CallPrinter.h"
-+#include "llvm/Analysis/CostModel.h"
-+#include "llvm/Analysis/CycleAnalysis.h"
-+#include "llvm/Analysis/DDG.h"
-+#include "llvm/Analysis/DDGPrinter.h"
-+#include "llvm/Analysis/Delinearization.h"
-+#include "llvm/Analysis/DemandedBits.h"
-+#include "llvm/Analysis/DependenceAnalysis.h"
-+#include "llvm/Analysis/DomPrinter.h"
-+#include "llvm/Analysis/DominanceFrontier.h"
-+#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
-+#include "llvm/Analysis/GlobalsModRef.h"
-+#include "llvm/Analysis/IRSimilarityIdentifier.h"
-+#include "llvm/Analysis/IVUsers.h"
-+#include "llvm/Analysis/InlineAdvisor.h"
-+#include "llvm/Analysis/InlineSizeEstimatorAnalysis.h"
-+#include "llvm/Analysis/InstCount.h"
-+#include "llvm/Analysis/LazyCallGraph.h"
-+#include "llvm/Analysis/LazyValueInfo.h"
-+#include "llvm/Analysis/Lint.h"
-+#include "llvm/Analysis/LoopAccessAnalysis.h"
-+#include "llvm/Analysis/LoopCacheAnalysis.h"
-+#include "llvm/Analysis/LoopInfo.h"
-+#include "llvm/Analysis/LoopNestAnalysis.h"
-+#include "llvm/Analysis/MemDerefPrinter.h"
-+#include "llvm/Analysis/MemoryDependenceAnalysis.h"
-+#include "llvm/Analysis/MemorySSA.h"
-+#include "llvm/Analysis/ModuleDebugInfoPrinter.h"
-+#include "llvm/Analysis/ModuleSummaryAnalysis.h"
-+#include "llvm/Analysis/MustExecute.h"
-+#include "llvm/Analysis/ObjCARCAliasAnalysis.h"
-+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-+#include "llvm/Analysis/PhiValues.h"
-+#include "llvm/Analysis/PostDominators.h"
-+#include "llvm/Analysis/ProfileSummaryInfo.h"
-+#include "llvm/Analysis/RegionInfo.h"
-+#include "llvm/Analysis/ScalarEvolution.h"
-+#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
-+#include "llvm/Analysis/ScopedNoAliasAA.h"
-+#include "llvm/Analysis/StackLifetime.h"
-+#include "llvm/Analysis/StackSafetyAnalysis.h"
-+#include "llvm/Analysis/TargetLibraryInfo.h"
-+#include "llvm/Analysis/TargetTransformInfo.h"
-+#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
-+#include "llvm/IR/Dominators.h"
-+#include "llvm/IR/IRPrintingPasses.h"
- #include "llvm/IR/PassManager.h"
-+#include <llvm/IR/PassTimingInfo.h>
- #include "llvm/IR/Verifier.h"
- #include "llvm/Passes/PassBuilder.h"
- #include "llvm/Passes/StandardInstrumentations.h"
-+#include "llvm/Support/raw_ostream.h"
-+#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
-+#include "llvm/Transforms/Coroutines/CoroCleanup.h"
-+#include "llvm/Transforms/Coroutines/CoroEarly.h"
-+#include "llvm/Transforms/Coroutines/CoroElide.h"
-+#include "llvm/Transforms/Coroutines/CoroSplit.h"
-+#include "llvm/Transforms/IPO/AlwaysInliner.h"
-+#include "llvm/Transforms/IPO/Annotation2Metadata.h"
-+#include "llvm/Transforms/IPO/ArgumentPromotion.h"
-+#include "llvm/Transforms/IPO/Attributor.h"
-+#include "llvm/Transforms/IPO/BlockExtractor.h"
-+#include "llvm/Transforms/IPO/CalledValuePropagation.h"
-+#include "llvm/Transforms/IPO/ConstantMerge.h"
-+#include "llvm/Transforms/IPO/CrossDSOCFI.h"
-+#include "llvm/Transforms/IPO/DeadArgumentElimination.h"
-+#include "llvm/Transforms/IPO/ElimAvailExtern.h"
-+#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
-+#include "llvm/Transforms/IPO/FunctionAttrs.h"
-+#include "llvm/Transforms/IPO/FunctionImport.h"
-+#include "llvm/Transforms/IPO/GlobalDCE.h"
-+#include "llvm/Transforms/IPO/GlobalOpt.h"
-+#include "llvm/Transforms/IPO/GlobalSplit.h"
-+#include "llvm/Transforms/IPO/HotColdSplitting.h"
-+#include "llvm/Transforms/IPO/IROutliner.h"
-+#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
-+#include "llvm/Transforms/IPO/Inliner.h"
-+#include "llvm/Transforms/IPO/Internalize.h"
-+#include "llvm/Transforms/IPO/LoopExtractor.h"
-+#include "llvm/Transforms/IPO/LowerTypeTests.h"
-+#include "llvm/Transforms/IPO/MergeFunctions.h"
-+#include "llvm/Transforms/IPO/ModuleInliner.h"
-+#include "llvm/Transforms/IPO/OpenMPOpt.h"
-+#include "llvm/Transforms/IPO/PartialInlining.h"
-+#include "llvm/Transforms/IPO/SCCP.h"
-+#include "llvm/Transforms/IPO/SampleProfile.h"
-+#include "llvm/Transforms/IPO/SampleProfileProbe.h"
-+#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
-+#include "llvm/Transforms/IPO/StripSymbols.h"
-+#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
- #include "llvm/Transforms/InstCombine/InstCombine.h"
-+#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
-+#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
-+#include "llvm/Transforms/Instrumentation/CGProfile.h"
-+#include "llvm/Transforms/Instrumentation/ControlHeightReduction.h"
-+#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
-+#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
-+#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
-+#include "llvm/Transforms/Instrumentation/InstrOrderFile.h"
-+#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
-+#include "llvm/Transforms/Instrumentation/MemProfiler.h"
-+#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
-+#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
-+#include "llvm/Transforms/Instrumentation/PoisonChecking.h"
-+#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
-+#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
-+#include "llvm/Transforms/ObjCARC.h"
-+#include "llvm/Transforms/Scalar/ADCE.h"
-+#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
-+#include "llvm/Transforms/Scalar/AnnotationRemarks.h"
-+#include "llvm/Transforms/Scalar/BDCE.h"
-+#include "llvm/Transforms/Scalar/CallSiteSplitting.h"
-+#include "llvm/Transforms/Scalar/ConstantHoisting.h"
-+#include "llvm/Transforms/Scalar/ConstraintElimination.h"
-+#include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h"
-+#include "llvm/Transforms/Scalar/DCE.h"
-+#include "llvm/Transforms/Scalar/DFAJumpThreading.h"
-+#include "llvm/Transforms/Scalar/DeadStoreElimination.h"
-+#include "llvm/Transforms/Scalar/DivRemPairs.h"
-+#include "llvm/Transforms/Scalar/EarlyCSE.h"
-+#include "llvm/Transforms/Scalar/FlattenCFG.h"
-+#include "llvm/Transforms/Scalar/Float2Int.h"
-+#include "llvm/Transforms/Scalar/GVN.h"
-+#include "llvm/Transforms/Scalar/GuardWidening.h"
-+#include "llvm/Transforms/Scalar/IVUsersPrinter.h"
-+#include "llvm/Transforms/Scalar/IndVarSimplify.h"
-+#include "llvm/Transforms/Scalar/InductiveRangeCheckElimination.h"
-+#include "llvm/Transforms/Scalar/InferAddressSpaces.h"
-+#include "llvm/Transforms/Scalar/InstSimplifyPass.h"
- #include "llvm/Transforms/Scalar/JumpThreading.h"
-+#include "llvm/Transforms/Scalar/LICM.h"
-+#include "llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h"
-+#include "llvm/Transforms/Scalar/LoopBoundSplit.h"
-+#include "llvm/Transforms/Scalar/LoopDataPrefetch.h"
-+#include "llvm/Transforms/Scalar/LoopDeletion.h"
-+#include "llvm/Transforms/Scalar/LoopDistribute.h"
-+#include "llvm/Transforms/Scalar/LoopFlatten.h"
-+#include "llvm/Transforms/Scalar/LoopFuse.h"
-+#include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
-+#include "llvm/Transforms/Scalar/LoopInstSimplify.h"
-+#include "llvm/Transforms/Scalar/LoopInterchange.h"
-+#include "llvm/Transforms/Scalar/LoopLoadElimination.h"
-+#include "llvm/Transforms/Scalar/LoopPassManager.h"
-+#include "llvm/Transforms/Scalar/LoopPredication.h"
- #include "llvm/Transforms/Scalar/LoopRotation.h"
-+#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
-+#include "llvm/Transforms/Scalar/LoopSink.h"
-+#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
-+#include "llvm/Transforms/Scalar/LoopUnrollAndJamPass.h"
- #include "llvm/Transforms/Scalar/LoopUnrollPass.h"
-+#include "llvm/Transforms/Scalar/LoopVersioningLICM.h"
-+#include "llvm/Transforms/Scalar/LowerAtomicPass.h"
-+#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
-+#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
-+#include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h"
-+#include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h"
-+#include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
-+#include "llvm/Transforms/Scalar/MakeGuardsExplicit.h"
-+#include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
-+#include "llvm/Transforms/Scalar/MergeICmps.h"
-+#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
-+#include "llvm/Transforms/Scalar/NaryReassociate.h"
-+#include "llvm/Transforms/Scalar/NewGVN.h"
-+#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
-+#include "llvm/Transforms/Scalar/Reassociate.h"
-+#include "llvm/Transforms/Scalar/Reg2Mem.h"
-+#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
-+#include "llvm/Transforms/Scalar/SCCP.h"
-+#include "llvm/Transforms/Scalar/SROA.h"
-+#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
-+#include "llvm/Transforms/Scalar/Scalarizer.h"
-+#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
-+#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
- #include "llvm/Transforms/Scalar/SimplifyCFG.h"
-+#include "llvm/Transforms/Scalar/Sink.h"
-+#include "llvm/Transforms/Scalar/SpeculativeExecution.h"
-+#include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h"
-+#include "llvm/Transforms/Scalar/StructurizeCFG.h"
-+#include "llvm/Transforms/Scalar/TLSVariableHoist.h"
-+#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
-+#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
-+#include "llvm/Transforms/Utils/AddDiscriminators.h"
-+#include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
-+#include "llvm/Transforms/Utils/BreakCriticalEdges.h"
-+#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
-+#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
-+#include "llvm/Transforms/Utils/Debugify.h"
-+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
-+#include "llvm/Transforms/Utils/FixIrreducible.h"
-+#include "llvm/Transforms/Utils/HelloWorld.h"
-+#include "llvm/Transforms/Utils/InjectTLIMappings.h"
-+#include "llvm/Transforms/Utils/InstructionNamer.h"
-+#include "llvm/Transforms/Utils/LCSSA.h"
-+#include "llvm/Transforms/Utils/LibCallsShrinkWrap.h"
-+#include "llvm/Transforms/Utils/LoopSimplify.h"
-+#include "llvm/Transforms/Utils/LoopVersioning.h"
-+#include "llvm/Transforms/Utils/LowerGlobalDtors.h"
-+#include "llvm/Transforms/Utils/LowerInvoke.h"
-+#include "llvm/Transforms/Utils/LowerSwitch.h"
-+#include "llvm/Transforms/Utils/Mem2Reg.h"
-+#include "llvm/Transforms/Utils/MetaRenamer.h"
-+#include "llvm/Transforms/Utils/NameAnonGlobals.h"
-+#include "llvm/Transforms/Utils/PredicateInfo.h"
-+#include "llvm/Transforms/Utils/RelLookupTableConverter.h"
-+#include "llvm/Transforms/Utils/StripGCRelocates.h"
-+#include "llvm/Transforms/Utils/StripNonLineTableDebugInfo.h"
-+#include "llvm/Transforms/Utils/SymbolRewriter.h"
-+#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
-+#include "llvm/Transforms/Utils/UnifyLoopExits.h"
-+#include "llvm/Transforms/Vectorize/LoadStoreVectorizer.h"
-+#include "llvm/Transforms/Vectorize/LoopVectorize.h"
-+#include "llvm/Transforms/Vectorize/SLPVectorizer.h"
-+#include "llvm/Transforms/Vectorize/VectorCombine.h"
- 
- using namespace llvm;
- 
-+#define STRINGIFY(x) #x
-+#define TOSTRING(x) STRINGIFY(x)
-+
- /*
-  * Exposed API
-  */
-@@ -75,13 +290,10 @@ LLVMPY_RunNewModulePassManager(LLVMModulePassManagerRef MPMRef,
- 
-     PrintPassOptions PrintPassOpts;
- 
--#if LLVM_VERSION_MAJOR < 16
--    StandardInstrumentations SI(DebugLogging, VerifyEach, PrintPassOpts);
--#else
-     StandardInstrumentations SI(M->getContext(), DebugLogging, VerifyEach,
-                                 PrintPassOpts);
--#endif
--    SI.registerCallbacks(*PB->getPassInstrumentationCallbacks(), &FAM);
-+    // https://reviews.llvm.org/D146160
-+    SI.registerCallbacks(*PB->getPassInstrumentationCallbacks(), &MAM);
- 
-     PB->registerLoopAnalyses(LAM);
-     PB->registerFunctionAnalyses(FAM);
-@@ -91,41 +303,6 @@ LLVMPY_RunNewModulePassManager(LLVMModulePassManagerRef MPMRef,
-     MPM->run(*M, MAM);
- }
- 
--API_EXPORT(void)
--LLVMPY_AddVerifierPass(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)->addPass(VerifierPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddAAEvalPass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)->addPass(
--        createModuleToFunctionPassAdaptor(AAEvaluator()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddSimplifyCFGPass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)->addPass(
--        createModuleToFunctionPassAdaptor(SimplifyCFGPass()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopUnrollPass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)->addPass(
--        createModuleToFunctionPassAdaptor(LoopUnrollPass()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopRotatePass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)->addPass(createModuleToFunctionPassAdaptor(
--        createFunctionToLoopPassAdaptor(LoopRotatePass())));
--}
--
--API_EXPORT(void)
--LLVMPY_AddInstructionCombinePass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)->addPass(
--        createModuleToFunctionPassAdaptor(InstCombinePass()));
--}
--
- API_EXPORT(void)
- LLVMPY_AddJumpThreadingPass_module(LLVMModulePassManagerRef MPM, int T) {
-     llvm::unwrap(MPM)->addPass(
-@@ -168,13 +345,10 @@ LLVMPY_RunNewFunctionPassManager(LLVMFunctionPassManagerRef FPMRef,
-     // TODO: Can expose this in ffi layer
-     PrintPassOptions PrintPassOpts;
- 
--#if LLVM_VERSION_MAJOR < 16
--    StandardInstrumentations SI(DebugLogging, VerifyEach, PrintPassOpts);
--#else
-     StandardInstrumentations SI(F->getContext(), DebugLogging, VerifyEach,
-                                 PrintPassOpts);
--#endif
--    SI.registerCallbacks(*PB->getPassInstrumentationCallbacks(), &FAM);
-+    // https://reviews.llvm.org/D146160
-+    SI.registerCallbacks(*PB->getPassInstrumentationCallbacks(), &MAM);
- 
-     PB->registerLoopAnalyses(LAM);
-     PB->registerFunctionAnalyses(FAM);
-@@ -184,32 +358,6 @@ LLVMPY_RunNewFunctionPassManager(LLVMFunctionPassManagerRef FPMRef,
-     FPM->run(*F, FAM);
- }
- 
--API_EXPORT(void)
--LLVMPY_AddAAEvalPass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)->addPass(AAEvaluator());
--}
--
--API_EXPORT(void)
--LLVMPY_AddSimplifyCFGPass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)->addPass(SimplifyCFGPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopUnrollPass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)->addPass(LoopUnrollPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopRotatePass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)->addPass(
--        createFunctionToLoopPassAdaptor(LoopRotatePass()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddInstructionCombinePass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)->addPass(InstCombinePass());
--}
--
- API_EXPORT(void)
- LLVMPY_AddJumpThreadingPass_function(LLVMFunctionPassManagerRef FPM, int T) {
-     llvm::unwrap(FPM)->addPass(JumpThreadingPass(T));
-@@ -267,16 +415,15 @@ LLVMPY_PTOSetLoopUnrolling(LLVMPipelineTuningOptionsRef PTO, bool value) {
-     llvm::unwrap(PTO)->LoopUnrolling = value;
- }
- 
--// FIXME: Available from llvm16
--// API_EXPORT(int)
--// LLVMPY_PTOGetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO) {
--//     return llvm::unwrap(PTO)->InlinerThreshold;
--// }
-+API_EXPORT(int)
-+LLVMPY_PTOGetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO) {
-+    return llvm::unwrap(PTO)->InlinerThreshold;
-+}
- 
--// API_EXPORT(void)
--// LLVMPY_PTOSetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO, bool value) {
--//     llvm::unwrap(PTO)->InlinerThreshold = value;
--// }
-+API_EXPORT(void)
-+LLVMPY_PTOSetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO, bool value) {
-+    llvm::unwrap(PTO)->InlinerThreshold = value;
-+}
- 
- API_EXPORT(void)
- LLVMPY_DisposePipelineTuningOptions(LLVMPipelineTuningOptionsRef PTO) {
-@@ -325,11 +472,7 @@ LLVMPY_CreatePassBuilder(LLVMTargetMachineRef TMRef,
-     TargetMachine *TM = llvm::unwrap(TMRef);
-     PipelineTuningOptions *PTO = llvm::unwrap(PTORef);
-     PassInstrumentationCallbacks *PIC = new PassInstrumentationCallbacks();
--#if LLVM_VERSION_MAJOR < 16
--    return llvm::wrap(new PassBuilder(TM, *PTO, None, PIC));
--#else
-     return llvm::wrap(new PassBuilder(TM, *PTO, std::nullopt, PIC));
--#endif
- }
- 
- API_EXPORT(void)
-@@ -397,4 +540,77 @@ LLVMPY_buildFunctionSimplificationPipeline(LLVMPassBuilderRef PBref,
-     return llvm::wrap(FPM);
- }
- 
-+API_EXPORT(void)
-+LLVMPY_module_AddModuleDebugInfoPrinterPass(LLVMModulePassManagerRef MPM) {
-+    llvm::unwrap(MPM)->addPass(ModuleDebugInfoPrinterPass(llvm::outs()));
-+}
-+
-+#define CGSCC_PASS(NAME)                                                       \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)->addPass(                                            \
-+            createModuleToPostOrderCGSCCPassAdaptor(NAME()));                  \
-+    }
-+#include "PASSREGISTRY.def"
-+
-+#define MODULE_PASS(NAME)                                                      \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)->addPass(NAME());                                    \
-+    }
-+#include "PASSREGISTRY.def"
-+
-+#define FUNCTION_PASS(NAME)                                                    \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)->addPass(createModuleToFunctionPassAdaptor(NAME())); \
-+    }                                                                          \
-+    void LLVMPY_function_Add##NAME(LLVMFunctionPassManagerRef FPM) {           \
-+        llvm::unwrap(FPM)->addPass(NAME());                                    \
-+    }
-+#include "PASSREGISTRY.def"
-+
-+#define LOOP_PASS(NAME)                                                        \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)->addPass(createModuleToFunctionPassAdaptor(          \
-+            createFunctionToLoopPassAdaptor(NAME())));                         \
-+    }                                                                          \
-+    void LLVMPY_function_Add##NAME(LLVMFunctionPassManagerRef FPM) {           \
-+        llvm::unwrap(FPM)->addPass(createFunctionToLoopPassAdaptor(NAME()));   \
-+    }
-+#include "PASSREGISTRY.def"
-+
-+const char *LLVMPY_getModuleLevelPasses() {
-+    std::string module_passes;
-+
-+#define MODULE_PASS(NAME) module_passes = module_passes + " " + TOSTRING(NAME);
-+#define FUNCTION_PASS(NAME)                                                    \
-+    module_passes = module_passes + " " + TOSTRING(NAME);
-+#define LOOP_PASS(NAME) module_passes = module_passes + " " + TOSTRING(NAME);
-+#include "PASSREGISTRY.def"
-+
-+    return LLVMPY_CreateString(module_passes.c_str());
-+}
-+
-+const char *LLVMPY_getFunctionLevelPasses() {
-+    std::string function_passes;
-+
-+#define FUNCTION_PASS(NAME)                                                    \
-+    function_passes = function_passes + " " + TOSTRING(NAME);
-+#define LOOP_PASS(NAME)                                                        \
-+    function_passes = function_passes + " " + TOSTRING(NAME);
-+#include "PASSREGISTRY.def"
-+
-+    return LLVMPY_CreateString(function_passes.c_str());
-+}
-+
-+API_EXPORT(void)
-+LLVMPY_SetTimePasses(bool enable) { TimePassesIsEnabled = enable; }
-+
-+API_EXPORT(void)
-+LLVMPY_ReportAndResetTimings(const char **outmsg) {
-+    std::string osbuf;
-+    raw_string_ostream os(osbuf);
-+    reportAndResetTimings(&os);
-+    os.flush();
-+    *outmsg = LLVMPY_CreateString(os.str().c_str());
-+}
-+
- } // end extern "C"
-diff --git a/ffi/orcjit.cpp b/ffi/orcjit.cpp
-index e19d6b97d..a00be2e7a 100644
---- a/ffi/orcjit.cpp
-+++ b/ffi/orcjit.cpp
-@@ -5,7 +5,7 @@
- 
- #include "llvm/AsmParser/Parser.h"
- #include "llvm/ExecutionEngine/Orc/Core.h"
--#include "llvm/ExecutionEngine/Orc/DebuggerSupportPlugin.h"
-+#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h"
- #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
- #include "llvm/ExecutionEngine/Orc/LLJIT.h"
- #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
-@@ -92,7 +92,7 @@ LLVMPY_CreateLLJITCompiler(LLVMTargetMachineRef tm, bool suppressErrors,
-             auto linkingLayer =
-                 std::make_unique<llvm::orc::ObjectLinkingLayer>(session);
- 
--            /* TODO(LLVM16): In newer LLVM versions, there is a simple
-+            /* FIXME(LLVM16): In newer LLVM versions, there is a simple
-              * EnableDebugSupport flag on the builder and we don't need to do
-              * any of this. */
-             if (triple.getObjectFormat() == Triple::ELF ||
-@@ -195,8 +195,11 @@ LLVMPY_LLJIT_Link(std::shared_ptr<LLJIT> *lljit, const char *libraryName,
-     for (size_t import_idx = 0; import_idx < imports_length; import_idx++) {
-         SymbolStringPtr mangled =
-             (*lljit)->mangleAndIntern(imports[import_idx].name);
--        JITEvaluatedSymbol symbol(imports[import_idx].address,
-+        ExecutorSymbolDef symbol(ExecutorAddr(imports[import_idx].address),
-                                   JITSymbolFlags::Exported);
-+        
-+        llvm::orc::SymbolMap sym_map;
-+        sym_map[mangled] = symbol;
-         auto error = dylib->define(absoluteSymbols({{mangled, symbol}}));
- 
-         if (error) {
-diff --git a/ffi/passmanagers.cpp b/ffi/passmanagers.cpp
-deleted file mode 100644
-index 444482937..000000000
---- a/ffi/passmanagers.cpp
-+++ /dev/null
-@@ -1,467 +0,0 @@
--#include <sstream>
--
--#include "core.h"
--
--#include "llvm-c/Transforms/IPO.h"
--#include "llvm-c/Transforms/Scalar.h"
--#include "llvm/ADT/STLExtras.h"
--#include "llvm/IR/DiagnosticInfo.h"
--#include "llvm/IR/DiagnosticPrinter.h"
--#include "llvm/IR/LegacyPassManager.h"
--#include "llvm/IR/Module.h"
--#include "llvm/Support/FileSystem.h"
--#include "llvm/Support/ToolOutputFile.h"
--#include "llvm/Support/YAMLTraits.h"
--#include "llvm/Support/raw_ostream.h"
--
--#include "llvm-c/Transforms/IPO.h"
--#include "llvm-c/Transforms/Scalar.h"
--#include "llvm/IR/LLVMRemarkStreamer.h"
--#include "llvm/IR/LegacyPassManager.h"
--#include "llvm/Remarks/RemarkStreamer.h"
--#include "llvm/Transforms/IPO.h"
--#include "llvm/Transforms/Scalar.h"
--
--#include <llvm/IR/PassTimingInfo.h>
--
--#include <llvm/Analysis/AliasAnalysisEvaluator.h>
--#include <llvm/Analysis/BasicAliasAnalysis.h>
--#include <llvm/Analysis/CFGPrinter.h>
--#include <llvm/Analysis/CallPrinter.h>
--#include <llvm/Analysis/DependenceAnalysis.h>
--#include <llvm/Analysis/DomPrinter.h>
--#include <llvm/Analysis/GlobalsModRef.h>
--#include <llvm/Analysis/IVUsers.h>
--#include <llvm/Analysis/Lint.h>
--#include <llvm/Analysis/Passes.h>
--#include <llvm/Analysis/ScalarEvolutionAliasAnalysis.h>
--#include <llvm/CodeGen/Passes.h>
--#include <llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h>
--#include <llvm/Transforms/IPO.h>
--#include <llvm/Transforms/IPO/AlwaysInliner.h>
--#include <llvm/Transforms/Scalar/SimpleLoopUnswitch.h>
--#include <llvm/Transforms/Utils.h>
--#include <llvm/Transforms/Utils/UnifyFunctionExitNodes.h>
--using namespace llvm;
--
--/*
-- * Exposed API
-- */
--
--extern "C" {
--
--API_EXPORT(void)
--LLVMPY_SetTimePasses(bool enable) { TimePassesIsEnabled = enable; }
--
--API_EXPORT(void)
--LLVMPY_ReportAndResetTimings(const char **outmsg) {
--    std::string osbuf;
--    raw_string_ostream os(osbuf);
--    reportAndResetTimings(&os);
--    os.flush();
--    *outmsg = LLVMPY_CreateString(os.str().c_str());
--}
--
--API_EXPORT(LLVMPassManagerRef)
--LLVMPY_CreatePassManager() { return LLVMCreatePassManager(); }
--
--API_EXPORT(void)
--LLVMPY_DisposePassManager(LLVMPassManagerRef PM) {
--    return LLVMDisposePassManager(PM);
--}
--
--API_EXPORT(LLVMPassManagerRef)
--LLVMPY_CreateFunctionPassManager(LLVMModuleRef M) {
--    return LLVMCreateFunctionPassManagerForModule(M);
--}
--
--API_EXPORT(int)
--LLVMPY_RunPassManagerWithRemarks(LLVMPassManagerRef PM, LLVMModuleRef M,
--                                 const char *remarks_format,
--                                 const char *remarks_filter,
--                                 const char *record_filename) {
--    auto setupResult = llvm::setupLLVMOptimizationRemarks(
--        unwrap(M)->getContext(), record_filename, remarks_filter,
--        remarks_format, true);
--    if (!setupResult) {
--        return -1;
--    }
--    auto optimisationFile = std::move(*setupResult);
--    auto r = LLVMRunPassManager(PM, M);
--
--    unwrap(M)->getContext().setMainRemarkStreamer(nullptr);
--    unwrap(M)->getContext().setLLVMRemarkStreamer(nullptr);
--
--    optimisationFile->keep();
--    optimisationFile->os().flush();
--    return r;
--}
--
--API_EXPORT(int)
--LLVMPY_RunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
--    return LLVMRunPassManager(PM, M);
--}
--
--API_EXPORT(int)
--LLVMPY_RunFunctionPassManagerWithRemarks(LLVMPassManagerRef PM, LLVMValueRef F,
--                                         const char *remarks_format,
--                                         const char *remarks_filter,
--                                         const char *record_filename) {
--    auto setupResult = llvm::setupLLVMOptimizationRemarks(
--        unwrap(F)->getContext(), record_filename, remarks_filter,
--        remarks_format, true);
--    if (!setupResult) {
--        return -1;
--    }
--    auto optimisationFile = std::move(*setupResult);
--
--    auto r = LLVMRunFunctionPassManager(PM, F);
--
--    unwrap(F)->getContext().setMainRemarkStreamer(nullptr);
--    unwrap(F)->getContext().setLLVMRemarkStreamer(nullptr);
--
--    optimisationFile->keep();
--    optimisationFile->os().flush();
--    return r;
--}
--
--API_EXPORT(int)
--LLVMPY_RunFunctionPassManager(LLVMPassManagerRef PM, LLVMValueRef F) {
--    return LLVMRunFunctionPassManager(PM, F);
--}
--
--API_EXPORT(int)
--LLVMPY_InitializeFunctionPassManager(LLVMPassManagerRef FPM) {
--    return LLVMInitializeFunctionPassManager(FPM);
--}
--
--API_EXPORT(int)
--LLVMPY_FinalizeFunctionPassManager(LLVMPassManagerRef FPM) {
--    return LLVMFinalizeFunctionPassManager(FPM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddAAEvalPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createAAEvalPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddBasicAAWrapperPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createBasicAAWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDependenceAnalysisPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createDependenceAnalysisWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddCallGraphDOTPrinterPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createCallGraphDOTPrinterPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDotDomPrinterPass(LLVMPassManagerRef PM, bool showBody) {
--    unwrap(PM)->add(showBody ? llvm::createDomPrinterWrapperPassPass()
--                             : llvm::createDomOnlyPrinterWrapperPassPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddGlobalsModRefAAPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createGlobalsAAWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDotPostDomPrinterPass(LLVMPassManagerRef PM, bool showBody) {
--    unwrap(PM)->add(showBody ? llvm::createPostDomPrinterWrapperPassPass()
--                             : llvm::createPostDomOnlyPrinterWrapperPassPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddCFGPrinterPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createCFGPrinterLegacyPassPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddConstantMergePass(LLVMPassManagerRef PM) {
--    LLVMAddConstantMergePass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddDeadStoreEliminationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createDeadStoreEliminationPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddReversePostOrderFunctionAttrsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createReversePostOrderFunctionAttrsPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDeadArgEliminationPass(LLVMPassManagerRef PM) {
--    LLVMAddDeadArgEliminationPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddInstructionCountPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createInstCountPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddIVUsersPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createIVUsersPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLazyValueInfoPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createLazyValueInfoPass());
--}
--API_EXPORT(void)
--LLVMPY_AddLintPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createLintLegacyPassPass());
--}
--API_EXPORT(void)
--LLVMPY_AddModuleDebugInfoPrinterPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createModuleDebugInfoPrinterPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddRegionInfoPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createRegionInfoPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddScalarEvolutionAAPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createSCEVAAWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddAggressiveDCEPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createAggressiveDCEPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddAlwaysInlinerPass(LLVMPassManagerRef PM, bool insertLifetime) {
--    unwrap(PM)->add(llvm::createAlwaysInlinerLegacyPass(insertLifetime));
--}
--
--API_EXPORT(void)
--LLVMPY_AddBreakCriticalEdgesPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(llvm::createBreakCriticalEdgesPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddFunctionAttrsPass(LLVMPassManagerRef PM) {
--    LLVMAddFunctionAttrsPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddFunctionInliningPass(LLVMPassManagerRef PM, int Threshold) {
--    unwrap(PM)->add(createFunctionInliningPass(Threshold));
--}
--
--API_EXPORT(void)
--LLVMPY_AddGlobalOptimizerPass(LLVMPassManagerRef PM) {
--    LLVMAddGlobalOptimizerPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddGlobalDCEPass(LLVMPassManagerRef PM) { LLVMAddGlobalDCEPass(PM); }
--
--API_EXPORT(void)
--LLVMPY_AddIPSCCPPass(LLVMPassManagerRef PM) { LLVMAddIPSCCPPass(PM); }
--
--API_EXPORT(void)
--LLVMPY_AddDeadCodeEliminationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createDeadCodeEliminationPass());
--}
--
--#if LLVM_VERSION_MAJOR < 16
--API_EXPORT(void)
--LLVMPY_AddAggressiveInstructionCombiningPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createAggressiveInstCombinerPass());
--}
--#endif
--
--API_EXPORT(void)
--LLVMPY_AddInternalizePass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createInternalizePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddJumpThreadingPass(LLVMPassManagerRef PM, int threshold) {
--    unwrap(PM)->add(createJumpThreadingPass(threshold));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLCSSAPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLCSSAPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopDeletionPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLoopDeletionPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopExtractorPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLoopExtractorPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddSingleLoopExtractorPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createSingleLoopExtractorPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopStrengthReducePass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLoopStrengthReducePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopSimplificationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLoopSimplifyPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopUnrollPass(LLVMPassManagerRef PM) { LLVMAddLoopUnrollPass(PM); }
--
--API_EXPORT(void)
--LLVMPY_AddLoopUnrollAndJamPass(LLVMPassManagerRef PM) {
--    LLVMAddLoopUnrollAndJamPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopUnswitchPass(LLVMPassManagerRef PM, bool optimizeForSize,
--                           bool hasBranchDivergence) {
--    unwrap(PM)->add(createSimpleLoopUnswitchLegacyPass(optimizeForSize));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLowerAtomicPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLowerAtomicPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLowerInvokePass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLowerInvokePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLowerSwitchPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createLowerSwitchPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddMemCpyOptimizationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createMemCpyOptPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddMergeFunctionsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createMergeFunctionsPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddMergeReturnsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createUnifyFunctionExitNodesPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddPartialInliningPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createPartialInliningPass());
--}
--
--#if LLVM_VERSION_MAJOR < 16
--API_EXPORT(void)
--LLVMPY_AddPruneExceptionHandlingPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createPruneEHPass());
--}
--#endif
--
--API_EXPORT(void)
--LLVMPY_AddReassociatePass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createReassociatePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDemoteRegisterToMemoryPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createDemoteRegisterToMemoryPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddSinkPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createSinkingPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripSymbolsPass(LLVMPassManagerRef PM, bool onlyDebugInfo) {
--    unwrap(PM)->add(createStripSymbolsPass(onlyDebugInfo));
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripDeadDebugInfoPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createStripDeadDebugInfoPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripDeadPrototypesPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createStripDeadPrototypesPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripDebugDeclarePrototypesPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createStripDebugDeclarePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripNondebugSymbolsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createStripNonDebugSymbolsPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddTailCallEliminationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createTailCallEliminationPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddCFGSimplificationPass(LLVMPassManagerRef PM) {
--    LLVMAddCFGSimplificationPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddGVNPass(LLVMPassManagerRef PM) { LLVMAddGVNPass(PM); }
--
--API_EXPORT(void)
--LLVMPY_AddInstructionCombiningPass(LLVMPassManagerRef PM) {
--    LLVMAddInstructionCombiningPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddLICMPass(LLVMPassManagerRef PM) { LLVMAddLICMPass(PM); }
--
--API_EXPORT(void)
--LLVMPY_AddSCCPPass(LLVMPassManagerRef PM) { LLVMAddSCCPPass(PM); }
--
--API_EXPORT(void)
--LLVMPY_AddSROAPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createSROAPass()); }
--
--API_EXPORT(void)
--LLVMPY_AddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM) {
--    LLVMAddTypeBasedAliasAnalysisPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddBasicAliasAnalysisPass(LLVMPassManagerRef PM) {
--    LLVMAddBasicAliasAnalysisPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopRotatePass(LLVMPassManagerRef PM) { LLVMAddLoopRotatePass(PM); }
--
--API_EXPORT(void)
--LLVMPY_AddInstructionNamerPass(LLVMPassManagerRef PM) {
--    unwrap(PM)->add(createInstructionNamerPass());
--}
--
--} // end extern "C"
-diff --git a/ffi/targets.cpp b/ffi/targets.cpp
-index 36b920adb..60f9ed729 100644
---- a/ffi/targets.cpp
-+++ b/ffi/targets.cpp
-@@ -1,13 +1,12 @@
- #include "core.h"
- #include "llvm-c/Target.h"
- #include "llvm-c/TargetMachine.h"
--#include "llvm/ADT/Optional.h"
--#include "llvm/ADT/Triple.h"
-+#include "llvm/TargetParser/Triple.h"
- #include "llvm/Analysis/TargetLibraryInfo.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/IR/Type.h"
- #include "llvm/MC/TargetRegistry.h"
--#include "llvm/Support/Host.h"
-+#include "llvm/TargetParser/Host.h"
- #include "llvm/Target/TargetMachine.h"
- 
- #include <cstdio>
-@@ -60,9 +59,10 @@ LLVMPY_GetTripleParts(const char *triple_str, const char **arch_out,
-  */
- API_EXPORT(int)
- LLVMPY_GetHostCPUFeatures(const char **Out) {
--    llvm::StringMap<bool> features;
-+    // https://github.com/llvm/llvm-project/pull/97824
-+    llvm::StringMap<bool> features = llvm::sys::getHostCPUFeatures();
-     std::ostringstream buf;
--    if (llvm::sys::getHostCPUFeatures(features)) {
-+    if (!features.empty()) {
-         for (auto &F : features) {
-             if (buf.tellp()) {
-                 buf << ',';
-@@ -147,20 +147,22 @@ LLVMPY_CreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU,
-                            const char *RelocModel, const char *CodeModel,
-                            int PrintMC, int JIT, const char *ABIName) {
-     using namespace llvm;
--    CodeGenOpt::Level cgol;
-+
-+    // https://github.com/llvm/llvm-project/pull/66295
-+    CodeGenOptLevel cgol;
-     switch (OptLevel) {
-     case 0:
--        cgol = CodeGenOpt::None;
-+        cgol = CodeGenOptLevel::None;
-         break;
-     case 1:
--        cgol = CodeGenOpt::Less;
-+        cgol = CodeGenOptLevel::Less;
-         break;
-     case 3:
--        cgol = CodeGenOpt::Aggressive;
-+        cgol = CodeGenOptLevel::Aggressive;
-         break;
-     case 2:
-     default:
--        cgol = CodeGenOpt::Default;
-+        cgol = CodeGenOptLevel::Default;
-     }
- 
-     CodeModel::Model cm;
-@@ -184,7 +186,8 @@ LLVMPY_CreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU,
-             cm = CodeModel::Large;
-     }
- 
--    Optional<Reloc::Model> rm;
-+    // llvm::Optional removed in llvm17
-+    std::optional<Reloc::Model> rm;
-     std::string rms(RelocModel);
-     if (rms == "static")
-         rm = Reloc::Static;
-diff --git a/ffi/transforms.cpp b/ffi/transforms.cpp
-deleted file mode 100644
-index 8d6d7f391..000000000
---- a/ffi/transforms.cpp
-+++ /dev/null
-@@ -1,96 +0,0 @@
--#include "core.h"
--#include "llvm-c/Target.h"
--#include "llvm-c/Transforms/PassManagerBuilder.h"
--#include "llvm/Transforms/IPO/PassManagerBuilder.h"
--
--extern "C" {
--
--API_EXPORT(LLVMPassManagerBuilderRef)
--LLVMPY_PassManagerBuilderCreate() { return LLVMPassManagerBuilderCreate(); }
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) {
--    LLVMPassManagerBuilderDispose(PMB);
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderPopulateModulePassManager(
--    LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) {
--    LLVMPassManagerBuilderPopulateModulePassManager(PMB, PM);
--}
--
--API_EXPORT(unsigned)
--LLVMPY_PassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef PMB) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    return pmb->OptLevel;
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
--                                     unsigned OptLevel) {
--    LLVMPassManagerBuilderSetOptLevel(PMB, OptLevel);
--}
--
--API_EXPORT(unsigned)
--LLVMPY_PassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef PMB) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    return pmb->SizeLevel;
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
--                                      unsigned SizeLevel) {
--    LLVMPassManagerBuilderSetSizeLevel(PMB, SizeLevel);
--}
--
--API_EXPORT(int)
--LLVMPY_PassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    return pmb->DisableUnrollLoops;
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
--                                               LLVMBool Value) {
--    LLVMPassManagerBuilderSetDisableUnrollLoops(PMB, Value);
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
--                                                 unsigned Threshold) {
--    LLVMPassManagerBuilderUseInlinerWithThreshold(PMB, Threshold);
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderPopulateFunctionPassManager(
--    LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) {
--    LLVMPassManagerBuilderPopulateFunctionPassManager(PMB, PM);
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderSetLoopVectorize(LLVMPassManagerBuilderRef PMB,
--                                          int Value) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    pmb->LoopVectorize = Value;
--}
--
--API_EXPORT(int)
--LLVMPY_PassManagerBuilderGetLoopVectorize(LLVMPassManagerBuilderRef PMB) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    return pmb->LoopVectorize;
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderSetSLPVectorize(LLVMPassManagerBuilderRef PMB,
--                                         int Value) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    pmb->SLPVectorize = Value;
--}
--
--API_EXPORT(int)
--LLVMPY_PassManagerBuilderGetSLPVectorize(LLVMPassManagerBuilderRef PMB) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    return pmb->SLPVectorize;
--}
--
--} // end extern "C"
-diff --git a/ffi/value.cpp b/ffi/value.cpp
-index b59e33ae0..0713821a9 100644
---- a/ffi/value.cpp
-+++ b/ffi/value.cpp
-@@ -7,6 +7,7 @@
- // the following is needed for WriteGraph()
- #include "llvm/Analysis/CFGPrinter.h"
- #include "llvm/Support/GraphWriter.h"
-+#include "llvm/IR/GlobalVariable.h"
- 
- /* An iterator around a attribute list, including the stop condition */
- struct AttributeListIterator {
-diff --git a/llvmlite/binding/__init__.py b/llvmlite/binding/__init__.py
-index 2eb177184..10768fe33 100644
---- a/llvmlite/binding/__init__.py
-+++ b/llvmlite/binding/__init__.py
-@@ -8,9 +8,7 @@
- from .module import *
- from .options import *
- from .newpassmanagers import *
--from .passmanagers import *
- from .targets import *
--from .transforms import *
- from .value import *
- from .typeref import *
- from .analysis import *
-diff --git a/llvmlite/binding/initfini.py b/llvmlite/binding/initfini.py
-index 4466d9da2..29f08c949 100644
---- a/llvmlite/binding/initfini.py
-+++ b/llvmlite/binding/initfini.py
-@@ -3,13 +3,6 @@
- from llvmlite.binding import ffi
- 
- 
--def initialize():
--    """
--    Initialize the LLVM core.
--    """
--    ffi.lib.LLVMPY_InitializeCore()
--
--
- def initialize_all_targets():
-     """
-     Initialize all targets. Necessary before targets can be looked up
-diff --git a/llvmlite/binding/newpassmanagers.py b/llvmlite/binding/newpassmanagers.py
-index 1f886924c..7a80e7096 100644
---- a/llvmlite/binding/newpassmanagers.py
-+++ b/llvmlite/binding/newpassmanagers.py
-@@ -1,6 +1,8 @@
--from ctypes import c_bool, c_int, c_size_t, c_char_p, POINTER
-+from ctypes import c_bool, c_int, c_size_t, POINTER, Structure, byref, c_char_p
-+from collections import namedtuple
- from enum import IntFlag
- from llvmlite.binding import ffi
-+from llvmlite.binding.common import _decode_string
- 
- 
- def create_new_module_pass_manager():
-@@ -19,6 +21,84 @@ def create_pipeline_tuning_options(speed_level=2, size_level=0):
-     return PipelineTuningOptions(speed_level, size_level)
- 
- 
-+_prunestats = namedtuple('PruneStats',
-+                         ('basicblock diamond fanout fanout_raise'))
-+
-+
-+class PruneStats(_prunestats):
-+    """ Holds statistics from reference count pruning.
-+    """
-+
-+    def __add__(self, other):
-+        if not isinstance(other, PruneStats):
-+            msg = 'PruneStats can only be added to another PruneStats, got {}.'
-+            raise TypeError(msg.format(type(other)))
-+        return PruneStats(self.basicblock + other.basicblock,
-+                          self.diamond + other.diamond,
-+                          self.fanout + other.fanout,
-+                          self.fanout_raise + other.fanout_raise)
-+
-+    def __sub__(self, other):
-+        if not isinstance(other, PruneStats):
-+            msg = ('PruneStats can only be subtracted from another PruneStats, '
-+                   'got {}.')
-+            raise TypeError(msg.format(type(other)))
-+        return PruneStats(self.basicblock - other.basicblock,
-+                          self.diamond - other.diamond,
-+                          self.fanout - other.fanout,
-+                          self.fanout_raise - other.fanout_raise)
-+
-+
-+class _c_PruneStats(Structure):
-+    _fields_ = [
-+        ('basicblock', c_size_t),
-+        ('diamond', c_size_t),
-+        ('fanout', c_size_t),
-+        ('fanout_raise', c_size_t)]
-+
-+
-+def dump_refprune_stats(printout=False):
-+    """ Returns a namedtuple containing the current values for the refop pruning
-+    statistics. If kwarg `printout` is True the stats are printed to stderr,
-+    default is False.
-+    """
-+
-+    stats = _c_PruneStats(0, 0, 0, 0)
-+    do_print = c_bool(printout)
-+
-+    ffi.lib.LLVMPY_DumpRefPruneStats(byref(stats), do_print)
-+    return PruneStats(stats.basicblock, stats.diamond, stats.fanout,
-+                      stats.fanout_raise)
-+
-+
-+def set_time_passes(enable):
-+    """Enable or disable the pass timers.
-+
-+    Parameters
-+    ----------
-+    enable : bool
-+        Set to True to enable the pass timers.
-+        Set to False to disable the pass timers.
-+    """
-+    ffi.lib.LLVMPY_SetTimePasses(c_bool(enable))
-+
-+
-+def report_and_reset_timings():
-+    """Returns the pass timings report and resets the LLVM internal timers.
-+
-+    Pass timers are enabled by ``set_time_passes()``. If the timers are not
-+    enabled, this function will return an empty string.
-+
-+    Returns
-+    -------
-+    res : str
-+        LLVM generated timing report.
-+    """
-+    with ffi.OutputString() as buf:
-+        ffi.lib.LLVMPY_ReportAndResetTimings(buf)
-+        return str(buf)
-+
-+
- class RefPruneSubpasses(IntFlag):
-     PER_BB       = 0b0001    # noqa: E221
-     DIAMOND      = 0b0010    # noqa: E221
-@@ -27,39 +107,341 @@ class RefPruneSubpasses(IntFlag):
-     ALL = PER_BB | DIAMOND | FANOUT | FANOUT_RAISE
- 
- 
--class ModulePassManager(ffi.ObjectRef):
-+def get_module_level_passes():
-+    passes = _decode_string(ffi.lib.LLVMPY_getModuleLevelPasses())
-+    passes = [p for p in passes.split(' ') if len(p) > 0]
-+    return passes
- 
--    def __init__(self, ptr=None):
--        if ptr is None:
--            ptr = ffi.lib.LLVMPY_CreateNewModulePassManager()
--        super().__init__(ptr)
- 
--    def run(self, module, pb):
--        ffi.lib.LLVMPY_RunNewModulePassManager(self, module, pb)
-+def get_function_level_passes():
-+    passes = _decode_string(ffi.lib.LLVMPY_getFunctionLevelPasses())
-+    passes = [p for p in passes.split(' ') if len(p) > 0]
-+    return passes
- 
--    def add_verifier(self):
--        ffi.lib.LLVMPY_AddVerifierPass(self)
-+
-+class NewPassManager():
-+
-+    def __init__(self):
-+        if type(self) is NewPassManager:
-+            raise TypeError("Cannot instantiate NewPassManager directly")
-+
-+    def run(self,IR, pb):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_RunNewModulePassManager(self, IR, pb)
-+        else:
-+            ffi.lib.LLVMPY_RunNewFunctionPassManager(self, IR, pb)
- 
-     def add_aa_eval_pass(self):
--        ffi.lib.LLVMPY_AddAAEvalPass_module(self)
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddAAEvaluator(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddAAEvaluator(self)
- 
-     def add_simplify_cfg_pass(self):
--        ffi.lib.LLVMPY_AddSimplifyCFGPass_module(self)
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddSimplifyCFGPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddSimplifyCFGPass(self)
- 
-     def add_loop_unroll_pass(self):
--        ffi.lib.LLVMPY_AddLoopUnrollPass_module(self)
--
--    def add_loop_rotate_pass(self):
--        ffi.lib.LLVMPY_AddLoopRotatePass_module(self)
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLoopUnrollPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLoopUnrollPass(self)
- 
-     def add_instruction_combine_pass(self):
--        ffi.lib.LLVMPY_AddInstructionCombinePass_module(self)
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddInstCombinePass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddInstCombinePass(self)
- 
-     def add_jump_threading_pass(self, threshold=-1):
--        ffi.lib.LLVMPY_AddJumpThreadingPass_module(self, threshold)
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_AddJumpThreadingPass_module(self, threshold)
-+        else:
-+            ffi.lib.LLVMPY_AddJumpThreadingPass_function(self, threshold)
-+
-+    def add_cfg_printer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddCFGPrinterPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddCFGPrinterPass(self)
-+
-+    def add_cfg_only_printer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddCFGOnlyPrinterPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddCFGOnlyPrinterPass(self)
-+
-+    def add_dom_printer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddDomPrinter(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddDomPrinter(self)
-+
-+    def add_dom_only_printer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddDomOnlyPrinter(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddDomOnlyPrinter(self)
-+
-+    def add_post_dom_printer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddPostDomPrinter(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddPostDomPrinter(self)
-+
-+    def add_post_dom_only_printer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddPostDomOnlyPrinter(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddPostDomOnlyPrinter(self)
-+
-+    def add_dom_viewer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddDomViewer(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddDomViewer(self)
-+
-+    def add_dom_only_viewer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddDomOnlyViewer(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddDomOnlyViewer(self)
-+
-+    def add_post_dom_viewer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddPostDomViewer(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddPostDomViewer(self)
-+
-+    def add_post_dom_only_viewer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddPostDomOnlyViewer(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddPostDomOnlyViewer(self)
-+
-+    def add_lint_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLintPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLintPass(self)
-+
-+    def add_aggressive_dce_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddADCEPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddADCEPass(self)
-+
-+    def add_break_critical_edges_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddBreakCriticalEdgesPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddBreakCriticalEdgesPass(self)
-+
-+    def add_dead_store_elimination_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddDSEPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddDSEPass(self)
-+
-+    def add_dead_code_elimination_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddDCEPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddDCEPass(self)
-+
-+    def add_aggressive_instcombine_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddAggressiveInstCombinePass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddAggressiveInstCombinePass(self)
-+
-+    def add_lcssa_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLCSSAPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLCSSAPass(self)
-+
-+    def add_new_gvn_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddNewGVNPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddNewGVNPass(self)
-+
-+    def add_loop_simplify_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLoopSimplifyPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLoopSimplifyPass(self)
-+
-+    def add_sccp_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddSCCPPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddSCCPPass(self)
-+
-+    def add_lower_atomic_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLowerAtomicPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLowerAtomicPass(self)
-+
-+    def add_lower_invoke_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLowerInvokePass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLowerInvokePass(self)
-+
-+    def add_lower_switch_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLowerSwitchPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLowerSwitchPass(self)
-+
-+    def add_mem_copy_opt_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddMemCpyOptPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddMemCpyOptPass(self)
-+
-+    def add_unify_function_exit_nodes_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddUnifyFunctionExitNodesPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddUnifyFunctionExitNodesPass(self)
-+
-+    def add_reassociate_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddReassociatePass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddReassociatePass(self)
-+
-+    def add_register_to_memory_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddRegToMemPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddRegToMemPass(self)
-+
-+    # FIXME: SROA now takes parameter whether to preserve cfg or not
-+    # https://reviews.llvm.org/D138238
-+    # def add_sroa_pass(self):
-+    #     if isinstance(self, ModulePassManager):
-+    #         ffi.lib.LLVMPY_module_AddSROAPass(self)
-+    #     else:
-+    #         ffi.lib.LLVMPY_function_AddSROAPass(self)
-+
-+    def add_sinking_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddSinkingPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddSinkingPass(self)
-+
-+    def add_tail_call_elimination_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddTailCallElimPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddTailCallElimPass(self)
-+
-+    def add_instruction_namer_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddInstructionNamerPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddInstructionNamerPass(self)
-+
-+    def add_loop_deletion_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLoopDeletionPass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLoopDeletionPass(self)
-+
-+    def add_loop_strength_reduce_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLoopStrengthReducePass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLoopStrengthReducePass(self)
-+
-+    def add_loop_rotate_pass(self):
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_module_AddLoopRotatePass(self)
-+        else:
-+            ffi.lib.LLVMPY_function_AddLoopRotatePass(self)
- 
-     def _dispose(self):
--        ffi.lib.LLVMPY_DisposeNewModulePassManger(self)
-+        if isinstance(self, ModulePassManager):
-+            ffi.lib.LLVMPY_DisposeNewModulePassManger(self)
-+        else:
-+            ffi.lib.LLVMPY_DisposeNewFunctionPassManger(self)
-+
-+
-+class ModulePassManager(ffi.ObjectRef, NewPassManager):
-+
-+    def __init__(self, ptr=None):
-+        if ptr is None:
-+            ptr = ffi.lib.LLVMPY_CreateNewModulePassManager()
-+        super().__init__(ptr)
-+
-+    def add_verifier(self):
-+        ffi.lib.LLVMPY_module_AddVerifierPass(self)
-+
-+    def add_constant_merge_pass(self):
-+        ffi.lib.LLVMPY_module_AddConstantMergePass(self)
-+
-+    def add_dead_arg_elimination_pass(self):
-+        ffi.lib.LLVMPY_module_AddDeadArgumentEliminationPass(self)
-+
-+    def add_dot_call_graph_printer_pass(self):
-+        ffi.lib.LLVMPY_module_AddCallGraphDOTPrinterPass(self)
-+
-+    # TODO: There are a lot more printer passes in llvm that can be exposed
-+    # FIXME: Find a way to write the output to a buffer instead of stdout
-+    def add_module_debug_info_pass(self):
-+        ffi.lib.LLVMPY_module_AddModuleDebugInfoPrinterPass(self)
-+
-+    def add_always_inliner_pass(self):
-+        ffi.lib.LLVMPY_module_AddAlwaysInlinerPass(self)
-+
-+    def add_rpo_function_attrs_pass(self):
-+        ffi.lib.LLVMPY_module_AddReversePostOrderFunctionAttrsPass(self)
-+
-+    def add_global_dead_code_eliminate_pass(self):
-+        ffi.lib.LLVMPY_module_AddGlobalDCEPass(self)
-+
-+    def add_global_opt_pass(self):
-+        ffi.lib.LLVMPY_module_AddGlobalOptPass(self)
-+
-+    def add_ipsccp_pass(self):
-+        ffi.lib.LLVMPY_module_AddIPSCCPPass(self)
-+
-+    def add_internalize_pass(self):
-+        ffi.lib.LLVMPY_module_AddInternalizePass(self)
-+
-+    def add_merge_functions_pass(self):
-+        ffi.lib.LLVMPY_module_AddMergeFunctionsPass(self)
-+
-+    def add_partial_inliner_pass(self):
-+        ffi.lib.LLVMPY_module_AddPartialInlinerPass(self)
-+
-+    def add_strip_symbols_pass(self):
-+        ffi.lib.LLVMPY_module_AddStripSymbolsPass(self)
-+
-+    def add_strip_dead_debug_info_pass(self):
-+        ffi.lib.LLVMPY_module_AddStripDeadDebugInfoPass(self)
-+
-+    def add_strip_dead_prototype_pass(self):
-+        ffi.lib.LLVMPY_module_AddStripDeadPrototypesPass(self)
-+
-+    def add_strip_debug_declare_pass(self):
-+        ffi.lib.LLVMPY_module_AddStripDebugDeclarePass(self)
-+
-+    def add_strip_non_debug_symbols_pass(self):
-+        ffi.lib.LLVMPY_module_AddStripNonDebugSymbolsPass(self)
-+
-+    def add_argument_promotion_pass(self):
-+        ffi.lib.LLVMPY_module_AddArgumentPromotionPass(self)
-+
-+    def add_post_order_function_attributes_pass(self):
-+        ffi.lib.LLVMPY_module_AddPostOrderFunctionAttrsPass(self)
- 
-     # Non-standard LLVM passes
-     def add_refprune_pass(self, subpasses_flags=RefPruneSubpasses.ALL,
-@@ -80,37 +462,13 @@ def add_refprune_pass(self, subpasses_flags=RefPruneSubpasses.ALL,
-         ffi.lib.LLVMPY_AddRefPrunePass_module(self, iflags, subgraph_limit)
- 
- 
--class FunctionPassManager(ffi.ObjectRef):
-+class FunctionPassManager(ffi.ObjectRef, NewPassManager):
- 
-     def __init__(self, ptr=None):
-         if ptr is None:
-             ptr = ffi.lib.LLVMPY_CreateNewFunctionPassManager()
-         super().__init__(ptr)
- 
--    def run(self, fun, pb):
--        ffi.lib.LLVMPY_RunNewFunctionPassManager(self, fun, pb)
--
--    def add_aa_eval_pass(self):
--        ffi.lib.LLVMPY_AddAAEvalPass_function(self)
--
--    def add_simplify_cfg_pass(self):
--        ffi.lib.LLVMPY_AddSimplifyCFGPass_function(self)
--
--    def add_loop_unroll_pass(self):
--        ffi.lib.LLVMPY_AddLoopUnrollPass_function(self)
--
--    def add_loop_rotate_pass(self):
--        ffi.lib.LLVMPY_AddLoopRotatePass_function(self)
--
--    def add_instruction_combine_pass(self):
--        ffi.lib.LLVMPY_AddInstructionCombinePass_function(self)
--
--    def add_jump_threading_pass(self, threshold=-1):
--        ffi.lib.LLVMPY_AddJumpThreadingPass_function(self, threshold)
--
--    def _dispose(self):
--        ffi.lib.LLVMPY_DisposeNewFunctionPassManger(self)
--
-     # Non-standard LLVM passes
-     def add_refprune_pass(self, subpasses_flags=RefPruneSubpasses.ALL,
-                           subgraph_limit=1000):
-@@ -195,14 +553,13 @@ def loop_unrolling(self):
-     def loop_unrolling(self, value):
-         ffi.lib.LLVMPY_PTOSetLoopUnrolling(self, value)
- 
--    # // FIXME: Available from llvm16
--    # @property
--    # def inlining_threshold(self):
--    #     return ffi.lib.LLVMPY_PTOGetInlinerThreshold(self)
-+    @property
-+    def inlining_threshold(self):
-+        return ffi.lib.LLVMPY_PTOGetInlinerThreshold(self)
- 
--    # @inlining_threshold.setter
--    # def inlining_threshold(self, value):
--    #     ffi.lib.LLVMPY_PTOSetInlinerThreshold(self, value)
-+    @inlining_threshold.setter
-+    def inlining_threshold(self, value):
-+        ffi.lib.LLVMPY_PTOSetInlinerThreshold(self, value)
- 
-     def _dispose(self):
-         ffi.lib.LLVMPY_DisposePipelineTuningOptions(self)
-@@ -275,6 +632,8 @@ def _dispose(self):
- # ============================================================================
- # FFI
- 
-+ffi.lib.LLVMPY_DumpRefPruneStats.argtypes = [POINTER(_c_PruneStats), c_bool]
-+
- # ModulePassManager
- 
- ffi.lib.LLVMPY_CreateNewModulePassManager.restype = ffi.LLVMModulePassManagerRef
-@@ -283,23 +642,179 @@ def _dispose(self):
-     ffi.LLVMModulePassManagerRef, ffi.LLVMModuleRef,
-     ffi.LLVMPassBuilderRef,]
- 
--ffi.lib.LLVMPY_AddVerifierPass.argtypes = [ffi.LLVMModulePassManagerRef,]
--ffi.lib.LLVMPY_AddAAEvalPass_module.argtypes = [ffi.LLVMModulePassManagerRef,]
--ffi.lib.LLVMPY_AddSimplifyCFGPass_module.argtypes = [
-+ffi.lib.LLVMPY_module_AddVerifierPass.argtypes = [ffi.LLVMModulePassManagerRef,]
-+ffi.lib.LLVMPY_module_AddAAEvaluator.argtypes = [ffi.LLVMModulePassManagerRef,]
-+ffi.lib.LLVMPY_module_AddSimplifyCFGPass.argtypes = [
-     ffi.LLVMModulePassManagerRef,]
- 
--ffi.lib.LLVMPY_AddLoopUnrollPass_module.argtypes = [
-+ffi.lib.LLVMPY_module_AddLoopUnrollPass.argtypes = [
-     ffi.LLVMModulePassManagerRef,]
- 
--ffi.lib.LLVMPY_AddLoopRotatePass_module.argtypes = [
-+ffi.lib.LLVMPY_module_AddLoopRotatePass.argtypes = [
-     ffi.LLVMModulePassManagerRef,]
- 
--ffi.lib.LLVMPY_AddInstructionCombinePass_module.argtypes = [
-+ffi.lib.LLVMPY_module_AddInstCombinePass.argtypes = [
-     ffi.LLVMModulePassManagerRef,]
- 
- ffi.lib.LLVMPY_AddJumpThreadingPass_module.argtypes = [
-     ffi.LLVMModulePassManagerRef,]
- 
-+ffi.lib.LLVMPY_module_AddCFGPrinterPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddCFGOnlyPrinterPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddDomPrinter.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddDomOnlyPrinter.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddPostDomPrinter.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddPostDomOnlyPrinter.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddDomViewer.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddDomOnlyViewer.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddPostDomViewer.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddPostDomOnlyViewer.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLintPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddADCEPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddBreakCriticalEdgesPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddDSEPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddDCEPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddAggressiveInstCombinePass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLCSSAPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddNewGVNPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLoopSimplifyPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddSCCPPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLowerAtomicPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLowerInvokePass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLowerSwitchPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddMemCpyOptPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddUnifyFunctionExitNodesPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddReassociatePass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddRegToMemPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+# ffi.lib.LLVMPY_module_AddSROAPass.argtypes = [
-+#     ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddSinkingPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddTailCallElimPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddInstructionNamerPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLoopDeletionPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddLoopStrengthReducePass.argtypes = [
-+    ffi.LLVMModulePassManagerRef,]
-+
-+ffi.lib.LLVMPY_module_AddConstantMergePass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddDeadArgumentEliminationPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddCallGraphDOTPrinterPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddModuleDebugInfoPrinterPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddAlwaysInlinerPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddReversePostOrderFunctionAttrsPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddGlobalDCEPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddGlobalOptPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddIPSCCPPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddInternalizePass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddMergeFunctionsPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddPartialInlinerPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddStripSymbolsPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddStripDeadDebugInfoPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddStripDeadPrototypesPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddStripDebugDeclarePass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddStripNonDebugSymbolsPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddArgumentPromotionPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
-+ffi.lib.LLVMPY_module_AddPostOrderFunctionAttrsPass.argtypes = [
-+    ffi.LLVMModulePassManagerRef, ]
-+
- ffi.lib.LLVMPY_DisposeNewModulePassManger.argtypes = [
-     ffi.LLVMModulePassManagerRef,]
- 
-@@ -316,24 +831,124 @@ def _dispose(self):
-     ffi.LLVMFunctionPassManagerRef, ffi.LLVMValueRef,
-     ffi.LLVMPassBuilderRef,]
- 
--ffi.lib.LLVMPY_AddAAEvalPass_function.argtypes = [
--    ffi.LLVMFunctionPassManagerRef,]
--
--ffi.lib.LLVMPY_AddSimplifyCFGPass_function.argtypes = [
-+ffi.lib.LLVMPY_function_AddAAEvaluator.argtypes = [
-     ffi.LLVMFunctionPassManagerRef,]
- 
--ffi.lib.LLVMPY_AddLoopUnrollPass_function.argtypes = [
-+ffi.lib.LLVMPY_function_AddSimplifyCFGPass.argtypes = [
-     ffi.LLVMFunctionPassManagerRef,]
- 
--ffi.lib.LLVMPY_AddLoopRotatePass_function.argtypes = [
-+ffi.lib.LLVMPY_function_AddLoopUnrollPass.argtypes = [
-     ffi.LLVMFunctionPassManagerRef,]
- 
--ffi.lib.LLVMPY_AddInstructionCombinePass_function.argtypes = [
-+ffi.lib.LLVMPY_function_AddInstCombinePass.argtypes = [
-     ffi.LLVMFunctionPassManagerRef,]
- 
- ffi.lib.LLVMPY_AddJumpThreadingPass_function.argtypes = [
-     ffi.LLVMFunctionPassManagerRef, c_int,]
- 
-+ffi.lib.LLVMPY_function_AddCFGPrinterPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddCFGOnlyPrinterPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddDomPrinter.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddDomOnlyPrinter.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddPostDomPrinter.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddPostDomOnlyPrinter.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddDomViewer.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddDomOnlyViewer.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddPostDomViewer.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddPostDomOnlyViewer.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLintPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddADCEPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddBreakCriticalEdgesPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddDSEPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddDCEPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddAggressiveInstCombinePass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLCSSAPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddNewGVNPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLoopSimplifyPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddSCCPPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLowerAtomicPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLowerInvokePass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLowerSwitchPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddMemCpyOptPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddUnifyFunctionExitNodesPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddReassociatePass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddRegToMemPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+# FIXME SROA is disabled
-+# ffi.lib.LLVMPY_function_AddSROAPass.argtypes = [
-+#     ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddSinkingPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddTailCallElimPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddInstructionNamerPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLoopRotatePass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLoopDeletionPass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
-+ffi.lib.LLVMPY_function_AddLoopStrengthReducePass.argtypes = [
-+    ffi.LLVMFunctionPassManagerRef, ]
-+
- ffi.lib.LLVMPY_DisposeNewFunctionPassManger.argtypes = [
-     ffi.LLVMFunctionPassManagerRef,]
- 
-@@ -407,10 +1022,15 @@ def _dispose(self):
- 
- ffi.lib.LLVMPY_buildPerModuleDefaultPipeline.restype = \
-     ffi.LLVMModulePassManagerRef
-+
- ffi.lib.LLVMPY_buildPerModuleDefaultPipeline.argtypes = [
-     ffi.LLVMPassBuilderRef, c_int, c_int]
- 
- ffi.lib.LLVMPY_buildFunctionSimplificationPipeline.restype = \
-     ffi.LLVMFunctionPassManagerRef
-+
- ffi.lib.LLVMPY_buildFunctionSimplificationPipeline.argtypes = [
-     ffi.LLVMPassBuilderRef, c_int, c_int]
-+
-+ffi.lib.LLVMPY_getFunctionLevelPasses.restype = c_char_p
-+ffi.lib.LLVMPY_getModuleLevelPasses.restype = c_char_p
-diff --git a/llvmlite/binding/passmanagers.py b/llvmlite/binding/passmanagers.py
-deleted file mode 100644
-index 0ce61aefc..000000000
---- a/llvmlite/binding/passmanagers.py
-+++ /dev/null
-@@ -1,946 +0,0 @@
--from ctypes import (c_bool, c_char_p, c_int, c_size_t, Structure, byref,
--                    POINTER)
--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
--
--llvm_version_major = llvm_version_info[0]
--
--_prunestats = namedtuple('PruneStats',
--                         ('basicblock diamond fanout fanout_raise'))
--
--
--class PruneStats(_prunestats):
--    """ Holds statistics from reference count pruning.
--    """
--
--    def __add__(self, other):
--        if not isinstance(other, PruneStats):
--            msg = 'PruneStats can only be added to another PruneStats, got {}.'
--            raise TypeError(msg.format(type(other)))
--        return PruneStats(self.basicblock + other.basicblock,
--                          self.diamond + other.diamond,
--                          self.fanout + other.fanout,
--                          self.fanout_raise + other.fanout_raise)
--
--    def __sub__(self, other):
--        if not isinstance(other, PruneStats):
--            msg = ('PruneStats can only be subtracted from another PruneStats, '
--                   'got {}.')
--            raise TypeError(msg.format(type(other)))
--        return PruneStats(self.basicblock - other.basicblock,
--                          self.diamond - other.diamond,
--                          self.fanout - other.fanout,
--                          self.fanout_raise - other.fanout_raise)
--
--
--class _c_PruneStats(Structure):
--    _fields_ = [
--        ('basicblock', c_size_t),
--        ('diamond', c_size_t),
--        ('fanout', c_size_t),
--        ('fanout_raise', c_size_t)]
--
--
--def dump_refprune_stats(printout=False):
--    """ Returns a namedtuple containing the current values for the refop pruning
--    statistics. If kwarg `printout` is True the stats are printed to stderr,
--    default is False.
--    """
--
--    stats = _c_PruneStats(0, 0, 0, 0)
--    do_print = c_bool(printout)
--
--    ffi.lib.LLVMPY_DumpRefPruneStats(byref(stats), do_print)
--    return PruneStats(stats.basicblock, stats.diamond, stats.fanout,
--                      stats.fanout_raise)
--
--
--def set_time_passes(enable):
--    """Enable or disable the pass timers.
--
--    Parameters
--    ----------
--    enable : bool
--        Set to True to enable the pass timers.
--        Set to False to disable the pass timers.
--    """
--    ffi.lib.LLVMPY_SetTimePasses(c_bool(enable))
--
--
--def report_and_reset_timings():
--    """Returns the pass timings report and resets the LLVM internal timers.
--
--    Pass timers are enabled by ``set_time_passes()``. If the timers are not
--    enabled, this function will return an empty string.
--
--    Returns
--    -------
--    res : str
--        LLVM generated timing report.
--    """
--    with ffi.OutputString() as buf:
--        ffi.lib.LLVMPY_ReportAndResetTimings(buf)
--        return str(buf)
--
--
--def create_module_pass_manager():
--    return ModulePassManager()
--
--
--def create_function_pass_manager(module):
--    return FunctionPassManager(module)
--
--
--class RefPruneSubpasses(IntFlag):
--    PER_BB       = 0b0001    # noqa: E221
--    DIAMOND      = 0b0010    # noqa: E221
--    FANOUT       = 0b0100    # noqa: E221
--    FANOUT_RAISE = 0b1000
--    ALL = PER_BB | DIAMOND | FANOUT | FANOUT_RAISE
--
--
--class PassManager(ffi.ObjectRef):
--    """PassManager
--    """
--
--    def _dispose(self):
--        self._capi.LLVMPY_DisposePassManager(self)
--
--    def add_aa_eval_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#aa-eval-exhaustive-alias-analysis-precision-evaluator
--
--        LLVM 14: `llvm::createAAEvalPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddAAEvalPass(self)
--
--    def add_basic_aa_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#basic-aa-basic-alias-analysis-stateless-aa-impl
--
--        LLVM 14: `llvm::createBasicAAWrapperPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddBasicAAWrapperPass(self)
--
--    def add_constant_merge_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#constmerge-merge-duplicate-global-constants
--
--        LLVM 14: `LLVMAddConstantMergePass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddConstantMergePass(self)
--
--    def add_dead_arg_elimination_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#deadargelim-dead-argument-elimination
--
--        LLVM 14: `LLVMAddDeadArgEliminationPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddDeadArgEliminationPass(self)
--
--    def add_dependence_analysis_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#da-dependence-analysis
--
--        LLVM 14: `llvm::createDependenceAnalysisWrapperPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddDependenceAnalysisPass(self)
--
--    def add_dot_call_graph_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#dot-callgraph-print-call-graph-to-dot-file
--
--        LLVM 14: `llvm::createCallGraphDOTPrinterPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddCallGraphDOTPrinterPass(self)
--
--    def add_dot_cfg_printer_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#dot-cfg-print-cfg-of-function-to-dot-file
--
--        LLVM 14: `llvm::createCFGPrinterLegacyPassPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddCFGPrinterPass(self)
--
--    def add_dot_dom_printer_pass(self, show_body=False):
--        """
--        See https://llvm.org/docs/Passes.html#dot-dom-print-dominance-tree-of-function-to-dot-file
--
--        LLVM 14: `llvm::createDomPrinterPass` and `llvm::createDomOnlyPrinterPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddDotDomPrinterPass(self, show_body)
--
--    def add_dot_postdom_printer_pass(self, show_body=False):
--        """
--        See https://llvm.org/docs/Passes.html#dot-postdom-print-postdominance-tree-of-function-to-dot-file
--
--        LLVM 14: `llvm::createPostDomPrinterPass` and `llvm::createPostDomOnlyPrinterPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddDotPostDomPrinterPass(self, show_body)
--
--    def add_globals_mod_ref_aa_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#globalsmodref-aa-simple-mod-ref-analysis-for-globals
--
--        LLVM 14: `llvm::createGlobalsAAWrapperPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddGlobalsModRefAAPass(self)
--
--    def add_iv_users_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#iv-users-induction-variable-users
--
--        LLVM 14: `llvm::createIVUsersPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddIVUsersPass(self)
--
--    def add_lint_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#lint-statically-lint-checks-llvm-ir
--
--        LLVM 14: `llvm::createLintLegacyPassPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLintPass(self)
--
--    def add_lazy_value_info_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#lazy-value-info-lazy-value-information-analysis
--
--        LLVM 14: `llvm::createLazyValueInfoPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLazyValueInfoPass(self)
--
--    def add_module_debug_info_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#module-debuginfo-decodes-module-level-debug-info
--
--        LLVM 14: `llvm::createModuleDebugInfoPrinterPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddModuleDebugInfoPrinterPass(self)
--
--    def add_region_info_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#regions-detect-single-entry-single-exit-regions
--
--        LLVM 14: `llvm::createRegionInfoPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddRegionInfoPass(self)
--
--    def add_scalar_evolution_aa_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#scev-aa-scalarevolution-based-alias-analysis
--
--        LLVM 14: `llvm::createSCEVAAWrapperPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddScalarEvolutionAAPass(self)
--
--    def add_aggressive_dead_code_elimination_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#adce-aggressive-dead-code-elimination
--
--        LLVM 14: `llvm::createAggressiveDCEPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddAggressiveDCEPass(self)
--
--    def add_always_inliner_pass(self, insert_lifetime=True):
--        """
--        See https://llvm.org/docs/Passes.html#always-inline-inliner-for-always-inline-functions
--
--        LLVM 14: `llvm::createAlwaysInlinerLegacyPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddAlwaysInlinerPass(self, insert_lifetime)
--
--    def add_arg_promotion_pass(self, max_elements=3):
--        """
--        See https://llvm.org/docs/Passes.html#argpromotion-promote-by-reference-arguments-to-scalars
--
--        LLVM 14: `llvm::createArgumentPromotionPass`
--        """  # noqa E501
--        raise RuntimeError('ArgumentPromotionPass unavailable in LLVM > 14')
--
--    def add_break_critical_edges_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#break-crit-edges-break-critical-edges-in-cfg
--
--        LLVM 14: `llvm::createBreakCriticalEdgesPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddBreakCriticalEdgesPass(self)
--
--    def add_dead_store_elimination_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#dse-dead-store-elimination
--
--        LLVM 14: `llvm::createDeadStoreEliminationPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddDeadStoreEliminationPass(self)
--
--    def add_reverse_post_order_function_attrs_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#function-attrs-deduce-function-attributes
--
--        LLVM 14: `llvm::createReversePostOrderFunctionAttrsPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddReversePostOrderFunctionAttrsPass(self)
--
--    def add_function_attrs_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#functionattrs-deduce-function-attributes
--
--        LLVM 14: `LLVMAddFunctionAttrsPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddFunctionAttrsPass(self)
--
--    def add_function_inlining_pass(self, threshold):
--        """
--        See http://llvm.org/docs/Passes.html#inline-function-integration-inlining
--
--        LLVM 14: `createFunctionInliningPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddFunctionInliningPass(self, threshold)
--
--    def add_global_dce_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#globaldce-dead-global-elimination
--
--        LLVM 14: `LLVMAddGlobalDCEPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddGlobalDCEPass(self)
--
--    def add_global_optimizer_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#globalopt-global-variable-optimizer
--
--        LLVM 14: `LLVMAddGlobalOptimizerPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddGlobalOptimizerPass(self)
--
--    def add_ipsccp_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#ipsccp-interprocedural-sparse-conditional-constant-propagation
--
--        LLVM 14: `LLVMAddIPSCCPPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddIPSCCPPass(self)
--
--    def add_dead_code_elimination_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#dce-dead-code-elimination
--        LLVM 14: `llvm::createDeadCodeEliminationPass`
--        """
--        ffi.lib.LLVMPY_AddDeadCodeEliminationPass(self)
--
--    def add_aggressive_instruction_combining_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#aggressive-instcombine-combine-expression-patterns
--
--        LLVM 14: `llvm::createAggressiveInstCombinerPass`
--        """  # noqa E501
--        if llvm_version_major > 15:
--            msg = "AggressiveInstrCombinerPass unavailable in LLVM > 15"
--            raise RuntimeError(msg)
--
--        ffi.lib.LLVMPY_AddAggressiveInstructionCombiningPass(self)
--
--    def add_internalize_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#internalize-internalize-global-symbols
--
--        LLVM 14: `llvm::createInternalizePass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddInternalizePass(self)
--
--    def add_cfg_simplification_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#simplifycfg-simplify-the-cfg
--
--        LLVM 14: `LLVMAddCFGSimplificationPass`
--        """
--        ffi.lib.LLVMPY_AddCFGSimplificationPass(self)
--
--    def add_jump_threading_pass(self, threshold=-1):
--        """
--        See https://llvm.org/docs/Passes.html#jump-threading-jump-threading
--
--        LLVM 14: `llvm::createJumpThreadingPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddJumpThreadingPass(self, threshold)
--
--    def add_lcssa_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#lcssa-loop-closed-ssa-form-pass
--
--        LLVM 14: `llvm::createLCSSAPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLCSSAPass(self)
--
--    def add_gvn_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#gvn-global-value-numbering
--
--        LLVM 14: `LLVMAddGVNPass`
--        """
--        ffi.lib.LLVMPY_AddGVNPass(self)
--
--    def add_instruction_combining_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#passes-instcombine
--
--        LLVM 14: `LLVMAddInstructionCombiningPass`
--        """
--        ffi.lib.LLVMPY_AddInstructionCombiningPass(self)
--
--    def add_licm_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#licm-loop-invariant-code-motion
--
--        LLVM 14: `LLVMAddLICMPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLICMPass(self)
--
--    def add_loop_deletion_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loop-deletion-delete-dead-loops
--
--        LLVM 14: `llvm::createLoopDeletionPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLoopDeletionPass(self)
--
--    def add_loop_extractor_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loop-extract-extract-loops-into-new-functions
--
--        LLVM 14: `llvm::createLoopExtractorPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLoopExtractorPass(self)
--
--    def add_single_loop_extractor_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loop-extract-single-extract-at-most-one-loop-into-a-new-function
--
--        LLVM 14: `llvm::createSingleLoopExtractorPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddSingleLoopExtractorPass(self)
--
--    def add_sccp_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#sccp-sparse-conditional-constant-propagation
--
--        LLVM 14: `LLVMAddSCCPPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddSCCPPass(self)
--
--    def add_loop_strength_reduce_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loop-reduce-loop-strength-reduction
--
--        LLVM 14: `llvm::createLoopStrengthReducePass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLoopStrengthReducePass(self)
--
--    def add_loop_simplification_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loop-simplify-canonicalize-natural-loops
--
--        LLVM 14: `llvm::createLoopSimplifyPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLoopSimplificationPass(self)
--
--    def add_loop_unroll_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loop-unroll-unroll-loops
--
--        LLVM 14: `LLVMAddLoopUnrollPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLoopUnrollPass(self)
--
--    def add_loop_unroll_and_jam_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loop-unroll-and-jam-unroll-and-jam-loops
--
--        LLVM 14: `LLVMAddLoopUnrollAndJamPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLoopUnrollAndJamPass(self)
--
--    def add_loop_unswitch_pass(self,
--                               optimize_for_size=False,
--                               has_branch_divergence=False):
--        """
--        See https://llvm.org/docs/Passes.html#loop-unswitch-unswitch-loops
--
--        LLVM 14: `llvm::createLoopUnswitchPass`
--        LLVM 15: `llvm::createSimpleLoopUnswitchLegacyPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLoopUnswitchPass(self, optimize_for_size,
--                                           has_branch_divergence)
--
--    def add_lower_atomic_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#loweratomic-lower-atomic-intrinsics-to-non-atomic-form
--
--        LLVM 14: `llvm::createLowerAtomicPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLowerAtomicPass(self)
--
--    def add_lower_invoke_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#lowerinvoke-lower-invokes-to-calls-for-unwindless-code-generators
--
--        LLVM 14: `llvm::createLowerInvokePass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLowerInvokePass(self)
--
--    def add_lower_switch_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#lowerswitch-lower-switchinsts-to-branches
--
--        LLVM 14: `llvm::createLowerSwitchPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddLowerSwitchPass(self)
--
--    def add_memcpy_optimization_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#memcpyopt-memcpy-optimization
--
--        LLVM 14: `llvm::createMemCpyOptPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddMemCpyOptimizationPass(self)
--
--    def add_merge_functions_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#mergefunc-merge-functions
--
--        LLVM 14: `llvm::createMergeFunctionsPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddMergeFunctionsPass(self)
--
--    def add_merge_returns_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#mergereturn-unify-function-exit-nodes
--
--        LLVM 14: `llvm::createUnifyFunctionExitNodesPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddMergeReturnsPass(self)
--
--    def add_partial_inlining_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#partial-inliner-partial-inliner
--
--        LLVM 14: `llvm::createPartialInliningPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddPartialInliningPass(self)
--
--    def add_prune_exception_handling_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#prune-eh-remove-unused-exception-handling-info
--
--        LLVM 14: `llvm::createPruneEHPass`
--        """  # noqa E501
--        if llvm_version_major > 15:
--            raise RuntimeError("PruneEHPass unavailable in LLVM > 15")
--        ffi.lib.LLVMPY_AddPruneExceptionHandlingPass(self)
--
--    def add_reassociate_expressions_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#reassociate-reassociate-expressions
--
--        LLVM 14: `llvm::createReassociatePass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddReassociatePass(self)
--
--    def add_demote_register_to_memory_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#rel-lookup-table-converter-relative-lookup-table-converter
--
--        LLVM 14: `llvm::createDemoteRegisterToMemoryPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddDemoteRegisterToMemoryPass(self)
--
--    def add_sroa_pass(self):
--        """
--        See http://llvm.org/docs/Passes.html#scalarrepl-scalar-replacement-of-aggregates-dt
--        Note that this pass corresponds to the ``opt -sroa`` command-line option,
--        despite the link above.
--
--        LLVM 14: `llvm::createSROAPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddSROAPass(self)
--
--    def add_sink_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#sink-code-sinking
--
--        LLVM 14: `llvm::createSinkingPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddSinkPass(self)
--
--    def add_strip_symbols_pass(self, only_debug=False):
--        """
--        See https://llvm.org/docs/Passes.html#strip-strip-all-symbols-from-a-module
--
--        LLVM 14: `llvm::createStripSymbolsPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddStripSymbolsPass(self, only_debug)
--
--    def add_strip_dead_debug_info_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#strip-dead-debug-info-strip-debug-info-for-unused-symbols
--
--        LLVM 14: `llvm::createStripDeadDebugInfoPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddStripDeadDebugInfoPass(self)
--
--    def add_strip_dead_prototypes_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#strip-dead-prototypes-strip-unused-function-prototypes
--
--        LLVM 14: `llvm::createStripDeadPrototypesPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddStripDeadPrototypesPass(self)
--
--    def add_strip_debug_declare_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#strip-debug-declare-strip-all-llvm-dbg-declare-intrinsics
--
--        LLVM 14: `llvm::createStripDebugDeclarePass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddStripDebugDeclarePrototypesPass(self)
--
--    def add_strip_nondebug_symbols_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#strip-nondebug-strip-all-symbols-except-dbg-symbols-from-a-module
--
--        LLVM 14: `llvm::createStripNonDebugSymbolsPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddStripNondebugSymbolsPass(self)
--
--    def add_tail_call_elimination_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#tailcallelim-tail-call-elimination
--
--        LLVM 14: `llvm::createTailCallEliminationPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddTailCallEliminationPass(self)
--
--    def add_type_based_alias_analysis_pass(self):
--        """
--        LLVM 14: `LLVMAddTypeBasedAliasAnalysisPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddTypeBasedAliasAnalysisPass(self)
--
--    def add_basic_alias_analysis_pass(self):
--        """
--        See http://llvm.org/docs/AliasAnalysis.html#the-basicaa-pass
--
--        LLVM 14: `LLVMAddBasicAliasAnalysisPass`
--        """
--        ffi.lib.LLVMPY_AddBasicAliasAnalysisPass(self)
--
--    def add_loop_rotate_pass(self):
--        """http://llvm.org/docs/Passes.html#loop-rotate-rotate-loops."""
--        ffi.lib.LLVMPY_AddLoopRotatePass(self)
--
--    def add_target_library_info(self, triple):
--        ffi.lib.LLVMPY_AddTargetLibraryInfoPass(self, _encode_string(triple))
--
--    def add_instruction_namer_pass(self):
--        """
--        See https://llvm.org/docs/Passes.html#instnamer-assign-names-to-anonymous-instructions.
--
--        LLVM 14: `llvm::createInstructionNamerPass`
--        """  # noqa E501
--        ffi.lib.LLVMPY_AddInstructionNamerPass(self)
--
--    # Non-standard LLVM passes
--
--    def add_refprune_pass(self, subpasses_flags=RefPruneSubpasses.ALL,
--                          subgraph_limit=1000):
--        """Add Numba specific Reference count pruning pass.
--
--        Parameters
--        ----------
--        subpasses_flags : RefPruneSubpasses
--            A bitmask to control the subpasses to be enabled.
--        subgraph_limit : int
--            Limit the fanout pruners to working on a subgraph no bigger than
--            this number of basic-blocks to avoid spending too much time in very
--            large graphs. Default is 1000. Subject to change in future
--            versions.
--        """
--        iflags = RefPruneSubpasses(subpasses_flags)
--        ffi.lib.LLVMPY_AddLegacyRefPrunePass(self, iflags, subgraph_limit)
--
--
--class ModulePassManager(PassManager):
--
--    def __init__(self, ptr=None):
--        if ptr is None:
--            ptr = ffi.lib.LLVMPY_CreatePassManager()
--        PassManager.__init__(self, ptr)
--
--    def run(self, module, remarks_file=None, remarks_format='yaml',
--            remarks_filter=''):
--        """
--        Run optimization passes on the given module.
--
--        Parameters
--        ----------
--        module : llvmlite.binding.ModuleRef
--            The module to be optimized inplace
--        remarks_file : str; optional
--            If not `None`, it is the file to store the optimization remarks.
--        remarks_format : str; optional
--            The format to write; YAML is default
--        remarks_filter : str; optional
--            The filter that should be applied to the remarks output.
--        """
--        if remarks_file is None:
--            return ffi.lib.LLVMPY_RunPassManager(self, module)
--        else:
--            r = ffi.lib.LLVMPY_RunPassManagerWithRemarks(
--                self, module, _encode_string(remarks_format),
--                _encode_string(remarks_filter),
--                _encode_string(remarks_file))
--            if r == -1:
--                raise IOError("Failed to initialize remarks file.")
--            return r > 0
--
--    def run_with_remarks(self, module, remarks_format='yaml',
--                         remarks_filter=''):
--        """
--        Run optimization passes on the given module and returns the result and
--        the remarks data.
--
--        Parameters
--        ----------
--        module : llvmlite.binding.ModuleRef
--            The module to be optimized
--        remarks_format : str
--            The remarks output; YAML is the default
--        remarks_filter : str; optional
--            The filter that should be applied to the remarks output.
--        """
--        remarkdesc, remarkfile = mkstemp()
--        try:
--            with os.fdopen(remarkdesc, 'r'):
--                pass
--            r = self.run(module, remarkfile, remarks_format, remarks_filter)
--            if r == -1:
--                raise IOError("Failed to initialize remarks file.")
--            with open(remarkfile) as f:
--                return bool(r), f.read()
--        finally:
--            os.unlink(remarkfile)
--
--
--class FunctionPassManager(PassManager):
--
--    def __init__(self, module):
--        ptr = ffi.lib.LLVMPY_CreateFunctionPassManager(module)
--        self._module = module
--        module._owned = True
--        PassManager.__init__(self, ptr)
--
--    def initialize(self):
--        """
--        Initialize the FunctionPassManager.  Returns True if it produced
--        any changes (?).
--        """
--        return ffi.lib.LLVMPY_InitializeFunctionPassManager(self)
--
--    def finalize(self):
--        """
--        Finalize the FunctionPassManager.  Returns True if it produced
--        any changes (?).
--        """
--        return ffi.lib.LLVMPY_FinalizeFunctionPassManager(self)
--
--    def run(self, function, remarks_file=None, remarks_format='yaml',
--            remarks_filter=''):
--        """
--        Run optimization passes on the given function.
--
--        Parameters
--        ----------
--        function : llvmlite.binding.FunctionRef
--            The function to be optimized inplace
--        remarks_file : str; optional
--            If not `None`, it is the file to store the optimization remarks.
--        remarks_format : str; optional
--            The format of the remarks file; the default is YAML
--        remarks_filter : str; optional
--            The filter that should be applied to the remarks output.
--        """
--        if remarks_file is None:
--            return ffi.lib.LLVMPY_RunFunctionPassManager(self, function)
--        else:
--            r = ffi.lib.LLVMPY_RunFunctionPassManagerWithRemarks(
--                self, function, _encode_string(remarks_format),
--                _encode_string(remarks_filter),
--                _encode_string(remarks_file))
--            if r == -1:
--                raise IOError("Failed to initialize remarks file.")
--            return bool(r)
--
--    def run_with_remarks(self, function, remarks_format='yaml',
--                         remarks_filter=''):
--        """
--        Run optimization passes on the given function and returns the result
--        and the remarks data.
--
--        Parameters
--        ----------
--        function : llvmlite.binding.FunctionRef
--            The function to be optimized inplace
--        remarks_format : str; optional
--            The format of the remarks file; the default is YAML
--        remarks_filter : str; optional
--            The filter that should be applied to the remarks output.
--        """
--        # LLVM is going to need to close this file and then reopen it, so we
--        # can't use an unlinked temporary file.
--        remarkdesc, remarkfile = mkstemp()
--        try:
--            # We get an open handle, but we need LLVM to write first, so close
--            # it.
--            with os.fdopen(remarkdesc, 'r'):
--                pass
--            r = self.run(function, remarkfile, remarks_format, remarks_filter)
--            if r == -1:
--                raise IOError("Failed to initialize remarks file.")
--            with open(remarkfile) as f:
--                return bool(r), f.read()
--        finally:
--            os.unlink(remarkfile)
--
--
--# ============================================================================
--# FFI
--
--ffi.lib.LLVMPY_CreatePassManager.restype = ffi.LLVMPassManagerRef
--
--ffi.lib.LLVMPY_CreateFunctionPassManager.argtypes = [ffi.LLVMModuleRef]
--ffi.lib.LLVMPY_CreateFunctionPassManager.restype = ffi.LLVMPassManagerRef
--
--ffi.lib.LLVMPY_DisposePassManager.argtypes = [ffi.LLVMPassManagerRef]
--
--ffi.lib.LLVMPY_RunPassManager.argtypes = [ffi.LLVMPassManagerRef,
--                                          ffi.LLVMModuleRef]
--ffi.lib.LLVMPY_RunPassManager.restype = c_bool
--
--ffi.lib.LLVMPY_RunPassManagerWithRemarks.argtypes = [ffi.LLVMPassManagerRef,
--                                                     ffi.LLVMModuleRef,
--                                                     c_char_p,
--                                                     c_char_p,
--                                                     c_char_p]
--ffi.lib.LLVMPY_RunPassManagerWithRemarks.restype = c_int
--
--ffi.lib.LLVMPY_InitializeFunctionPassManager.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_InitializeFunctionPassManager.restype = c_bool
--
--ffi.lib.LLVMPY_FinalizeFunctionPassManager.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_FinalizeFunctionPassManager.restype = c_bool
--
--ffi.lib.LLVMPY_RunFunctionPassManager.argtypes = [ffi.LLVMPassManagerRef,
--                                                  ffi.LLVMValueRef]
--ffi.lib.LLVMPY_RunFunctionPassManager.restype = c_bool
--
--ffi.lib.LLVMPY_RunFunctionPassManagerWithRemarks.argtypes = [
--    ffi.LLVMPassManagerRef, ffi.LLVMValueRef, c_char_p, c_char_p, c_char_p
--]
--ffi.lib.LLVMPY_RunFunctionPassManagerWithRemarks.restype = c_int
--
--ffi.lib.LLVMPY_AddAAEvalPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddBasicAAWrapperPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddConstantMergePass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddDeadArgEliminationPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddDependenceAnalysisPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddCallGraphDOTPrinterPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddCFGPrinterPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddDotDomPrinterPass.argtypes = [ffi.LLVMPassManagerRef, c_bool]
--ffi.lib.LLVMPY_AddDotPostDomPrinterPass.argtypes = [
--    ffi.LLVMPassManagerRef,
--    c_bool]
--ffi.lib.LLVMPY_AddGlobalsModRefAAPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddInstructionCountPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddIVUsersPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLazyValueInfoPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLintPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddModuleDebugInfoPrinterPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddRegionInfoPass.argtypes = [ffi.LLVMPassManagerRef]
--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_AddBreakCriticalEdgesPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddDeadStoreEliminationPass.argtypes = [
--    ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddReversePostOrderFunctionAttrsPass.argtypes = [
--    ffi.LLVMPassManagerRef]
--
--if llvm_version_major < 16:
--    ffi.lib.LLVMPY_AddAggressiveInstructionCombiningPass.argtypes = [
--        ffi.LLVMPassManagerRef]
--
--ffi.lib.LLVMPY_AddInternalizePass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLCSSAPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLoopDeletionPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLoopExtractorPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddSingleLoopExtractorPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLoopStrengthReducePass.argtypes = [ffi.LLVMPassManagerRef]
--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]
--ffi.lib.LLVMPY_AddLowerAtomicPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLowerInvokePass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLowerSwitchPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddMemCpyOptimizationPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddMergeFunctionsPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddMergeReturnsPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddPartialInliningPass.argtypes = [ffi.LLVMPassManagerRef]
--
--if llvm_version_major < 16:
--    ffi.lib.LLVMPY_AddPruneExceptionHandlingPass.argtypes = [
--        ffi.LLVMPassManagerRef
--    ]
--
--ffi.lib.LLVMPY_AddReassociatePass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddDemoteRegisterToMemoryPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddSinkPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddStripSymbolsPass.argtypes = [ffi.LLVMPassManagerRef, c_bool]
--ffi.lib.LLVMPY_AddStripDeadDebugInfoPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddStripDeadPrototypesPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddStripDebugDeclarePrototypesPass.argtypes = [
--    ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddStripNondebugSymbolsPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddTailCallEliminationPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddJumpThreadingPass.argtypes = [ffi.LLVMPassManagerRef, c_int]
--ffi.lib.LLVMPY_AddFunctionAttrsPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddFunctionInliningPass.argtypes = [
--    ffi.LLVMPassManagerRef, c_int]
--ffi.lib.LLVMPY_AddGlobalDCEPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddGlobalOptimizerPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddIPSCCPPass.argtypes = [ffi.LLVMPassManagerRef]
--
--ffi.lib.LLVMPY_AddDeadCodeEliminationPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddCFGSimplificationPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddGVNPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddInstructionCombiningPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddLICMPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddSCCPPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddSROAPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddTypeBasedAliasAnalysisPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddBasicAliasAnalysisPass.argtypes = [ffi.LLVMPassManagerRef]
--ffi.lib.LLVMPY_AddTargetLibraryInfoPass.argtypes = [ffi.LLVMPassManagerRef,
--                                                    c_char_p]
--ffi.lib.LLVMPY_AddInstructionNamerPass.argtypes = [ffi.LLVMPassManagerRef]
--
--ffi.lib.LLVMPY_AddLegacyRefPrunePass.argtypes = [ffi.LLVMPassManagerRef, c_int,
--                                                 c_size_t]
--
--ffi.lib.LLVMPY_DumpRefPruneStats.argtypes = [POINTER(_c_PruneStats), c_bool]
-diff --git a/llvmlite/binding/targets.py b/llvmlite/binding/targets.py
-index 353eb3b26..a16dd05c4 100644
---- a/llvmlite/binding/targets.py
-+++ b/llvmlite/binding/targets.py
-@@ -115,28 +115,17 @@ def get_host_cpu_name():
- llvm_version_major = llvm_version_info[0]
- 
- 
--if llvm_version_major >= 15:
--    _object_formats = {
--        0: "Unknown",
--        1: "COFF",
--        2: "DXContainer",
--        3: "ELF",
--        4: "GOFF",
--        5: "MachO",
--        6: "SPIRV",
--        7: "Wasm",
--        8: "XCOFF",
--    }
--else:
--    _object_formats = {
--        0: "Unknown",
--        1: "COFF",
--        2: "ELF",
--        3: "GOFF",
--        4: "MachO",
--        5: "Wasm",
--        6: "XCOFF",
--    }
-+_object_formats = {
-+    0: "Unknown",
-+    1: "COFF",
-+    2: "DXContainer",
-+    3: "ELF",
-+    4: "GOFF",
-+    5: "MachO",
-+    6: "SPIRV",
-+    7: "Wasm",
-+    8: "XCOFF",
-+}
- 
- 
- def get_object_format(triple=None):
-diff --git a/llvmlite/binding/transforms.py b/llvmlite/binding/transforms.py
-deleted file mode 100644
-index 82c5dc157..000000000
---- a/llvmlite/binding/transforms.py
-+++ /dev/null
-@@ -1,151 +0,0 @@
--from ctypes import c_uint, c_bool
--from llvmlite.binding import ffi
--from llvmlite.binding import passmanagers
--
--
--def create_pass_manager_builder():
--    return PassManagerBuilder()
--
--
--class PassManagerBuilder(ffi.ObjectRef):
--    __slots__ = ()
--
--    def __init__(self, ptr=None):
--        if ptr is None:
--            ptr = ffi.lib.LLVMPY_PassManagerBuilderCreate()
--        ffi.ObjectRef.__init__(self, ptr)
--
--    @property
--    def opt_level(self):
--        """
--        The general optimization level as an integer between 0 and 3.
--        """
--        return ffi.lib.LLVMPY_PassManagerBuilderGetOptLevel(self)
--
--    @opt_level.setter
--    def opt_level(self, level):
--        ffi.lib.LLVMPY_PassManagerBuilderSetOptLevel(self, level)
--
--    @property
--    def size_level(self):
--        """
--        Whether and how much to optimize for size.  An integer between 0 and 2.
--        """
--        return ffi.lib.LLVMPY_PassManagerBuilderGetSizeLevel(self)
--
--    @size_level.setter
--    def size_level(self, size):
--        ffi.lib.LLVMPY_PassManagerBuilderSetSizeLevel(self, size)
--
--    @property
--    def inlining_threshold(self):
--        """
--        The integer threshold for inlining a function into another.  The higher,
--        the more likely inlining a function is.  This attribute is write-only.
--        """
--        raise NotImplementedError("inlining_threshold is write-only")
--
--    @inlining_threshold.setter
--    def inlining_threshold(self, threshold):
--        ffi.lib.LLVMPY_PassManagerBuilderUseInlinerWithThreshold(
--            self, threshold)
--
--    @property
--    def disable_unroll_loops(self):
--        """
--        If true, disable loop unrolling.
--        """
--        return ffi.lib.LLVMPY_PassManagerBuilderGetDisableUnrollLoops(self)
--
--    @disable_unroll_loops.setter
--    def disable_unroll_loops(self, disable=True):
--        ffi.lib.LLVMPY_PassManagerBuilderSetDisableUnrollLoops(self, disable)
--
--    @property
--    def loop_vectorize(self):
--        """
--        If true, allow vectorizing loops.
--        """
--        return ffi.lib.LLVMPY_PassManagerBuilderGetLoopVectorize(self)
--
--    @loop_vectorize.setter
--    def loop_vectorize(self, enable=True):
--        return ffi.lib.LLVMPY_PassManagerBuilderSetLoopVectorize(self, enable)
--
--    @property
--    def slp_vectorize(self):
--        """
--        If true, enable the "SLP vectorizer", which uses a different algorithm
--        from the loop vectorizer.  Both may be enabled at the same time.
--        """
--        return ffi.lib.LLVMPY_PassManagerBuilderGetSLPVectorize(self)
--
--    @slp_vectorize.setter
--    def slp_vectorize(self, enable=True):
--        return ffi.lib.LLVMPY_PassManagerBuilderSetSLPVectorize(self, enable)
--
--    def _populate_module_pm(self, pm):
--        ffi.lib.LLVMPY_PassManagerBuilderPopulateModulePassManager(self, pm)
--
--    def _populate_function_pm(self, pm):
--        ffi.lib.LLVMPY_PassManagerBuilderPopulateFunctionPassManager(self, pm)
--
--    def populate(self, pm):
--        if isinstance(pm, passmanagers.ModulePassManager):
--            self._populate_module_pm(pm)
--        elif isinstance(pm, passmanagers.FunctionPassManager):
--            self._populate_function_pm(pm)
--        else:
--            raise TypeError(pm)
--
--    def _dispose(self):
--        self._capi.LLVMPY_PassManagerBuilderDispose(self)
--
--
--# ============================================================================
--# FFI
--
--ffi.lib.LLVMPY_PassManagerBuilderCreate.restype = ffi.LLVMPassManagerBuilderRef
--
--ffi.lib.LLVMPY_PassManagerBuilderDispose.argtypes = [
--    ffi.LLVMPassManagerBuilderRef,
--]
--
--ffi.lib.LLVMPY_PassManagerBuilderPopulateModulePassManager.argtypes = [
--    ffi.LLVMPassManagerBuilderRef,
--    ffi.LLVMPassManagerRef,
--]
--
--ffi.lib.LLVMPY_PassManagerBuilderPopulateFunctionPassManager.argtypes = [
--    ffi.LLVMPassManagerBuilderRef,
--    ffi.LLVMPassManagerRef,
--]
--
--# Unsigned int PassManagerBuilder properties
--
--for _func in (ffi.lib.LLVMPY_PassManagerBuilderSetOptLevel,
--              ffi.lib.LLVMPY_PassManagerBuilderSetSizeLevel,
--              ffi.lib.LLVMPY_PassManagerBuilderUseInlinerWithThreshold,
--              ):
--    _func.argtypes = [ffi.LLVMPassManagerBuilderRef, c_uint]
--
--for _func in (ffi.lib.LLVMPY_PassManagerBuilderGetOptLevel,
--              ffi.lib.LLVMPY_PassManagerBuilderGetSizeLevel,
--              ):
--    _func.argtypes = [ffi.LLVMPassManagerBuilderRef]
--    _func.restype = c_uint
--
--# Boolean PassManagerBuilder properties
--
--for _func in (ffi.lib.LLVMPY_PassManagerBuilderSetDisableUnrollLoops,
--              ffi.lib.LLVMPY_PassManagerBuilderSetLoopVectorize,
--              ffi.lib.LLVMPY_PassManagerBuilderSetSLPVectorize,
--              ):
--    _func.argtypes = [ffi.LLVMPassManagerBuilderRef, c_bool]
--
--for _func in (ffi.lib.LLVMPY_PassManagerBuilderGetDisableUnrollLoops,
--              ffi.lib.LLVMPY_PassManagerBuilderGetLoopVectorize,
--              ffi.lib.LLVMPY_PassManagerBuilderGetSLPVectorize,
--              ):
--    _func.argtypes = [ffi.LLVMPassManagerBuilderRef]
--    _func.restype = c_bool
-diff --git a/llvmlite/binding/typeref.py b/llvmlite/binding/typeref.py
-index f34baff94..2394f6204 100644
---- a/llvmlite/binding/typeref.py
-+++ b/llvmlite/binding/typeref.py
-@@ -109,17 +109,6 @@ def elements(self):
-             raise ValueError("Type {} doesn't contain elements.".format(self))
-         return _TypeListIterator(ffi.lib.LLVMPY_ElementIter(self))
- 
--    # FIXME: Remove me once typed pointers support is removed.
--    @property
--    def element_type(self):
--        """
--        Returns the pointed-to type. When the type is not a pointer,
--        raises exception.
--        """
--        if not self.is_pointer:
--            raise ValueError("Type {} is not a pointer".format(self))
--        return TypeRef(ffi.lib.LLVMPY_GetElementType(self))
--
-     @property
-     def element_count(self):
-         """
-diff --git a/llvmlite/tests/refprune_proto.py b/llvmlite/tests/refprune_proto.py
-index 3edc58f4b..043a0b678 100644
---- a/llvmlite/tests/refprune_proto.py
-+++ b/llvmlite/tests/refprune_proto.py
-@@ -103,6 +103,7 @@ def case7():
- 
- def case8():
-     edges = {
-+        "entry:": ["A"],
-         "A": ["B", "C"],
-         "B": ["C"],
-         "C": [],
-diff --git a/llvmlite/tests/test_binding.py b/llvmlite/tests/test_binding.py
-index a5cf72c08..340e0077e 100644
---- a/llvmlite/tests/test_binding.py
-+++ b/llvmlite/tests/test_binding.py
-@@ -412,11 +412,11 @@ def no_de_locale():
-     'addi\tsp, sp, -16',
-     'sw\ta1, 8(sp)',
-     'sw\ta2, 12(sp)',
--    'fld\tft0, 8(sp)',
--    'fmv.w.x\tft1, a0',
--    'fcvt.d.s\tft1, ft1',
--    'fadd.d\tft0, ft1, ft0',
--    'fsd\tft0, 8(sp)',
-+    'fld\tfa5, 8(sp)',
-+    'fmv.w.x\tfa4, a0',
-+    'fcvt.d.s\tfa4, fa4',
-+    'fadd.d\tfa5, fa4, fa5',
-+    'fsd\tfa5, 8(sp)',
-     'lw\ta0, 8(sp)',
-     'lw\ta1, 12(sp)',
-     'addi\tsp, sp, 16',
-@@ -428,10 +428,10 @@ def no_de_locale():
-     'addi\tsp, sp, -16',
-     'sw\ta0, 8(sp)',
-     'sw\ta1, 12(sp)',
--    'fld\tft0, 8(sp)',
--    'fcvt.d.s\tft1, fa0',
--    'fadd.d\tft0, ft1, ft0',
--    'fsd\tft0, 8(sp)',
-+    'fld\tfa5, 8(sp)',
-+    'fcvt.d.s\tfa4, fa0',
-+    'fadd.d\tfa5, fa4, fa5',
-+    'fsd\tfa5, 8(sp)',
-     'lw\ta0, 8(sp)',
-     'lw\ta1, 12(sp)',
-     'addi\tsp, sp, 16',
-@@ -440,8 +440,8 @@ def no_de_locale():
- 
- 
- riscv_asm_ilp32d = [
--    'fcvt.d.s\tft0, fa0',
--    'fadd.d\tfa0, ft0, fa1',
-+    'fcvt.d.s\tfa5, fa0',
-+    'fadd.d\tfa0, fa5, fa1',
-     'ret'
- ]
- 
-@@ -651,7 +651,6 @@ def no_de_locale():
- class BaseTest(TestCase):
- 
-     def setUp(self):
--        llvm.initialize()
-         llvm.initialize_native_target()
-         llvm.initialize_native_asmprinter()
-         gc.collect()
-@@ -889,7 +888,6 @@ def test_initfini(self):
-         code = """if 1:
-             from llvmlite import binding as llvm
- 
--            llvm.initialize()
-             llvm.initialize_native_target()
-             llvm.initialize_native_asmprinter()
-             llvm.initialize_all_targets()
-@@ -911,7 +909,7 @@ def test_set_option(self):
-     def test_version(self):
-         major, minor, patch = llvm.llvm_version_info
-         # one of these can be valid
--        valid = (15, 16)
-+        valid = (17, 18, 19)
-         self.assertIn(major, valid)
-         self.assertIn(patch, range(8))
- 
-@@ -1733,7 +1731,7 @@ def test_instruction_operands(self):
- 
-     def test_function_attributes(self):
-         ver = llvm.llvm_version_info[0]
--        readonly_attrs = [b'memory(read)' if ver == 16 else b'readonly']
-+        readonly_attrs = [b'memory(read)' if ver > 15 else b'readonly']
-         mod = self.module(asm_attributes)
-         for func in mod.functions:
-             attrs = list(func.attributes)
-@@ -2227,11 +2225,6 @@ def test_get_struct_element_offset(self):
- 
- class TestTargetMachine(BaseTest):
- 
--    def test_add_analysis_passes(self):
--        tm = self.target_machine(jit=False)
--        pm = llvm.create_module_pass_manager()
--        tm.add_analysis_passes(pm)
--
-     def test_target_data_from_tm(self):
-         tm = self.target_machine(jit=False)
-         td = tm.target_data
-@@ -2242,370 +2235,6 @@ def test_target_data_from_tm(self):
-         self.assertEqual(td.get_abi_size(gv_i32.type), pointer_size)
- 
- 
--class TestPassManagerBuilder(BaseTest):
--
--    def pmb(self):
--        return llvm.PassManagerBuilder()
--
--    def test_old_api(self):
--        # Test the create_pass_manager_builder() factory function
--        pmb = llvm.create_pass_manager_builder()
--        pmb.inlining_threshold = 2
--        pmb.opt_level = 3
--
--    def test_close(self):
--        pmb = self.pmb()
--        pmb.close()
--        pmb.close()
--
--    def test_opt_level(self):
--        pmb = self.pmb()
--        self.assertIsInstance(pmb.opt_level, int)
--        for i in range(4):
--            pmb.opt_level = i
--            self.assertEqual(pmb.opt_level, i)
--
--    def test_size_level(self):
--        pmb = self.pmb()
--        self.assertIsInstance(pmb.size_level, int)
--        for i in range(4):
--            pmb.size_level = i
--            self.assertEqual(pmb.size_level, i)
--
--    def test_inlining_threshold(self):
--        pmb = self.pmb()
--        with self.assertRaises(NotImplementedError):
--            pmb.inlining_threshold
--        for i in (25, 80, 350):
--            pmb.inlining_threshold = i
--
--    def test_disable_unroll_loops(self):
--        pmb = self.pmb()
--        self.assertIsInstance(pmb.disable_unroll_loops, bool)
--        for b in (True, False):
--            pmb.disable_unroll_loops = b
--            self.assertEqual(pmb.disable_unroll_loops, b)
--
--    def test_loop_vectorize(self):
--        pmb = self.pmb()
--        self.assertIsInstance(pmb.loop_vectorize, bool)
--        for b in (True, False):
--            pmb.loop_vectorize = b
--            self.assertEqual(pmb.loop_vectorize, b)
--
--    def test_slp_vectorize(self):
--        pmb = self.pmb()
--        self.assertIsInstance(pmb.slp_vectorize, bool)
--        for b in (True, False):
--            pmb.slp_vectorize = b
--            self.assertEqual(pmb.slp_vectorize, b)
--
--    def test_populate_module_pass_manager(self):
--        pmb = self.pmb()
--        pm = llvm.create_module_pass_manager()
--        pmb.populate(pm)
--        pmb.close()
--        pm.close()
--
--    def test_populate_function_pass_manager(self):
--        mod = self.module()
--        pmb = self.pmb()
--        pm = llvm.create_function_pass_manager(mod)
--        pmb.populate(pm)
--        pmb.close()
--        pm.close()
--
--
--class PassManagerTestMixin(object):
--
--    def pmb(self):
--        pmb = llvm.create_pass_manager_builder()
--        pmb.opt_level = 2
--        pmb.inlining_threshold = 300
--        return pmb
--
--    def test_close(self):
--        pm = self.pm()
--        pm.close()
--        pm.close()
--
--
--class TestModulePassManager(BaseTest, PassManagerTestMixin):
--
--    def pm(self):
--        return llvm.create_module_pass_manager()
--
--    def test_run(self):
--        pm = self.pm()
--        self.pmb().populate(pm)
--        mod = self.module()
--        orig_asm = str(mod)
--        pm.run(mod)
--        opt_asm = str(mod)
--        # Quick check that optimizations were run, should get:
--        # define i32 @sum(i32 %.1, i32 %.2) local_unnamed_addr #0 {
--        # %.X = add i32 %.2, %.1
--        # ret i32 %.X
--        # }
--        # where X in %.X is 3 or 4
--        opt_asm_split = opt_asm.splitlines()
--        for idx, l in enumerate(opt_asm_split):
--            if l.strip().startswith('ret i32'):
--                toks = {'%.3', '%.4'}
--                for t in toks:
--                    if t in l:
--                        break
--                else:
--                    raise RuntimeError("expected tokens not found")
--                othertoken = (toks ^ {t}).pop()
--
--                self.assertIn("%.3", orig_asm)
--                self.assertNotIn(othertoken, opt_asm)
--                break
--        else:
--            raise RuntimeError("expected IR not found")
--
--    def test_run_with_remarks_successful_inline(self):
--        pm = self.pm()
--        pm.add_function_inlining_pass(70)
--        self.pmb().populate(pm)
--        mod = self.module(asm_inlineasm2)
--        (status, remarks) = pm.run_with_remarks(mod)
--        self.assertTrue(status)
--        # Inlining has happened?  The remark will tell us.
--        self.assertIn("Passed", remarks)
--        self.assertIn("inlineme", remarks)
--
--    def test_run_with_remarks_failed_inline(self):
--        pm = self.pm()
--        pm.add_function_inlining_pass(0)
--        self.pmb().populate(pm)
--        mod = self.module(asm_inlineasm3)
--        (status, remarks) = pm.run_with_remarks(mod)
--        self.assertTrue(status)
--
--        # Inlining has not happened?  The remark will tell us.
--        self.assertIn("Missed", remarks)
--        self.assertIn("inlineme", remarks)
--        self.assertIn("noinline function attribute", remarks)
--
--    def test_run_with_remarks_inline_filter_out(self):
--        pm = self.pm()
--        pm.add_function_inlining_pass(70)
--        self.pmb().populate(pm)
--        mod = self.module(asm_inlineasm2)
--        (status, remarks) = pm.run_with_remarks(mod, remarks_filter="nothing")
--        self.assertTrue(status)
--        self.assertEqual("", remarks)
--
--    def test_run_with_remarks_inline_filter_in(self):
--        pm = self.pm()
--        pm.add_function_inlining_pass(70)
--        self.pmb().populate(pm)
--        mod = self.module(asm_inlineasm2)
--        (status, remarks) = pm.run_with_remarks(mod, remarks_filter="inlin.*")
--        self.assertTrue(status)
--        self.assertIn("Passed", remarks)
--        self.assertIn("inlineme", remarks)
--
--
--class TestFunctionPassManager(BaseTest, PassManagerTestMixin):
--
--    def pm(self, mod=None):
--        mod = mod or self.module()
--        return llvm.create_function_pass_manager(mod)
--
--    def test_initfini(self):
--        pm = self.pm()
--        pm.initialize()
--        pm.finalize()
--
--    def test_run(self):
--        mod = self.module()
--        fn = mod.get_function("sum")
--        pm = self.pm(mod)
--        self.pmb().populate(pm)
--        mod.close()
--        orig_asm = str(fn)
--        pm.initialize()
--        pm.run(fn)
--        pm.finalize()
--        opt_asm = str(fn)
--        # Quick check that optimizations were run
--        self.assertIn("%.4", orig_asm)
--        self.assertNotIn("%.4", opt_asm)
--
--    def test_run_with_remarks(self):
--        mod = self.module(licm_asm)
--        fn = mod.get_function("licm")
--        pm = self.pm(mod)
--        pm.add_licm_pass()
--        self.pmb().populate(pm)
--        mod.close()
--
--        pm.initialize()
--        (ok, remarks) = pm.run_with_remarks(fn)
--        pm.finalize()
--        self.assertTrue(ok)
--        self.assertIn("Passed", remarks)
--        self.assertIn("licm", remarks)
--
--    def test_run_with_remarks_filter_out(self):
--        mod = self.module(licm_asm)
--        fn = mod.get_function("licm")
--        pm = self.pm(mod)
--        pm.add_licm_pass()
--        self.pmb().populate(pm)
--        mod.close()
--
--        pm.initialize()
--        (ok, remarks) = pm.run_with_remarks(fn, remarks_filter="nothing")
--        pm.finalize()
--        self.assertTrue(ok)
--        self.assertEqual("", remarks)
--
--    def test_run_with_remarks_filter_in(self):
--        mod = self.module(licm_asm)
--        fn = mod.get_function("licm")
--        pm = self.pm(mod)
--        pm.add_licm_pass()
--        self.pmb().populate(pm)
--        mod.close()
--
--        pm.initialize()
--        (ok, remarks) = pm.run_with_remarks(fn, remarks_filter="licm")
--        pm.finalize()
--        self.assertTrue(ok)
--        self.assertIn("Passed", remarks)
--        self.assertIn("licm", remarks)
--
--
--class TestPasses(BaseTest, PassManagerTestMixin):
--
--    def pm(self):
--        return llvm.create_module_pass_manager()
--
--    def test_populate(self):
--        llvm_ver = llvm.llvm_version_info[0]
--
--        pm = self.pm()
--        pm.add_target_library_info("") # unspecified target triple
--        pm.add_constant_merge_pass()
--        pm.add_dead_arg_elimination_pass()
--        pm.add_function_attrs_pass()
--        pm.add_function_inlining_pass(225)
--        pm.add_global_dce_pass()
--        pm.add_global_optimizer_pass()
--        pm.add_ipsccp_pass()
--        pm.add_dead_code_elimination_pass()
--        pm.add_cfg_simplification_pass()
--        pm.add_gvn_pass()
--        pm.add_instruction_combining_pass()
--        pm.add_licm_pass()
--        pm.add_sccp_pass()
--        pm.add_sroa_pass()
--        pm.add_type_based_alias_analysis_pass()
--        pm.add_basic_alias_analysis_pass()
--        pm.add_loop_rotate_pass()
--        pm.add_region_info_pass()
--        pm.add_scalar_evolution_aa_pass()
--        pm.add_aggressive_dead_code_elimination_pass()
--        pm.add_aa_eval_pass()
--        pm.add_always_inliner_pass()
--        pm.add_break_critical_edges_pass()
--        pm.add_dead_store_elimination_pass()
--        pm.add_reverse_post_order_function_attrs_pass()
--
--        if llvm_ver < 16:
--            pm.add_aggressive_instruction_combining_pass()
--
--        pm.add_internalize_pass()
--        pm.add_jump_threading_pass(7)
--        pm.add_lcssa_pass()
--        pm.add_loop_deletion_pass()
--        pm.add_loop_extractor_pass()
--        pm.add_single_loop_extractor_pass()
--        pm.add_loop_strength_reduce_pass()
--        pm.add_loop_simplification_pass()
--        pm.add_loop_unroll_pass()
--        pm.add_loop_unroll_and_jam_pass()
--        pm.add_lower_atomic_pass()
--        pm.add_lower_invoke_pass()
--        pm.add_lower_switch_pass()
--        pm.add_memcpy_optimization_pass()
--        pm.add_merge_functions_pass()
--        pm.add_merge_returns_pass()
--        pm.add_partial_inlining_pass()
--
--        if llvm_ver < 16:
--            pm.add_prune_exception_handling_pass()
--
--        pm.add_reassociate_expressions_pass()
--        pm.add_demote_register_to_memory_pass()
--        pm.add_sink_pass()
--        pm.add_strip_symbols_pass()
--        pm.add_strip_dead_debug_info_pass()
--        pm.add_strip_dead_prototypes_pass()
--        pm.add_strip_debug_declare_pass()
--        pm.add_strip_nondebug_symbols_pass()
--        pm.add_tail_call_elimination_pass()
--        pm.add_basic_aa_pass()
--        pm.add_dependence_analysis_pass()
--        pm.add_dot_call_graph_pass()
--        pm.add_dot_cfg_printer_pass()
--        pm.add_dot_dom_printer_pass()
--        pm.add_dot_postdom_printer_pass()
--        pm.add_globals_mod_ref_aa_pass()
--        pm.add_iv_users_pass()
--        pm.add_lazy_value_info_pass()
--        pm.add_lint_pass()
--        pm.add_module_debug_info_pass()
--        pm.add_refprune_pass()
--        pm.add_instruction_namer_pass()
--
--    @unittest.skipUnless(platform.machine().startswith("x86"), "x86 only")
--    def test_target_library_info_behavior(self):
--        """Test a specific situation that demonstrate TLI is affecting
--        optimization. See https://github.com/numba/numba/issues/8898.
--        """
--        def run(use_tli):
--            mod = llvm.parse_assembly(asm_tli_exp2)
--            target = llvm.Target.from_triple(mod.triple)
--            tm = target.create_target_machine()
--            pm = llvm.ModulePassManager()
--            tm.add_analysis_passes(pm)
--            if use_tli:
--                pm.add_target_library_info(mod.triple)
--            pm.add_instruction_combining_pass()
--            pm.run(mod)
--            return mod
--
--        # Run with TLI should suppress transformation of exp2 -> ldexpf
--        mod = run(use_tli=True)
--        self.assertIn("call float @llvm.exp2.f32", str(mod))
--
--        # Run without TLI will enable the transformation
--        mod = run(use_tli=False)
--        self.assertNotIn("call float @llvm.exp2.f32", str(mod))
--        self.assertIn("call float @ldexpf", str(mod))
--
--    def test_instruction_namer_pass(self):
--        asm = asm_inlineasm3.format(triple=llvm.get_default_triple())
--        mod = llvm.parse_assembly(asm)
--
--        # Run instnamer pass
--        pm = llvm.ModulePassManager()
--        pm.add_instruction_namer_pass()
--        pm.run(mod)
--
--        # Test that unnamed instructions are now named
--        func = mod.get_function('foo')
--        first_block = next(func.blocks)
--        instructions = list(first_block.instructions)
--        self.assertEqual(instructions[0].name, 'i')
--        self.assertEqual(instructions[1].name, 'i2')
--
--
- class TestDylib(BaseTest):
- 
-     def test_bad_library(self):
-@@ -2872,29 +2501,30 @@ def test_get_section_content(self):
-                 self.assertEqual(s.data().hex(), issue_632_text)
- 
- 
--class TestTimePasses(BaseTest):
--    def test_reporting(self):
--        mp = llvm.create_module_pass_manager()
-+# FIXME: Implement settimepasses for NPM and port the test
-+# class TestTimePasses(BaseTest):
-+#     def test_reporting(self):
-+#         mp = llvm.create_module_pass_manager()
- 
--        pmb = llvm.create_pass_manager_builder()
--        pmb.opt_level = 3
--        pmb.populate(mp)
-+#         pmb = llvm.create_pass_manager_builder()
-+#         pmb.opt_level = 3
-+#         pmb.populate(mp)
- 
--        try:
--            llvm.set_time_passes(True)
--            mp.run(self.module())
--            mp.run(self.module())
--            mp.run(self.module())
--        finally:
--            report = llvm.report_and_reset_timings()
--            llvm.set_time_passes(False)
-+#         try:
-+#             llvm.set_time_passes(True)
-+#             mp.run(self.module())
-+#             mp.run(self.module())
-+#             mp.run(self.module())
-+#         finally:
-+#             report = llvm.report_and_reset_timings()
-+#             llvm.set_time_passes(False)
- 
--        self.assertIsInstance(report, str)
--        self.assertEqual(report.count("Pass execution timing report"), 1)
-+#         self.assertIsInstance(report, str)
-+#         self.assertEqual(report.count("Pass execution timing report"), 1)
- 
--    def test_empty_report(self):
--        # Returns empty str if no data is collected
--        self.assertFalse(llvm.report_and_reset_timings())
-+#     def test_empty_report(self):
-+#         # Returns empty str if no data is collected
-+#         self.assertFalse(llvm.report_and_reset_timings())
- 
- 
- class TestLLVMLockCallbacks(BaseTest):
-@@ -2913,7 +2543,7 @@ def rel():
-         # Check: events are initially empty
-         self.assertFalse(events)
-         # Call LLVM functions
--        llvm.create_module_pass_manager()
-+        llvm.create_new_module_pass_manager()
-         # Check: there must be at least one acq and one rel
-         self.assertIn("acq", events)
-         self.assertIn("rel", events)
-@@ -3151,13 +2781,64 @@ def test_optnone(self):
- 
-     def test_add_passes(self):
-         mpm = self.pm()
-+        mpm.add_argument_promotion_pass()
-+        mpm.add_post_order_function_attributes_pass()
-         mpm.add_verifier()
-+        mpm.add_constant_merge_pass()
-+        mpm.add_dead_arg_elimination_pass()
-+        mpm.add_dot_call_graph_printer_pass()
-+        mpm.add_always_inliner_pass()
-+        mpm.add_rpo_function_attrs_pass()
-+        mpm.add_global_dead_code_eliminate_pass()
-+        mpm.add_global_opt_pass()
-+        mpm.add_ipsccp_pass()
-+        mpm.add_internalize_pass()
-+        mpm.add_merge_functions_pass()
-+        mpm.add_partial_inliner_pass()
-+        mpm.add_strip_symbols_pass()
-+        mpm.add_strip_dead_debug_info_pass()
-+        mpm.add_strip_dead_prototype_pass()
-+        mpm.add_strip_debug_declare_pass()
-+        mpm.add_strip_non_debug_symbols_pass()
-         mpm.add_aa_eval_pass()
-         mpm.add_simplify_cfg_pass()
-         mpm.add_loop_unroll_pass()
--        mpm.add_loop_rotate_pass()
-         mpm.add_instruction_combine_pass()
-         mpm.add_jump_threading_pass()
-+        mpm.add_cfg_printer_pass()
-+        mpm.add_cfg_only_printer_pass()
-+        mpm.add_dom_printer_pass()
-+        mpm.add_dom_only_printer_pass()
-+        mpm.add_post_dom_printer_pass()
-+        mpm.add_post_dom_only_printer_pass()
-+        mpm.add_dom_viewer_pass()
-+        mpm.add_dom_only_printer_pass()
-+        mpm.add_post_dom_viewer_pass()
-+        mpm.add_post_dom_only_viewer_pass()
-+        mpm.add_lint_pass()
-+        mpm.add_aggressive_dce_pass()
-+        mpm.add_break_critical_edges_pass()
-+        mpm.add_dead_store_elimination_pass()
-+        mpm.add_dead_code_elimination_pass()
-+        mpm.add_aggressive_instcombine_pass()
-+        mpm.add_lcssa_pass()
-+        mpm.add_new_gvn_pass()
-+        mpm.add_loop_simplify_pass()
-+        mpm.add_sccp_pass()
-+        mpm.add_lower_atomic_pass()
-+        mpm.add_lower_invoke_pass()
-+        mpm.add_lower_switch_pass()
-+        mpm.add_mem_copy_opt_pass()
-+        mpm.add_unify_function_exit_nodes_pass()
-+        mpm.add_reassociate_pass()
-+        mpm.add_register_to_memory_pass()
-+        # mpm.add_sroa_pass()
-+        mpm.add_sinking_pass()
-+        mpm.add_tail_call_elimination_pass()
-+        mpm.add_instruction_namer_pass()
-+        mpm.add_loop_deletion_pass()
-+        mpm.add_loop_strength_reduce_pass()
-+        mpm.add_loop_rotate_pass()
-         mpm.add_refprune_pass()
- 
- 
-@@ -3231,9 +2912,42 @@ def test_add_passes(self):
-         fpm.add_aa_eval_pass()
-         fpm.add_simplify_cfg_pass()
-         fpm.add_loop_unroll_pass()
--        fpm.add_loop_rotate_pass()
-         fpm.add_instruction_combine_pass()
-         fpm.add_jump_threading_pass()
-+        fpm.add_cfg_printer_pass()
-+        fpm.add_cfg_only_printer_pass()
-+        fpm.add_dom_printer_pass()
-+        fpm.add_dom_only_printer_pass()
-+        fpm.add_post_dom_printer_pass()
-+        fpm.add_post_dom_only_printer_pass()
-+        fpm.add_dom_viewer_pass()
-+        fpm.add_dom_only_printer_pass()
-+        fpm.add_post_dom_viewer_pass()
-+        fpm.add_post_dom_only_viewer_pass()
-+        fpm.add_lint_pass()
-+        fpm.add_aggressive_dce_pass()
-+        fpm.add_break_critical_edges_pass()
-+        fpm.add_dead_store_elimination_pass()
-+        fpm.add_dead_code_elimination_pass()
-+        fpm.add_aggressive_instcombine_pass()
-+        fpm.add_lcssa_pass()
-+        fpm.add_new_gvn_pass()
-+        fpm.add_loop_simplify_pass()
-+        fpm.add_sccp_pass()
-+        fpm.add_lower_atomic_pass()
-+        fpm.add_lower_invoke_pass()
-+        fpm.add_lower_switch_pass()
-+        fpm.add_mem_copy_opt_pass()
-+        fpm.add_unify_function_exit_nodes_pass()
-+        fpm.add_reassociate_pass()
-+        fpm.add_register_to_memory_pass()
-+        # fpm.add_sroa_pass()
-+        fpm.add_sinking_pass()
-+        fpm.add_tail_call_elimination_pass()
-+        fpm.add_instruction_namer_pass()
-+        fpm.add_loop_deletion_pass()
-+        fpm.add_loop_strength_reduce_pass()
-+        fpm.add_loop_rotate_pass()
-         fpm.add_refprune_pass()
- 
- 
-diff --git a/llvmlite/tests/test_refprune.py b/llvmlite/tests/test_refprune.py
-index ab82c74cd..69d896dca 100644
---- a/llvmlite/tests/test_refprune.py
-+++ b/llvmlite/tests/test_refprune.py
-@@ -1,4 +1,5 @@
- import unittest
-+from collections import defaultdict
- from llvmlite import ir
- from llvmlite import binding as llvm
- from llvmlite.tests import TestCase
-@@ -133,16 +134,13 @@ def apply_refprune(self, irmod):
-         pm.run(mod, pb)
-         return mod
- 
--    def apply_refprune_legacy(self, irmod):
--        mod = llvm.parse_assembly(str(irmod))
--        pm = llvm.ModulePassManager()
--        pm.add_refprune_pass()
--        pm.run(mod)
--        return mod
--
-     def check(self, mod, expected, nodes):
-         # preprocess incref/decref locations
--        d = {}
-+
-+        # LLVM >= 18 have been adds an extra empty block "LoopExit" which causes
-+        # regular dict to throw KeyError
-+        d = defaultdict(lambda: defaultdict(int))
-+
-         for k, vs in nodes.items():
-             n_incref = vs.count('incref')
-             n_decref = vs.count('decref')
-@@ -157,6 +155,7 @@ def check(self, mod, expected, nodes):
-         for f in mod.functions:
-             if f.name == 'main':
-                 break
-+
-         # check each BB
-         for bb in f.blocks:
-             stats = d[bb.name]
-@@ -172,19 +171,11 @@ def generate_test(self, case_gen):
-         outmod = self.apply_refprune(irmod)
-         self.check(outmod, expected, nodes)
- 
--    def generate_test_legacy(self, case_gen):
--        nodes, edges, expected = case_gen()
--        irmod = self.generate_ir(nodes, edges)
--        outmod = self.apply_refprune_legacy(irmod)
--        self.check(outmod, expected, nodes)
--
-+    # FIXME: Tests/Refprune pass needs fixing for llvm18
-     # Generate tests
-     for name, case in _iterate_cases(generate_test):
-         locals()[name] = case
- 
--    for name, case in _iterate_cases(generate_test_legacy):
--        locals()[name + "_legacy"] = case
--
- 
- class BaseTestByIR(TestCase, PassManagerMixin):
-     refprune_bitmask = 0
-@@ -208,19 +199,6 @@ def check(self, irmod, subgraph_limit=None):
-         after = llvm.dump_refprune_stats()
-         return mod, after - before
- 
--    def check_legacy(self, irmod, subgraph_limit=None):
--        mod = llvm.parse_assembly(f"{self.prologue}\n{irmod}")
--        pm = llvm.ModulePassManager()
--        if subgraph_limit is None:
--            pm.add_refprune_pass(self.refprune_bitmask)
--        else:
--            pm.add_refprune_pass(self.refprune_bitmask,
--                                 subgraph_limit=subgraph_limit)
--        before = llvm.dump_refprune_stats()
--        pm.run(mod)
--        after = llvm.dump_refprune_stats()
--        return mod, after - before
--
- 
- class TestPerBB(BaseTestByIR):
-     refprune_bitmask = llvm.RefPruneSubpasses.PER_BB
-@@ -237,10 +215,6 @@ def test_per_bb_1(self):
-         mod, stats = self.check(self.per_bb_ir_1)
-         self.assertEqual(stats.basicblock, 2)
- 
--    def test_per_bb_1_legacy(self):
--        mod, stats = self.check_legacy(self.per_bb_ir_1)
--        self.assertEqual(stats.basicblock, 2)
--
-     per_bb_ir_2 = r"""
- define void @main(i8* %ptr) {
-     call void @NRT_incref(i8* %ptr)
-@@ -258,12 +232,6 @@ def test_per_bb_2(self):
-         # not pruned
-         self.assertIn("call void @NRT_incref(ptr %ptr)", str(mod))
- 
--    def test_per_bb_2_legacy(self):
--        mod, stats = self.check_legacy(self.per_bb_ir_2)
--        self.assertEqual(stats.basicblock, 4)
--        # not pruned
--        self.assertIn("call void @NRT_incref(ptr %ptr)", str(mod))
--
-     per_bb_ir_3 = r"""
- define void @main(ptr %ptr, ptr %other) {
-     call void @NRT_incref(ptr %ptr)
-@@ -280,12 +248,6 @@ def test_per_bb_3(self):
-         # not pruned
-         self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
- 
--    def test_per_bb_3_legacy(self):
--        mod, stats = self.check_legacy(self.per_bb_ir_3)
--        self.assertEqual(stats.basicblock, 2)
--        # not pruned
--        self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
--
-     per_bb_ir_4 = r"""
- ; reordered
- define void @main(ptr %ptr, ptr %other) {
-@@ -304,12 +266,6 @@ def test_per_bb_4(self):
-         # not pruned
-         self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
- 
--    def test_per_bb_4_legacy(self):
--        mod, stats = self.check_legacy(self.per_bb_ir_4)
--        self.assertEqual(stats.basicblock, 4)
--        # not pruned
--        self.assertIn("call void @NRT_decref(ptr %other)", str(mod))
--
- 
- class TestDiamond(BaseTestByIR):
-     refprune_bitmask = llvm.RefPruneSubpasses.DIAMOND
-@@ -329,10 +285,6 @@ def test_per_diamond_1(self):
-         mod, stats = self.check(self.per_diamond_1)
-         self.assertEqual(stats.diamond, 2)
- 
--    def test_per_diamond_1_legacy(self):
--        mod, stats = self.check_legacy(self.per_diamond_1)
--        self.assertEqual(stats.diamond, 2)
--
-     per_diamond_2 = r"""
- define void @main(i8* %ptr, i1 %cond) {
- bb_A:
-@@ -352,10 +304,6 @@ def test_per_diamond_2(self):
-         mod, stats = self.check(self.per_diamond_2)
-         self.assertEqual(stats.diamond, 2)
- 
--    def test_per_diamond_2_legacy(self):
--        mod, stats = self.check_legacy(self.per_diamond_2)
--        self.assertEqual(stats.diamond, 2)
--
-     per_diamond_3 = r"""
- define void @main(i8* %ptr, i1 %cond) {
- bb_A:
-@@ -376,10 +324,6 @@ def test_per_diamond_3(self):
-         mod, stats = self.check(self.per_diamond_3)
-         self.assertEqual(stats.diamond, 0)
- 
--    def test_per_diamond_3_legacy(self):
--        mod, stats = self.check_legacy(self.per_diamond_3)
--        self.assertEqual(stats.diamond, 0)
--
-     per_diamond_4 = r"""
- define void @main(i8* %ptr, i1 %cond) {
- bb_A:
-@@ -400,10 +344,6 @@ def test_per_diamond_4(self):
-         mod, stats = self.check(self.per_diamond_4)
-         self.assertEqual(stats.diamond, 2)
- 
--    def test_per_diamond_4_legacy(self):
--        mod, stats = self.check_legacy(self.per_diamond_4)
--        self.assertEqual(stats.diamond, 2)
--
-     per_diamond_5 = r"""
- define void @main(i8* %ptr, i1 %cond) {
- bb_A:
-@@ -425,10 +365,6 @@ def test_per_diamond_5(self):
-         mod, stats = self.check(self.per_diamond_5)
-         self.assertEqual(stats.diamond, 4)
- 
--    def test_per_diamond_5_legacy(self):
--        mod, stats = self.check_legacy(self.per_diamond_5)
--        self.assertEqual(stats.diamond, 4)
--
- 
- class TestFanout(BaseTestByIR):
-     """More complex cases are tested in TestRefPrunePass
-@@ -454,10 +390,6 @@ def test_fanout_1(self):
-         mod, stats = self.check(self.fanout_1)
-         self.assertEqual(stats.fanout, 3)
- 
--    def test_fanout_1_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_1)
--        self.assertEqual(stats.fanout, 3)
--
-     fanout_2 = r"""
- define void @main(i8* %ptr, i1 %cond, i8** %excinfo) {
- bb_A:
-@@ -476,10 +408,6 @@ def test_fanout_2(self):
-         mod, stats = self.check(self.fanout_2)
-         self.assertEqual(stats.fanout, 0)
- 
--    def test_fanout_2_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_2)
--        self.assertEqual(stats.fanout, 0)
--
-     fanout_3 = r"""
- define void @main(i8* %ptr, i1 %cond) {
- bb_A:
-@@ -508,16 +436,6 @@ def test_fanout_3_limited(self):
-         mod, stats = self.check(self.fanout_3, subgraph_limit=1)
-         self.assertEqual(stats.fanout, 0)
- 
--    def test_fanout_3_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_3)
--        self.assertEqual(stats.fanout, 6)
--
--    def test_fanout_3_limited_legacy(self):
--        # With subgraph limit at 1, it is essentially turning off the fanout
--        # pruner.
--        mod, stats = self.check_legacy(self.fanout_3, subgraph_limit=1)
--        self.assertEqual(stats.fanout, 0)
--
- 
- class TestFanoutRaise(BaseTestByIR):
-     refprune_bitmask = llvm.RefPruneSubpasses.FANOUT_RAISE
-@@ -541,10 +459,6 @@ def test_fanout_raise_1(self):
-         mod, stats = self.check(self.fanout_raise_1)
-         self.assertEqual(stats.fanout_raise, 2)
- 
--    def test_fanout_raise_1_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_raise_1)
--        self.assertEqual(stats.fanout_raise, 2)
--
-     fanout_raise_2 = r"""
- define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
- bb_A:
-@@ -567,12 +481,6 @@ def test_fanout_raise_2(self):
-         mod, stats = self.check(self.fanout_raise_2)
-         self.assertEqual(stats.fanout_raise, 0)
- 
--    def test_fanout_raise_2_legacy(self):
--        # This is ensuring that fanout_raise is not pruning when the metadata
--        # is incorrectly named.
--        mod, stats = self.check_legacy(self.fanout_raise_2)
--        self.assertEqual(stats.fanout_raise, 0)
--
-     fanout_raise_3 = r"""
- define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
- bb_A:
-@@ -593,10 +501,6 @@ def test_fanout_raise_3(self):
-         mod, stats = self.check(self.fanout_raise_3)
-         self.assertEqual(stats.fanout_raise, 2)
- 
--    def test_fanout_raise_3_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_raise_3)
--        self.assertEqual(stats.fanout_raise, 2)
--
-     fanout_raise_4 = r"""
- define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
- bb_A:
-@@ -615,10 +519,6 @@ def test_fanout_raise_4(self):
-         mod, stats = self.check(self.fanout_raise_4)
-         self.assertEqual(stats.fanout_raise, 0)
- 
--    def test_fanout_raise_4_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_raise_4)
--        self.assertEqual(stats.fanout_raise, 0)
--
-     fanout_raise_5 = r"""
- define i32 @main(i8* %ptr, i1 %cond, i8** %excinfo) {
- bb_A:
-@@ -641,10 +541,6 @@ def test_fanout_raise_5(self):
-         mod, stats = self.check(self.fanout_raise_5)
-         self.assertEqual(stats.fanout_raise, 2)
- 
--    def test_fanout_raise_5_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_raise_5)
--        self.assertEqual(stats.fanout_raise, 2)
--
-     # test case 6 is from https://github.com/numba/llvmlite/issues/1023
-     fanout_raise_6 = r"""
- define i32 @main(i8* %ptr, i1 %cond1, i1 %cond2, i1 %cond3, i8** %excinfo) {
-@@ -676,10 +572,6 @@ def test_fanout_raise_6(self):
-         mod, stats = self.check(self.fanout_raise_6)
-         self.assertEqual(stats.fanout_raise, 7)
- 
--    def test_fanout_raise_6_legacy(self):
--        mod, stats = self.check_legacy(self.fanout_raise_6)
--        self.assertEqual(stats.fanout_raise, 7)
--
- 
- if __name__ == '__main__':
-     unittest.main()
diff --git a/debian/patches/recognize-default-buildflags.patch b/debian/patches/recognize-default-buildflags.patch
deleted file mode 100644
index 663afb9..0000000
--- a/debian/patches/recognize-default-buildflags.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-Description: recognize build flags from environment
- Quick fix to solve https://github.com/numba/llvmlite/issues/443.
-Author: Daniel Stender <stender at debian.org>
-Forwarded: not-needed
-Last-Update: 2019-01-04
-
---- a/ffi/build.py
-+++ b/ffi/build.py
-@@ -220,10 +220,10 @@
-     else:
-         print('SVML not detected')
- 
--    os.environ['LLVM_CXXFLAGS'] = ' '.join(cxxflags)
-+    os.environ['LLVM_CXXFLAGS'] = os.environ['CXXFLAGS'] + ' ' + ' '.join(cxxflags)
- 
-     ldflags = run_llvm_config(llvm_config, ["--ldflags"])
--    os.environ['LLVM_LDFLAGS'] = ldflags.strip()
-+    os.environ['LLVM_LDFLAGS'] = os.environ['LDFLAGS'] + ' ' + ldflags.strip()
-     # static link libstdc++ for portability
-     if int(os.environ.get('LLVMLITE_CXX_STATIC_LINK', 0)):
-         os.environ['CXX_STATIC_LINK'] = "-static-libstdc++"
diff --git a/debian/patches/series b/debian/patches/series
index db19649..bb52353 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,4 @@
-recognize-default-buildflags.patch
 use-local-objectsinv.patch
-llvm-19-support-pr1182.patch
-skip-llvm-19-broken-tests.patch
+0002-Support-llvm-21.patch
+0003-Skip-llvm-version-test.patch
+0004-Skip-failing-tests-with-llvm-21.patch
diff --git a/debian/patches/skip-llvm-19-broken-tests.patch b/debian/patches/skip-llvm-19-broken-tests.patch
deleted file mode 100644
index 321d3b4..0000000
--- a/debian/patches/skip-llvm-19-broken-tests.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/llvmlite/tests/test_binding.py
-+++ b/llvmlite/tests/test_binding.py
-@@ -1485,6 +1485,7 @@
-         del rt
-         self.assertNotEqual(shared_value.value, 20)
- 
-+    @unittest.expectedFailure
-     def test_lookup_current_process_symbol_fails(self):
-         # An attempt to lookup a symbol in the current process (Py_GetVersion,
-         # in this case) should fail with an appropriate error if we have not
-@@ -2428,6 +2429,8 @@
-         }}
-     """
- 
-+    # something about the .text layout changed by llvm-19
-+    @unittest.skip
-     def test_object_file(self):
-         target_machine = self.target_machine(jit=False)
-         mod = self.module()
diff --git a/debian/patches/use-local-objectsinv.patch b/debian/patches/use-local-objectsinv.patch
index 61e8be0..9c7c642 100644
--- a/debian/patches/use-local-objectsinv.patch
+++ b/debian/patches/use-local-objectsinv.patch
@@ -1,17 +1,25 @@
-Author: Diane Trout <diane at ghic.org>
-Description: Point intersphinx to copies of the sphinx objects.inv
- files built by debian for the referenced projects
+From: Diane Trout <diane at ghic.org>
+Date: Mon, 15 Dec 2025 17:21:17 +1100
+Subject: Point intersphinx to copies of the sphinx objects.inv
 
+files built by debian for the referenced projects
+---
+ docs/source/conf.py | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/docs/source/conf.py b/docs/source/conf.py
+index 9f4bcd3..cd7652b 100644
 --- a/docs/source/conf.py
 +++ b/docs/source/conf.py
-@@ -300,8 +300,8 @@
+@@ -300,8 +300,9 @@ texinfo_documents = [
  
  # Example configuration for intersphinx: refer to the Python standard library.
  intersphinx_mapping = {
 -    'python': ('https://docs.python.org/3', None),
--    'llvm': ('http://llvm.org/releases/15.0.0/docs', None),
+-    'llvm': ('https://releases.llvm.org/20.1.0/docs', None),
 +    'python': ('https://docs.python.org/3', '/usr/share/doc/python3-doc/html/objects.inv'),
-+    'llvm': ('http://llvm.org/releases/19.0.0/docs', '/usr/share/doc/llvm-19-doc/html/objects.inv'),
++    'llvm': ('https://releases.llvm.org/20.1.0/docs',
++        '/usr/share/doc/llvm-20-doc/html/objects.inv'),
      }
  
  nitpicky = True
diff --git a/debian/rules b/debian/rules
index 017817e..7253a08 100755
--- a/debian/rules
+++ b/debian/rules
@@ -8,12 +8,17 @@ export CXXFLAGS := $(shell DEB_CXXFLAGS_MAINT_APPEND=-fPIC dpkg-buildflags --get
 export CXX_FLTO_FLAGS=
 export LD_FLTO_FLAGS=
 
+export LLVMLITE_SKIP_LLVM_VERSION_CHECK=1
+
 %:
 	dh $@ --with python3 --buildsystem=pybuild
 
 override_dh_auto_test:
-# prevent tests break if armhf/armel is build for, see #917252
-ifneq (,$(filter $(DEB_HOST_ARCH),armhf armel))
+# prevent tests break on archs:
+#   armhf/armel see #917252
+#   loong64 see #1120659
+#   riscv64 see #1071569
+ifneq (,$(filter $(DEB_HOST_ARCH),armhf armel loong64 riscv64))
 	dh_auto_test || true
 else
 	dh_auto_test
@@ -33,3 +38,5 @@ override_dh_python3:
 
 override_dh_gencontrol:
 	dh_gencontrol -- -Vllvm:Depends="$(shell basename $(shell $(LLVM_CONFIG) --prefix))"
+
+override_dh_dwz:
diff --git a/debian/watch b/debian/watch
index 6ede6b4..c9a487f 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,4 +1,7 @@
-version=4
-opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%llvmlite-$1.tar.gz%" \
-    https://github.com/numba/llvmlite/tags \
-    (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
+Version: 5
+
+Template: Github
+Owner: numba
+Project: llvmlite
+Version-Type: SEMANTIC_VERSION
+#Version-Type: ANY_VERSION


More information about the Pkg-llvm-team mailing list