[From nobody Thu Sep 10 09:37:06 2026
Received: (at submit) by bugs.debian.org; 5 Feb 2026 01:47:07 +0000
X-Spam-Checker-Version: SpamAssassin 4.0.1-bugs.debian.org_2005_01_02
 (2024-03-25) on buxtehude.debian.org
X-Spam-Level: 
X-Spam-Status: No, score=-10.1 required=4.0 tests=BAYES_00,FOURLA,
 FROMDEVELOPER,FVGT_m_MULTI_ODD,MD5_SHA1_SUM,RDNS_NONE,SPF_HELO_NONE,
 SPF_NONE,XMAILER_REPORTBUG autolearn=ham autolearn_force=no
 version=4.0.1-bugs.debian.org_2005_01_02
X-Spam-Bayes: score:0.0000 Tokens: new, 944; hammy, 150; neutral, 910; spammy,
 0. spammytokens: hammytokens:0.000-+--XDebbugsCc,
 0.000-+--X-Debbugs-Cc, 0.000-+--python3, 0.000-+--cmake,
 0.000-+--HTo:N*Debian
Return-path: &lt;stuart@debian.org&gt;
Received: from [130.220.241.121] (port=50598 helo=trochilus.nanonanonano.net)
 by buxtehude.debian.org with esmtp (Exim 4.96)
 (envelope-from &lt;stuart@debian.org&gt;) id 1vnoSX-006nus-3D
 for submit@bugs.debian.org; Thu, 05 Feb 2026 01:47:07 +0000
Content-Type: multipart/mixed; boundary=&quot;===============6242040190130373143==&quot;
MIME-Version: 1.0
From: Stuart Prescott &lt;stuart@debian.org&gt;
To: Debian Bug Tracking System &lt;submit@bugs.debian.org&gt;
Subject: llvmlite: Diff for NMU upload to experimental 0.46.0-0.1
Message-ID: &lt;177025602331.66390.1474847401588400124.reportbug@trochilus.nanonanonano.net&gt;
X-Mailer: reportbug 13.2.0
Date: Thu, 05 Feb 2026 12:47:03 +1100
Delivered-To: submit@bugs.debian.org

This is a multi-part MIME message sent by reportbug.


--===============6242040190130373143==
Content-Type: text/plain; charset=&quot;us-ascii&quot;
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Source: llvmlite
Version: 0.44.0-1
Severity: normal
X-Debbugs-Cc: stuart@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

--===============6242040190130373143==
Content-Type: text/plain; charset=&quot;us-ascii&quot;
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=&quot;llvmlite_0.44.0-1_to__0.46.0-0.1.diff&quot;

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 &lt;stuart@debian.org&gt;  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 &lt;pkg-llvm-team@lists.alioth.debian.org&gt;
 Uploaders: Mo Zhou &lt;lumin@debian.org&gt;
 Build-Depends:
+ cmake,
  debhelper-compat (= 13),
  dh-python,
+ libcurl4-gnutls-dev,
+ libedit-dev,
+ libzstd-dev,
  python3-doc &lt;!nodoc&gt;,
  python3:any | python3-all:any,
  python3-all-dev,
  python3-setuptools,
- llvm-19-dev,
- llvm-19-doc &lt;!nodoc&gt;,
+ llvm-21-dev,
+ llvm-21-doc &lt;!nodoc&gt;,
 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 &lt;stuart@debian.org&gt;
+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 &quot;hidden&quot;)
+ set(CMAKE_C_VISIBILITY_PRESET &quot;hidden&quot;)
+ 
+-find_package(LLVM REQUIRED CONFIG)
++find_package(LLVM REQUIRED CONFIG 21.1)
+ 
+ message(STATUS &quot;Found LLVM ${LLVM_PACKAGE_VERSION}&quot;)
+ message(STATUS &quot;Using LLVMConfig.cmake in: ${LLVM_DIR}&quot;)
+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 &quot;llvm/Transforms/Instrumentation/DataFlowSanitizer.h&quot;
+ #include &quot;llvm/Transforms/Instrumentation/GCOVProfiler.h&quot;
+ #include &quot;llvm/Transforms/Instrumentation/HWAddressSanitizer.h&quot;
+-#include &quot;llvm/Transforms/Instrumentation/InstrOrderFile.h&quot;
+ #include &quot;llvm/Transforms/Instrumentation/InstrProfiling.h&quot;
+-#include &quot;llvm/Transforms/Instrumentation/MemProfiler.h&quot;
+ #include &quot;llvm/Transforms/Instrumentation/MemorySanitizer.h&quot;
+ #include &quot;llvm/Transforms/Instrumentation/PGOInstrumentation.h&quot;
+ #include &quot;llvm/Transforms/Instrumentation/SanitizerCoverage.h&quot;
+@@ -639,6 +637,18 @@ LLVMPY_module_AddModuleDebugInfoPrinterPass(LLVMModulePassManagerRef MPM) {
+     }
+ #include &quot;PASSREGISTRY.def&quot;
+ 
++#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)-&gt;addPass(createModuleToFunctionPassAdaptor(NAME(ARG_LIST)));              \
++    }                                                                                               \
++    API_EXPORT(void)                                                                                \
++    LLVMPY_function_Add##NAME(LLVMFunctionPassManagerRef FPM, UNPAREN(PARAM_DECLS)) {               \
++        llvm::unwrap(FPM)-&gt;addPass(NAME(ARG_LIST));                                                 \
++    }
++#include &quot;PASSREGISTRY.def&quot;
++
+ #define LOOP_PASS(NAME)                                                        \
+     API_EXPORT(void) LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {   \
+         llvm::unwrap(MPM)-&gt;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 &quot;llvm/Support/MemoryBuffer.h&quot;
+ #include &quot;llvm/Support/SourceMgr.h&quot;
+ 
++#include &quot;llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h&quot;
++
++extern &quot;C&quot; 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-&gt;getTargetTriple())
+-                .setCPU(template_tm-&gt;getTargetCPU().str())
+-                .setRelocationModel(template_tm-&gt;getRelocationModel())
+-                .setCodeModel(template_tm-&gt;getCodeModel())
+-                .setCodeGenOptLevel(template_tm-&gt;getOptLevel())
+-                .setFeatures(template_tm-&gt;getTargetFeatureString())
+-                .setOptions(template_tm-&gt;Options));
++        auto JTMB = JITTargetMachineBuilder(template_tm-&gt;getTargetTriple());\
++        JTMB.setCPU(template_tm-&gt;getTargetCPU().str())\
++            .setRelocationModel(template_tm-&gt;getRelocationModel())\
++            .setCodeModel(template_tm-&gt;getCodeModel())\
++            .setCodeGenOptLevel(template_tm-&gt;getOptLevel())\
++            .setFeatures(template_tm-&gt;getTargetFeatureString())\
++            .setOptions(template_tm-&gt;Options);\
++        builder.setJITTargetMachineBuilder(std::move(JTMB));
+     }
++    auto triple = builder.getJITTargetMachineBuilder()-&gt;getTargetTriple();
+     builder.setObjectLinkingLayerCreator(
+-        [=](llvm::orc::ExecutionSession &amp;session, const llvm::Triple &amp;triple)
+-            -&gt; std::unique_ptr&lt;llvm::orc::ObjectLayer&gt; {
++        [=](llvm::orc::ExecutionSession &amp;session) -&gt; Expected&lt;std::unique_ptr&lt;llvm::orc::ObjectLayer&gt;&gt; {
+             if (useJitLink) {
+                 auto linkingLayer =
+                     std::make_unique&lt;llvm::orc::ObjectLinkingLayer&gt;(session);
+@@ -108,7 +113,7 @@ LLVMPY_CreateLLJITCompiler(LLVMTargetMachineRef tm, bool suppressErrors,
+                 return linkingLayer;
+             } else {
+                 auto linkingLayer = std::make_unique&lt;
+-                    llvm::orc::RTDyldObjectLinkingLayer&gt;(session, []() {
++                    llvm::orc::RTDyldObjectLinkingLayer&gt;(session, [](const llvm::MemoryBuffer &amp;ObjBuffer) {
+                     return std::make_unique&lt;llvm::SectionMemoryManager&gt;();
+                 });
+                 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 &lt;stuart@debian.org&gt;
+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):
+             &quot;&quot;&quot;
+         subprocess.check_call([sys.executable, &quot;-c&quot;, code])
+ 
++    @unittest.skip(&quot;Debian package built with Debian llvm version&quot;)
+     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 &lt;stuart@debian.org&gt;
+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(&quot;'nocapture' attribute test broken with llvm-21?&quot;)
+     def test_add_function_attribute(self):
+         mod = self.module()
+         fn = mod.get_function(&quot;sum&quot;)
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 &quot;llvm/Transforms/IPO.h&quot;
- #include &quot;llvm/Transforms/Scalar.h&quot;
- 
-+#include &quot;llvm/Pass.h&quot;
- #include &lt;llvm/IR/PassTimingInfo.h&gt;
- 
- #include &lt;llvm/Analysis/AliasAnalysisEvaluator.h&gt;
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 &lt;rjj@nvidia.com&gt;
-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 &quot;%OPAQUE_POINTERS%&quot;==&quot;yes&quot; (
--  set LLVMLITE_ENABLE_OPAQUE_POINTERS=1
--  echo &quot;Testing with opaque pointers enabled&quot;
-+  set LLVMLITE_ENABLE_IR_LAYER_TYPED_POINTERS=0
-+  echo &quot;Testing with IR layer opaque pointers enabled&quot;
- ) else (
--  echo &quot;Testing with opaque pointers disabled&quot;
-+  echo &quot;Testing with IR layer opaque pointers disabled&quot;
- )
- 
- 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 [ &quot;$OPAQUE_POINTERS&quot; == &quot;yes&quot; ]; then
--    export LLVMLITE_ENABLE_OPAQUE_POINTERS=1
--    echo &quot;Testing with opaque pointers enabled&quot;
-+    export LLVMLITE_ENABLE_IR_LAYER_TYPED_POINTERS=0
-+    echo &quot;Testing with IR layer opaque pointers enabled&quot;
- else
--    echo &quot;Testing with opaque pointers disabled&quot;
-+    echo &quot;Testing with IR layer opaque pointers disabled&quot;
- fi
- 
- if [ &quot;$WHEEL&quot; == &quot;yes&quot; ]; 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 &lt;https://llvm.org/docs/OpaquePointers.html&gt;`_:
-   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
-+&lt;https://docs.nvidia.com/cuda/nvvm-ir-spec/&gt;`_.
- 
- 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 (&gt;= 0.46), the IR layer will use Opaque
-+  Pointers by default.
-+- In a subsequent version of llvmlite (&gt;= 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 '&quot;{0}&quot;'.format(x.replace('\\', '\\5c').replace('&quot;', '\\22'))
-@@ -145,8 +143,6 @@ def from_llvm(cls, typeref, ir_ctx):
-         &quot;&quot;&quot;
-         Create from a llvmlite.binding.TypeRef
-         &quot;&quot;&quot;
--        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 &quot;{0}*&quot;.format(self.pointee) if self.addrspace == 0 else \
-                    &quot;{0} addrspace({1})*&quot;.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):
--        &quot;&quot;&quot;
--        Create from a llvmlite.binding.TypeRef
--        &quot;&quot;&quot;
--        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):
-     &quot;&quot;&quot;
-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 = \
-         &quot;&quot;&quot;i32 @&quot;my_func&quot;(i32 %&quot;.1&quot;, i32 %&quot;.2&quot;, double %&quot;.3&quot;, ptr %&quot;.4&quot;)&quot;&quot;&quot; \
--        if opaque_pointers_enabled else \
-+        if not ir_layer_typed_pointers_enabled else \
-         &quot;&quot;&quot;i32 @&quot;my_func&quot;(i32 %&quot;.1&quot;, i32 %&quot;.2&quot;, double %&quot;.3&quot;, i32* %&quot;.4&quot;)&quot;&quot;&quot;
- 
-     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,
-                              (&quot;declare %s alwaysinline convergent optsize &quot;
-                               &quot;alignstack(16) &quot;
-@@ -172,8 +168,7 @@ def test_function_attributes(self):
-         func.args[3].add_attribute(&quot;nonnull&quot;)
-         func.return_value.add_attribute(&quot;noalias&quot;)
-         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,
-                              &quot;&quot;&quot;declare noalias i32 @&quot;my_func&quot;(i32 zeroext %&quot;.1&quot;, i32 dereferenceable(5) dereferenceable_or_null(10) %&quot;.2&quot;, double %&quot;.3&quot;, ptr nonnull align 4 %&quot;.4&quot;)&quot;&quot;&quot;  # noqa E501
-                              )
-@@ -284,8 +279,7 @@ def test_declare_intrinsics(self):
-         assume = module.declare_intrinsic('llvm.assume')
-         self.check_descr(self.descr(powi).strip(), &quot;&quot;&quot;\
-             declare double @&quot;llvm.powi.f64&quot;(double %&quot;.1&quot;, i32 %&quot;.2&quot;)&quot;&quot;&quot;)
--        # 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(), &quot;&quot;&quot;\
-                 declare void @&quot;llvm.memset.p0i8.i32&quot;(ptr %&quot;.1&quot;, i8 %&quot;.2&quot;, i32 %&quot;.3&quot;, i1 %&quot;.4&quot;)&quot;&quot;&quot;)  # noqa E501
-             self.check_descr(self.descr(memcpy).strip(), &quot;&quot;&quot;\
-@@ -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(&quot;!0 = !{ ptr null }&quot;, mod)
-         else:
-             self.assert_ir_line(&quot;!0 = !{ i32* null }&quot;, 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),
-                              &quot;&lt;ir.GlobalVariable 'globdouble' of type 'ptr'&gt;&quot;)
-         else:
-@@ -1027,7 +1019,7 @@ def test_mem_ops(self):
-         self.assertEqual(j.type, ir.VoidType())
-         k = builder.load_atomic(c, ordering=&quot;seq_cst&quot;, 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),
-                              &quot;cannot store i32 to ptr: mismatching types&quot;)
-             self.check_block(block, &quot;&quot;&quot;\
-@@ -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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;c&quot; = 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;d&quot; = bitcast i32 %&quot;.1&quot; 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;d&quot; = bitcast i32 %&quot;.1&quot; 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;c&quot; = 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;c&quot; = 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, &quot;k&quot;)  # 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;c&quot; = trunc i32 %&quot;.1&quot; 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;c&quot; = 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, &quot;&quot;&quot;\
-                 my_block:
-                     indirectbr ptr blockaddress(@&quot;my_func&quot;, %&quot;b_1&quot;), [label %&quot;b_1&quot;, label %&quot;b_2&quot;]
-@@ -1505,8 +1487,7 @@ def test_call_metadata(self):
-         a = builder.alloca(int32, name=&quot;a&quot;)
-         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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;a&quot; = 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, &quot;&quot;&quot;\
-             my_block:
-                 %&quot;retval&quot; = 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, &quot;&quot;&quot;\
-             my_block:
-                 %&quot;retval&quot; = 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;lp&quot; = 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, &quot;&quot;&quot;\
-                 my_block:
-                     %&quot;c&quot; = 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, &quot;myconstant&quot;)
-         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 @&quot;myconstant&quot;, 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) @&quot;myconstant&quot;, i32 0, i32 1)'))
-@@ -2819,8 +2790,7 @@ def test_bitcast(self):
-         m = self.module()
-         gv = ir.GlobalVariable(m, int32, &quot;myconstant&quot;)
-         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 @&quot;myconstant&quot; to ptr)')
-         else:
-             self.assertEqual(str(c), 'bitcast (i32* @&quot;myconstant&quot; 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, &quot;myconstant&quot;)
-         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 @&quot;myconstant&quot; 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 &lt;rjj@nvidia.com&gt;
-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 &quot;ptr&quot;
- 
-+    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):
-         &quot;&quot;&quot;
-@@ -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):
-         &quot;&quot;&quot;
-         Test the string representation of types.
-
-From 4faac9686c0d8eb6df5ad7fb31ee7cfa26a872cf Mon Sep 17 00:00:00 2001
-From: Ricardo Jesus &lt;rjj@nvidia.com&gt;
-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&lt;char *&gt;(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 &gt;= 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 &gt;= 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 &quot;C&quot; */
- 
-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-&gt;isPointerTy())
--        return -1;
--    tp = tp-&gt;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-&gt;isPointerTy())
--        return -1;
--    tp = tp-&gt;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-&gt;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&lt;llvm::PointerType&gt;(unwrapped);
--    if (ty != nullptr) {
--#if LLVM_VERSION_MAJOR &lt; 14
--        return llvm::wrap(ty-&gt;getElementType());
--#else
--        return llvm::wrap(ty-&gt;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):
-         &quot;&quot;&quot;
-         return ffi.lib.LLVMPY_ABIAlignmentOfType(self, ty)
- 
--    def get_pointee_abi_size(self, ty):
--        &quot;&quot;&quot;
--        Get ABI size of pointee type of LLVM pointer type *ty*.
--        &quot;&quot;&quot;
--        if opaque_pointers_enabled:
--            raise RuntimeError(&quot;Cannot get pointee type in opaque pointer &quot;
--                               &quot;mode.&quot;)
--        size = ffi.lib.LLVMPY_ABISizeOfElementType(self, ty)
--        if size == -1:
--            raise RuntimeError(&quot;Not a pointer type: %s&quot; % (ty,))
--        return size
--
--    def get_pointee_abi_alignment(self, ty):
--        &quot;&quot;&quot;
--        Get minimum ABI alignment of pointee type of LLVM pointer type *ty*.
--        &quot;&quot;&quot;
--        if opaque_pointers_enabled:
--            raise RuntimeError(&quot;Cannot get pointee type in opaque pointer &quot;
--                               &quot;mode.&quot;)
--        size = ffi.lib.LLVMPY_ABIAlignmentOfElementType(self, ty)
--        if size == -1:
--            raise RuntimeError(&quot;Not a pointer type: %s&quot; % (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):
-         &quot;&quot;&quot;
-         Returns iterator over enclosing types
-         &quot;&quot;&quot;
--        if self.is_pointer and opaque_pointers_enabled:
-+        if self.is_pointer:
-             raise ValueError(&quot;Type {} doesn't contain elements.&quot;.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(&quot;glob_struct&quot;)
-         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&quot;%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }&quot;,
-             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(&quot;Type ptr is not a function&quot;, str(raises.exception))
--        else:
--            self.assertIn(&quot;Type i32 (i32, i32)* is not a function&quot;,
--                          str(raises.exception))
-+        self.assertIn(&quot;Type ptr is not a function&quot;, 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 @&quot;llvm.powi.f64&quot;(double %&quot;.1&quot;, i32 %&quot;.2&quot;)&quot;&quot;&quot;)
-         if not ir_layer_typed_pointers_enabled:
-             self.check_descr(self.descr(memset).strip(), &quot;&quot;&quot;\
--                declare void @&quot;llvm.memset.p0i8.i32&quot;(ptr %&quot;.1&quot;, i8 %&quot;.2&quot;, i32 %&quot;.3&quot;, i1 %&quot;.4&quot;)&quot;&quot;&quot;)  # noqa E501
-+                declare void @&quot;llvm.memset.p0.i32&quot;(ptr %&quot;.1&quot;, i8 %&quot;.2&quot;, i32 %&quot;.3&quot;, i1 %&quot;.4&quot;)&quot;&quot;&quot;)  # noqa E501
-             self.check_descr(self.descr(memcpy).strip(), &quot;&quot;&quot;\
--                declare void @&quot;llvm.memcpy.p0i8.p0i8.i32&quot;(ptr %&quot;.1&quot;, ptr %&quot;.2&quot;, i32 %&quot;.3&quot;, i1 %&quot;.4&quot;)&quot;&quot;&quot;)  # noqa E501
-+                declare void @&quot;llvm.memcpy.p0.p0.i32&quot;(ptr %&quot;.1&quot;, ptr %&quot;.2&quot;, i32 %&quot;.3&quot;, i1 %&quot;.4&quot;)&quot;&quot;&quot;)  # noqa E501
-         else:
-             self.check_descr(self.descr(memset).strip(), &quot;&quot;&quot;\
-                 declare void @&quot;llvm.memset.p0i8.i32&quot;(i8* %&quot;.1&quot;, i8 %&quot;.2&quot;, i32 %&quot;.3&quot;, i1 %&quot;.4&quot;)&quot;&quot;&quot;)  # 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):
-         &quot;&quot;&quot;
-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(&quot;call void @NRT_incref(ptr %ptr)&quot;, str(mod))
--        else:
--            self.assertIn(&quot;call void @NRT_incref(i8* %ptr)&quot;, str(mod))
-+        self.assertIn(&quot;call void @NRT_incref(ptr %ptr)&quot;, 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(&quot;call void @NRT_incref(ptr %ptr)&quot;, str(mod))
--        else:
--            self.assertIn(&quot;call void @NRT_incref(i8* %ptr)&quot;, str(mod))
-+        self.assertIn(&quot;call void @NRT_incref(ptr %ptr)&quot;, str(mod))
- 
-     per_bb_ir_3 = r&quot;&quot;&quot;
- 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
- }
--&quot;&quot;&quot; if opaque_pointers_enabled else r&quot;&quot;&quot;
--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
--}
- &quot;&quot;&quot;
- 
-     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(&quot;call void @NRT_decref(ptr %other)&quot;, str(mod))
--        else:
--            self.assertIn(&quot;call void @NRT_decref(i8* %other)&quot;, str(mod))
-+        self.assertIn(&quot;call void @NRT_decref(ptr %other)&quot;, 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(&quot;call void @NRT_decref(ptr %other)&quot;, str(mod))
--        else:
--            self.assertIn(&quot;call void @NRT_decref(i8* %other)&quot;, str(mod))
-+        self.assertIn(&quot;call void @NRT_decref(ptr %other)&quot;, str(mod))
- 
-     per_bb_ir_4 = r&quot;&quot;&quot;
- ; reordered
-@@ -323,37 +296,19 @@ def test_per_bb_3_legacy(self):
-     call void @NRT_incref(ptr %ptr)
-     ret void
- }
--&quot;&quot;&quot; if opaque_pointers_enabled else r&quot;&quot;&quot;
--; 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
--}
- &quot;&quot;&quot;
- 
-     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(&quot;call void @NRT_decref(ptr %other)&quot;, str(mod))
--        else:
--            self.assertIn(&quot;call void @NRT_decref(i8* %other)&quot;, str(mod))
-+        self.assertIn(&quot;call void @NRT_decref(ptr %other)&quot;, 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(&quot;call void @NRT_decref(ptr %other)&quot;, str(mod))
--        else:
--            self.assertIn(&quot;call void @NRT_decref(i8* %other)&quot;, str(mod))
-+        self.assertIn(&quot;call void @NRT_decref(ptr %other)&quot;, str(mod))
- 
- 
- class TestDiamond(BaseTestByIR):
-
-From 3b6fb0d00a0486c65dddc13bd49271f017385c07 Mon Sep 17 00:00:00 2001
-From: Yashwant Singh &lt;yashwants@nvidia.com&gt;
-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&lt;TargetMachine *&gt;(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-&gt;getPassInstrumentationCallbacks();
-+    TP-&gt;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-&gt;setOutStream(os);
-+    TP-&gt;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 &lt; 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(&quot;LLVMSectionIterator&quot;)
- LLVMOrcLLJITRef = _make_opaque_ref(&quot;LLVMOrcLLJITRef&quot;)
- LLVMOrcDylibTrackerRef = _make_opaque_ref(&quot;LLVMOrcDylibTrackerRef&quot;)
--
-+LLVMTimePassesHandlerRef = _make_opaque_ref(&quot;LLVMTimePassesHandler&quot;)
- LLVMPipelineTuningOptionsRef = _make_opaque_ref(&quot;LLVMPipeLineTuningOptions&quot;)
- LLVMModulePassManagerRef = _make_opaque_ref(&quot;LLVMModulePassManager&quot;)
- LLVMFunctionPassManagerRef = _make_opaque_ref(&quot;LLVMFunctionPassManager&quot;)
-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):
-+        &quot;&quot;&quot;Enable the pass timers.
-+
-+        Raises
-+        ------
-+        RuntimeError
-+            If pass timing is already enabled.
-+        &quot;&quot;&quot;
-+        if self._time_passes_handler:
-+            raise RuntimeError(&quot;Pass timing can only be done once&quot;)
-+        self._time_passes_handler = TimePassesHandler()
-+        ffi.lib.LLVMPY_EnableTimePasses(self, self._time_passes_handler)
-+
-+    def finish_pass_timing(self):
-+        &quot;&quot;&quot;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.
-+        &quot;&quot;&quot;
-+
-+        if not self._time_passes_handler:
-+            raise RuntimeError(&quot;Pass timing is not enabled&quot;)
-+
-+        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(&quot;sum&quot;), pb)
-         pb.close()
- 
-+    def test_time_passes(self):
-+        &quot;&quot;&quot;Test pass timing reports for O3 and O0 optimization levels&quot;&quot;&quot;
-+        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(&quot;Pass execution timing report&quot;), 1)
-+        self.assertEqual(report_O0.count(&quot;Pass execution timing report&quot;), 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, &quot;only be done once&quot;):
-+            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, &quot;not enabled&quot;):
-+            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 &lt;yashwants@nvidia.com&gt;
-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 = &quot;&quot;&quot;
-+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
-+}
-+&quot;&quot;&quot;
-+
-+dbgmodstr = &quot;&quot;&quot;
-+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: &quot;clang version 3.4 (192092)&quot;, isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
-+!1 = !DIFile(filename: &quot;test1.c&quot;, directory: &quot;/tmp&quot;)
-+!2 = !{}
-+!4 = distinct !DISubprogram(name: &quot;f&quot;, 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: &quot;test1.c&quot;, directory: &quot;/tmp&quot;)
-+!6 = !DISubroutineType(types: !7)
-+!7 = !{null}
-+!8 = distinct !DICompileUnit(language: DW_LANG_C99, producer: &quot;clang version 3.4 (192092)&quot;, isOptimized: false, emissionKind: FullDebug, file: !9, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
-+!9 = !DIFile(filename: &quot;test2.c&quot;, directory: &quot;/tmp&quot;)
-+!11 = distinct !DISubprogram(name: &quot;g&quot;, 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: &quot;test2.c&quot;, directory: &quot;/tmp&quot;)
-+!13 = !{i32 2, !&quot;Dwarf Version&quot;, i32 4}
-+!14 = !DILocation(line: 1, scope: !4)
-+!15 = !DILocation(line: 1, scope: !11, inlinedAt: !14)
-+!16 = !{i32 1, !&quot;Debug Info Version&quot;, i32 3}
-+&quot;&quot;&quot;
-+
-+
-+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(&quot;attributor&quot;, AttributorPass())
-+MODULE_PASS(&quot;annotation2metadata&quot;, Annotation2MetadataPass())
-+MODULE_PASS(&quot;openmp-opt&quot;, OpenMPOptPass())
-+MODULE_PASS(&quot;called-value-propagation&quot;, CalledValuePropagationPass())
-+MODULE_PASS(&quot;canonicalize-aliases&quot;, CanonicalizeAliasesPass())
-+MODULE_PASS(&quot;cg-profile&quot;, CGProfilePass())
-+MODULE_PASS(&quot;check-debugify&quot;, NewPMCheckDebugifyPass())
-+MODULE_PASS(&quot;coro-early&quot;, CoroEarlyPass())
-+MODULE_PASS(&quot;coro-cleanup&quot;, CoroCleanupPass())
-+MODULE_PASS(&quot;cross-dso-cfi&quot;, CrossDSOCFIPass())
-+MODULE_PASS(&quot;debugify&quot;, NewPMDebugifyPass())
-+MODULE_PASS(&quot;dot-callgraph&quot;, CallGraphDOTPrinterPass())
-+MODULE_PASS(&quot;elim-avail-extern&quot;, EliminateAvailableExternallyPass())
-+MODULE_PASS(&quot;extract-blocks&quot;, BlockExtractorPass())
-+MODULE_PASS(&quot;forceattrs&quot;, ForceFunctionAttrsPass())
-+MODULE_PASS(&quot;function-import&quot;, FunctionImportPass())
-+MODULE_PASS(&quot;function-specialization&quot;, FunctionSpecializationPass())
-+MODULE_PASS(&quot;globalsplit&quot;, GlobalSplitPass())
-+MODULE_PASS(&quot;hotcoldsplit&quot;, HotColdSplittingPass())
-+MODULE_PASS(&quot;inferattrs&quot;, InferFunctionAttrsPass())
-+MODULE_PASS(&quot;inliner-wrapper&quot;, ModuleInlinerWrapperPass())
-+MODULE_PASS(&quot;inliner-ml-advisor-release&quot;, ModuleInlinerWrapperPass(getInlineParams(), true, {}, InliningAdvisorMode::Release, 0))
-+MODULE_PASS(&quot;print&lt;inline-advisor&gt;&quot;, InlineAdvisorAnalysisPrinterPass(dbgs()))
-+MODULE_PASS(&quot;inliner-wrapper-no-mandatory-first&quot;, ModuleInlinerWrapperPass(getInlineParams(),false))
-+MODULE_PASS(&quot;insert-gcov-profiling&quot;, GCOVProfilerPass())
-+MODULE_PASS(&quot;instrorderfile&quot;, InstrOrderFilePass())
-+MODULE_PASS(&quot;instrprof&quot;, InstrProfiling())
-+MODULE_PASS(&quot;invalidate&lt;all&gt;&quot;, InvalidateAllAnalysesPass())
-+MODULE_PASS(&quot;iroutliner&quot;, IROutlinerPass())
-+MODULE_PASS(&quot;print-ir-similarity&quot;, IRSimilarityAnalysisPrinterPass(dbgs()))
-+MODULE_PASS(&quot;lower-global-dtors&quot;, LowerGlobalDtorsPass())
-+MODULE_PASS(&quot;lowertypetests&quot;, LowerTypeTestsPass())
-+MODULE_PASS(&quot;metarenamer&quot;, MetaRenamerPass())
-+MODULE_PASS(&quot;name-anon-globals&quot;, NameAnonGlobalPass())
-+MODULE_PASS(&quot;no-op-module&quot;, NoOpModulePass())
-+MODULE_PASS(&quot;objc-arc-apelim&quot;, ObjCARCAPElimPass())
-+MODULE_PASS(&quot;pgo-icall-prom&quot;, PGOIndirectCallPromotion())
-+MODULE_PASS(&quot;pgo-instr-gen&quot;, PGOInstrumentationGen())
-+MODULE_PASS(&quot;pgo-instr-use&quot;, PGOInstrumentationUse())
-+MODULE_PASS(&quot;print-profile-summary&quot;, ProfileSummaryPrinterPass(dbgs()))
-+MODULE_PASS(&quot;print-callgraph&quot;, CallGraphPrinterPass(dbgs()))
-+MODULE_PASS(&quot;print&quot;, PrintModulePass(dbgs()))
-+MODULE_PASS(&quot;print-lcg&quot;, LazyCallGraphPrinterPass(dbgs()))
-+MODULE_PASS(&quot;print-lcg-dot&quot;, LazyCallGraphDOTPrinterPass(dbgs()))
-+MODULE_PASS(&quot;print-must-be-executed-contexts&quot;, MustBeExecutedContextPrinterPass(dbgs()))
-+MODULE_PASS(&quot;print-stack-safety&quot;, StackSafetyGlobalPrinterPass(dbgs()))
-+MODULE_PASS(&quot;print&lt;module-debuginfo&gt;&quot;, ModuleDebugInfoPrinterPass(dbgs()))
-+MODULE_PASS(&quot;recompute-globalsaa&quot;, RecomputeGlobalsAAPass())
-+MODULE_PASS(&quot;rel-lookup-table-converter&quot;, RelLookupTableConverterPass())
-+MODULE_PASS(&quot;rewrite-statepoints-for-gc&quot;, RewriteStatepointsForGC())
-+MODULE_PASS(&quot;rewrite-symbols&quot;, RewriteSymbolPass())
-+MODULE_PASS(&quot;sample-profile&quot;, SampleProfileLoaderPass())
-+MODULE_PASS(&quot;scc-oz-module-inliner&quot;,buildInlinerPipeline(OptimizationLevel::Oz, ThinOrFullLTOPhase::None))
-+MODULE_PASS(&quot;pseudo-probe&quot;, SampleProfileProbePass(TM))
-+MODULE_PASS(&quot;strip-nonlinetable-debuginfo&quot;, StripNonLineTableDebugInfoPass())
-+MODULE_PASS(&quot;synthetic-counts-propagation&quot;, SyntheticCountsPropagation())
-+MODULE_PASS(&quot;trigger-crash&quot;, TriggerCrashPass())
-+MODULE_PASS(&quot;verify&quot;, VerifierPass())
-+MODULE_PASS(&quot;view-callgraph&quot;, CallGraphViewerPass())
-+MODULE_PASS(&quot;wholeprogramdevirt&quot;, WholeProgramDevirtPass())
-+MODULE_PASS(&quot;dfsan&quot;, DataFlowSanitizerPass())
-+MODULE_PASS(&quot;msan-module&quot;, ModuleMemorySanitizerPass({}))
-+MODULE_PASS(&quot;module-inline&quot;, ModuleInlinerPass())
-+MODULE_PASS(&quot;tsan-module&quot;, ModuleThreadSanitizerPass())
-+MODULE_PASS(&quot;sancov-module&quot;, ModuleSanitizerCoveragePass())
-+MODULE_PASS(&quot;memprof-module&quot;, ModuleMemProfilerPass())
-+MODULE_PASS(&quot;poison-checking&quot;, PoisonCheckingPass())
-+MODULE_PASS(&quot;pseudo-probe-update&quot;, PseudoProbeUpdatePass())
-+
-+CGSCC_PASS(&quot;argpromotion&quot;, ArgumentPromotionPass())
-+CGSCC_PASS(&quot;invalidate&lt;all&gt;&quot;, InvalidateAllAnalysesPass())
-+CGSCC_PASS(&quot;attributor-cgscc&quot;, AttributorCGSCCPass())
-+CGSCC_PASS(&quot;openmp-opt-cgscc&quot;, OpenMPOptCGSCCPass())
-+CGSCC_PASS(&quot;no-op-cgscc&quot;, NoOpCGSCCPass())
-+
-+FUNCTION_PASS(&quot;add-discriminators&quot;, AddDiscriminatorsPass())
-+FUNCTION_PASS(&quot;assume-builder&quot;, AssumeBuilderPass())
-+FUNCTION_PASS(&quot;assume-simplify&quot;, AssumeSimplifyPass())
-+FUNCTION_PASS(&quot;alignment-from-assumptions&quot;, AlignmentFromAssumptionsPass())
-+FUNCTION_PASS(&quot;annotation-remarks&quot;, AnnotationRemarksPass())
-+FUNCTION_PASS(&quot;bdce&quot;, BDCEPass())
-+FUNCTION_PASS(&quot;bounds-checking&quot;, BoundsCheckingPass())
-+FUNCTION_PASS(&quot;callsite-splitting&quot;, CallSiteSplittingPass())
-+FUNCTION_PASS(&quot;consthoist&quot;, ConstantHoistingPass())
-+FUNCTION_PASS(&quot;constraint-elimination&quot;, ConstraintEliminationPass())
-+FUNCTION_PASS(&quot;chr&quot;, ControlHeightReductionPass())
-+FUNCTION_PASS(&quot;coro-elide&quot;, CoroElidePass())
-+FUNCTION_PASS(&quot;correlated-propagation&quot;, CorrelatedValuePropagationPass())
-+FUNCTION_PASS(&quot;dfa-jump-threading&quot;, DFAJumpThreadingPass())
-+FUNCTION_PASS(&quot;div-rem-pairs&quot;, DivRemPairsPass())
-+FUNCTION_PASS(&quot;fix-irreducible&quot;, FixIrreduciblePass())
-+FUNCTION_PASS(&quot;flattencfg&quot;, FlattenCFGPass())
-+FUNCTION_PASS(&quot;make-guards-explicit&quot;, MakeGuardsExplicitPass())
-+FUNCTION_PASS(&quot;gvn-hoist&quot;, GVNHoistPass())
-+FUNCTION_PASS(&quot;gvn-sink&quot;, GVNSinkPass())
-+FUNCTION_PASS(&quot;helloworld&quot;, HelloWorldPass())
-+FUNCTION_PASS(&quot;infer-address-spaces&quot;, InferAddressSpacesPass())
-+FUNCTION_PASS(&quot;instcombine&quot;, InstCombinePass())
-+FUNCTION_PASS(&quot;instcount&quot;, InstCountPass())
-+FUNCTION_PASS(&quot;instsimplify&quot;, InstSimplifyPass())
-+FUNCTION_PASS(&quot;invalidate&lt;all&gt;&quot;, InvalidateAllAnalysesPass())
-+FUNCTION_PASS(&quot;irce&quot;, IRCEPass())
-+FUNCTION_PASS(&quot;float2int&quot;, Float2IntPass())
-+FUNCTION_PASS(&quot;no-op-function&quot;, NoOpFunctionPass())
-+FUNCTION_PASS(&quot;libcalls-shrinkwrap&quot;, LibCallsShrinkWrapPass())
-+FUNCTION_PASS(&quot;inject-tli-mappings&quot;, InjectTLIMappings())
-+FUNCTION_PASS(&quot;lower-expect&quot;, LowerExpectIntrinsicPass())
-+FUNCTION_PASS(&quot;lower-guard-intrinsic&quot;, LowerGuardIntrinsicPass())
-+FUNCTION_PASS(&quot;lower-constant-intrinsics&quot;, LowerConstantIntrinsicsPass())
-+FUNCTION_PASS(&quot;lower-widenable-condition&quot;, LowerWidenableConditionPass())
-+FUNCTION_PASS(&quot;guard-widening&quot;, GuardWideningPass())
-+FUNCTION_PASS(&quot;load-store-vectorizer&quot;, LoadStoreVectorizerPass())
-+FUNCTION_PASS(&quot;loop-sink&quot;, LoopSinkPass())
-+FUNCTION_PASS(&quot;mem2reg&quot;, PromotePass())
-+FUNCTION_PASS(&quot;mergeicmps&quot;, MergeICmpsPass())
-+FUNCTION_PASS(&quot;nary-reassociate&quot;, NaryReassociatePass())
-+FUNCTION_PASS(&quot;jump-threading&quot;, JumpThreadingPass())
-+FUNCTION_PASS(&quot;partially-inline-libcalls&quot;, PartiallyInlineLibCallsPass())
-+FUNCTION_PASS(&quot;loop-data-prefetch&quot;, LoopDataPrefetchPass())
-+FUNCTION_PASS(&quot;loop-load-elim&quot;, LoopLoadEliminationPass())
-+FUNCTION_PASS(&quot;loop-fusion&quot;, LoopFusePass())
-+FUNCTION_PASS(&quot;loop-distribute&quot;, LoopDistributePass())
-+FUNCTION_PASS(&quot;loop-versioning&quot;, LoopVersioningPass())
-+FUNCTION_PASS(&quot;objc-arc&quot;, ObjCARCOptPass())
-+FUNCTION_PASS(&quot;objc-arc-contract&quot;, ObjCARCContractPass())
-+FUNCTION_PASS(&quot;objc-arc-expand&quot;, ObjCARCExpandPass())
-+FUNCTION_PASS(&quot;pgo-memop-opt&quot;, PGOMemOPSizeOpt())
-+FUNCTION_PASS(&quot;print&quot;, PrintFunctionPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;assumptions&gt;&quot;, AssumptionPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;block-freq&gt;&quot;, BlockFrequencyPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;branch-prob&gt;&quot;, BranchProbabilityPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;cost-model&gt;&quot;, CostModelPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;cycles&gt;&quot;, CycleInfoPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;da&gt;&quot;, DependenceAnalysisPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;divergence&gt;&quot;, DivergenceAnalysisPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;domtree&gt;&quot;, DominatorTreePrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;postdomtree&gt;&quot;, PostDominatorTreePrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;delinearization&gt;&quot;, DelinearizationPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;demanded-bits&gt;&quot;, DemandedBitsPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;domfrontier&gt;&quot;, DominanceFrontierPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;func-properties&gt;&quot;, FunctionPropertiesPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;inline-cost&gt;&quot;, InlineCostAnnotationPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;inliner-size-estimator&gt;&quot;,InlineSizeEstimatorAnalysisPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;loops&gt;&quot;, LoopPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;memoryssa&gt;&quot;, MemorySSAPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;memoryssa-walker&gt;&quot;, MemorySSAWalkerPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;phi-values&gt;&quot;, PhiValuesPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;regions&gt;&quot;, RegionInfoPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;scalar-evolution&gt;&quot;, ScalarEvolutionPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print&lt;stack-safety-local&gt;&quot;, StackSafetyPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print-alias-sets&quot;, AliasSetsPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print-predicateinfo&quot;, PredicateInfoPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print-mustexecute&quot;, MustExecutePrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;print-memderefs&quot;, MemDerefPrinterPass(dbgs()))
-+FUNCTION_PASS(&quot;redundant-dbg-inst-elim&quot;, RedundantDbgInstEliminationPass())
-+FUNCTION_PASS(&quot;scalarize-masked-mem-intrin&quot;, ScalarizeMaskedMemIntrinPass())
-+FUNCTION_PASS(&quot;scalarizer&quot;, ScalarizerPass())
-+FUNCTION_PASS(&quot;separate-const-offset-from-gep&quot;, SeparateConstOffsetFromGEPPass())
-+FUNCTION_PASS(&quot;slp-vectorizer&quot;, SLPVectorizerPass())
-+FUNCTION_PASS(&quot;slsr&quot;, StraightLineStrengthReducePass())
-+FUNCTION_PASS(&quot;speculative-execution&quot;, SpeculativeExecutionPass())
-+FUNCTION_PASS(&quot;strip-gc-relocates&quot;, StripGCRelocates())
-+FUNCTION_PASS(&quot;structurizecfg&quot;, StructurizeCFGPass())
-+FUNCTION_PASS(&quot;unify-loop-exits&quot;, UnifyLoopExitsPass())
-+FUNCTION_PASS(&quot;vector-combine&quot;, VectorCombinePass())
-+FUNCTION_PASS(&quot;verify&quot;, VerifierPass())
-+FUNCTION_PASS(&quot;verify&lt;domtree&gt;&quot;, DominatorTreeVerifierPass())
-+FUNCTION_PASS(&quot;verify&lt;loops&gt;&quot;, LoopVerifierPass())
-+FUNCTION_PASS(&quot;verify&lt;memoryssa&gt;&quot;, MemorySSAVerifierPass())
-+FUNCTION_PASS(&quot;verify&lt;regions&gt;&quot;, RegionInfoVerifierPass())
-+FUNCTION_PASS(&quot;verify&lt;safepoint-ir&gt;&quot;, SafepointIRVerifierPass())
-+FUNCTION_PASS(&quot;verify&lt;scalar-evolution&gt;&quot;, ScalarEvolutionVerifierPass())
-+FUNCTION_PASS(&quot;view-cfg&quot;, CFGViewerPass())
-+FUNCTION_PASS(&quot;view-cfg-only&quot;, CFGOnlyViewerPass())
-+FUNCTION_PASS(&quot;tlshoist&quot;, TLSVariableHoistPass())
-+FUNCTION_PASS(&quot;transform-warning&quot;, WarnMissedTransformationsPass())
-+FUNCTION_PASS(&quot;tsan&quot;, ThreadSanitizerPass())
-+FUNCTION_PASS(&quot;memprof&quot;, MemProfilerPass())
-+
-+LOOP_PASS(&quot;canon-freeze&quot;, CanonicalizeFreezeInLoopsPass())
-+LOOP_PASS(&quot;dot-ddg&quot;, DDGDotPrinterPass())
-+LOOP_PASS(&quot;invalidate&lt;all&gt;&quot;, InvalidateAllAnalysesPass())
-+LOOP_PASS(&quot;loop-idiom&quot;, LoopIdiomRecognizePass())
-+LOOP_PASS(&quot;loop-instsimplify&quot;, LoopInstSimplifyPass())
-+LOOP_PASS(&quot;no-op-loop&quot;, NoOpLoopPass())
-+LOOP_PASS(&quot;print&quot;, PrintLoopPass(dbgs()))
-+LOOP_PASS(&quot;loop-simplifycfg&quot;, LoopSimplifyCFGPass())
-+LOOP_PASS(&quot;indvars&quot;, IndVarSimplifyPass())
-+LOOP_PASS(&quot;loop-unroll-full&quot;, LoopFullUnrollPass())
-+LOOP_PASS(&quot;print-access-info&quot;, LoopAccessInfoPrinterPass(dbgs()))
-+LOOP_PASS(&quot;print&lt;ddg&gt;&quot;, DDGAnalysisPrinterPass(dbgs()))
-+LOOP_PASS(&quot;print&lt;iv-users&gt;&quot;, IVUsersPrinterPass(dbgs()))
-+LOOP_PASS(&quot;print&lt;loopnest&gt;&quot;, LoopNestPrinterPass(dbgs()))
-+LOOP_PASS(&quot;print&lt;loop-cache-cost&gt;&quot;, LoopCachePrinterPass(dbgs()))
-+LOOP_PASS(&quot;loop-predication&quot;, LoopPredicationPass())
-+LOOP_PASS(&quot;guard-widening&quot;, GuardWideningPass())
-+LOOP_PASS(&quot;loop-bound-split&quot;, LoopBoundSplitPass())
-+LOOP_PASS(&quot;loop-reroll&quot;, LoopRerollPass())
-+LOOP_PASS(&quot;loop-versioning-licm&quot;, 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 = (&quot;Building with LLVM 16; note that LLVM 16 support is &quot;
--                   &quot;presently experimental&quot;)
--            show_warning(msg)
--        elif version != 15:
--
--            msg = (&quot;Building llvmlite requires LLVM 15, got &quot;
-+        if version not in (17, 18, 19):
-+            msg = (&quot;Building llvmlite requires LLVM {0}, got &quot;
-                    &quot;{!r}. Be sure to set LLVM_CONFIG to the right executable &quot;
-                    &quot;path.\nRead the documentation at &quot;
-                    &quot;http://llvmlite.pydata.org/ for more information about &quot;
--                   &quot;building llvmlite.\n&quot;.format(out.strip()))
-+                   &quot;building llvmlite.\n&quot;.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&lt;char *&gt;(msg)); }
- API_EXPORT(LLVMContextRef)
- LLVMPY_GetGlobalContext() {
-     auto context = LLVMGetGlobalContext();
--    // FIXME: Remove with LLVM &gt;= 17.
--    LLVMContextSetOpaquePointers(context, true);
-     return context;
- }
- 
- API_EXPORT(LLVMContextRef)
- LLVMPY_ContextCreate() {
-     LLVMContextRef context = LLVMContextCreate();
--    // FIXME: Remove with LLVM &gt;= 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 &quot;llvm/Analysis/PostDominators.h&quot;
- #include &quot;llvm/Support/raw_ostream.h&quot;
- 
--#include &quot;llvm/IR/LegacyPassManager.h&quot;
--
- #include &quot;llvm/InitializePasses.h&quot;
- #include &quot;llvm/LinkAllPasses.h&quot;
- 
-@@ -25,11 +23,6 @@
- 
- using namespace llvm;
- 
--namespace llvm {
--void initializeRefNormalizeLegacyPassPass(PassRegistry &amp;Registry);
--void initializeRefPruneLegacyPassPass(PassRegistry &amp;Registry);
--} // namespace llvm
--
- namespace llvm {
- struct OpaqueModulePassManager;
- typedef OpaqueModulePassManager *LLVMModulePassManagerRef;
-@@ -960,7 +953,7 @@ struct RefPrune {
-                 auto name = dyn_cast&lt;StoreInst&gt;(&amp;instruction)
-                                 -&gt;getPointerOperand()
-                                 -&gt;getName();
--                if (name.equals(&quot;excinfo&quot;) &amp;&amp;
-+                if (name.compare(&quot;excinfo&quot;) == 0 &amp;&amp;
-                     instruction.hasMetadata(&quot;numba_exception_output&quot;)) {
-                     return true;
-                 }
-@@ -1192,84 +1185,21 @@ class RefNormalizePass : public PassInfoMixin&lt;RefNormalizePass&gt; {
-     RefNormalizePass() = default;
- 
-     PreservedAnalyses run(Function &amp;F, FunctionAnalysisManager &amp;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 &amp;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 &amp;F) override {
--        auto &amp;DT = getAnalysis&lt;DominatorTreeWrapperPass&gt;().getDomTree();
--
--        auto &amp;PDT =
--            getAnalysis&lt;PostDominatorTreeWrapperPass&gt;().getPostDomTree();
--
--        return RefPrune(DT, PDT, flags, subgraph_limit).runOnFunction(F);
--    };
--
--    /**
--     * getAnalysisUsage() LLVM plumbing for the pass
--     */
--    void getAnalysisUsage(AnalysisUsage &amp;Info) const override {
--        Info.addRequired&lt;DominatorTreeWrapperPass&gt;();
--        Info.addRequired&lt;PostDominatorTreeWrapperPass&gt;();
--    }
--};
--
--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, &quot;nrtRefNormalize&quot;,
--                &quot;Normalize NRT refops&quot;, false, false)
--
--INITIALIZE_PASS_BEGIN(RefPruneLegacyPass, &quot;nrtRefPruneLegacyPass&quot;,
--                      &quot;Prune NRT refops&quot;, false, false)
--INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
--INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
--
--INITIALIZE_PASS_END(RefPruneLegacyPass, &quot;RefPruneLegacyPass&quot;,
--                    &quot;Prune NRT refops&quot;, false, false)
--
- extern &quot;C&quot; {
- 
--API_EXPORT(void)
--LLVMPY_AddLegacyRefPrunePass(LLVMPassManagerRef PM, int subpasses,
--                             size_t subgraph_limit) {
--    unwrap(PM)-&gt;add(new RefNormalizeLegacyPass());
--    unwrap(PM)-&gt;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() &lt;&lt; &quot;refprune stats &quot;
--               &lt;&lt; &quot;per-BB &quot; &lt;&lt; RefPrune::stats_per_bb &lt;&lt; &quot; &quot;
--               &lt;&lt; &quot;diamond &quot; &lt;&lt; RefPrune::stats_diamond &lt;&lt; &quot; &quot;
--               &lt;&lt; &quot;fanout &quot; &lt;&lt; RefPrune::stats_fanout &lt;&lt; &quot; &quot;
--               &lt;&lt; &quot;fanout+raise &quot; &lt;&lt; RefPrune::stats_fanout_raise &lt;&lt; &quot; &quot;
--               &lt;&lt; &quot;\n&quot;;
-+        errs() &lt;&lt; &quot;refprune stats &quot; &lt;&lt; &quot;per-BB &quot; &lt;&lt; RefPrune::stats_per_bb
-+               &lt;&lt; &quot; &quot; &lt;&lt; &quot;diamond &quot; &lt;&lt; RefPrune::stats_diamond &lt;&lt; &quot; &quot;
-+               &lt;&lt; &quot;fanout &quot; &lt;&lt; RefPrune::stats_fanout &lt;&lt; &quot; &quot; &lt;&lt; &quot;fanout+raise &quot;
-+               &lt;&lt; RefPrune::stats_fanout_raise &lt;&lt; &quot; &quot; &lt;&lt; &quot;\n&quot;;
-     };
- 
-     buf-&gt;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 &quot;llvm-c/Core.h&quot;
--#include &quot;llvm-c/Initialization.h&quot;
- #include &quot;llvm-c/Target.h&quot;
- 
- #include &quot;core.h&quot;
-@@ -7,27 +6,8 @@
- 
- extern &quot;C&quot; {
- 
--#define INIT(F)                                                                \
--    API_EXPORT(void) LLVMPY_Initialize##F() {                                  \
--        LLVMInitialize##F(LLVMGetGlobalPassRegistry());                        \
--    }
--
--INIT(Core)
--INIT(TransformUtils)
--INIT(ScalarOpts)
--#if LLVM_VERSION_MAJOR &lt; 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 &lt; 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(&quot;default&quot;))) ErrorInfoBase;
- #include &lt;string&gt;
- #include &lt;system_error&gt;
- 
--#if LLVM_VERSION_MAJOR &lt; 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 &quot;core.h&quot;
- #include &quot;llvm-c/TargetMachine.h&quot;
- #include &quot;llvm/Analysis/AliasAnalysisEvaluator.h&quot;
-+#include &quot;llvm/Analysis/AliasSetTracker.h&quot;
-+#include &quot;llvm/Analysis/AssumptionCache.h&quot;
-+#include &quot;llvm/Analysis/BasicAliasAnalysis.h&quot;
-+#include &quot;llvm/Analysis/BlockFrequencyInfo.h&quot;
-+#include &quot;llvm/Analysis/BranchProbabilityInfo.h&quot;
-+#include &quot;llvm/Analysis/CFGPrinter.h&quot;
-+#include &quot;llvm/Analysis/CGSCCPassManager.h&quot;
-+#include &quot;llvm/Analysis/CallGraph.h&quot;
-+#include &quot;llvm/Analysis/CallPrinter.h&quot;
-+#include &quot;llvm/Analysis/CostModel.h&quot;
-+#include &quot;llvm/Analysis/CycleAnalysis.h&quot;
-+#include &quot;llvm/Analysis/DDG.h&quot;
-+#include &quot;llvm/Analysis/DDGPrinter.h&quot;
-+#include &quot;llvm/Analysis/Delinearization.h&quot;
-+#include &quot;llvm/Analysis/DemandedBits.h&quot;
-+#include &quot;llvm/Analysis/DependenceAnalysis.h&quot;
-+#include &quot;llvm/Analysis/DomPrinter.h&quot;
-+#include &quot;llvm/Analysis/DominanceFrontier.h&quot;
-+#include &quot;llvm/Analysis/FunctionPropertiesAnalysis.h&quot;
-+#include &quot;llvm/Analysis/GlobalsModRef.h&quot;
-+#include &quot;llvm/Analysis/IRSimilarityIdentifier.h&quot;
-+#include &quot;llvm/Analysis/IVUsers.h&quot;
-+#include &quot;llvm/Analysis/InlineAdvisor.h&quot;
-+#include &quot;llvm/Analysis/InlineSizeEstimatorAnalysis.h&quot;
-+#include &quot;llvm/Analysis/InstCount.h&quot;
-+#include &quot;llvm/Analysis/LazyCallGraph.h&quot;
-+#include &quot;llvm/Analysis/LazyValueInfo.h&quot;
-+#include &quot;llvm/Analysis/Lint.h&quot;
-+#include &quot;llvm/Analysis/LoopAccessAnalysis.h&quot;
-+#include &quot;llvm/Analysis/LoopCacheAnalysis.h&quot;
-+#include &quot;llvm/Analysis/LoopInfo.h&quot;
-+#include &quot;llvm/Analysis/LoopNestAnalysis.h&quot;
-+#include &quot;llvm/Analysis/MemDerefPrinter.h&quot;
-+#include &quot;llvm/Analysis/MemoryDependenceAnalysis.h&quot;
-+#include &quot;llvm/Analysis/MemorySSA.h&quot;
-+#include &quot;llvm/Analysis/ModuleDebugInfoPrinter.h&quot;
-+#include &quot;llvm/Analysis/ModuleSummaryAnalysis.h&quot;
-+#include &quot;llvm/Analysis/MustExecute.h&quot;
-+#include &quot;llvm/Analysis/ObjCARCAliasAnalysis.h&quot;
-+#include &quot;llvm/Analysis/OptimizationRemarkEmitter.h&quot;
-+#include &quot;llvm/Analysis/PhiValues.h&quot;
-+#include &quot;llvm/Analysis/PostDominators.h&quot;
-+#include &quot;llvm/Analysis/ProfileSummaryInfo.h&quot;
-+#include &quot;llvm/Analysis/RegionInfo.h&quot;
-+#include &quot;llvm/Analysis/ScalarEvolution.h&quot;
-+#include &quot;llvm/Analysis/ScalarEvolutionAliasAnalysis.h&quot;
-+#include &quot;llvm/Analysis/ScopedNoAliasAA.h&quot;
-+#include &quot;llvm/Analysis/StackLifetime.h&quot;
-+#include &quot;llvm/Analysis/StackSafetyAnalysis.h&quot;
-+#include &quot;llvm/Analysis/TargetLibraryInfo.h&quot;
-+#include &quot;llvm/Analysis/TargetTransformInfo.h&quot;
-+#include &quot;llvm/Analysis/TypeBasedAliasAnalysis.h&quot;
-+#include &quot;llvm/IR/Dominators.h&quot;
-+#include &quot;llvm/IR/IRPrintingPasses.h&quot;
- #include &quot;llvm/IR/PassManager.h&quot;
-+#include &lt;llvm/IR/PassTimingInfo.h&gt;
- #include &quot;llvm/IR/Verifier.h&quot;
- #include &quot;llvm/Passes/PassBuilder.h&quot;
- #include &quot;llvm/Passes/StandardInstrumentations.h&quot;
-+#include &quot;llvm/Support/raw_ostream.h&quot;
-+#include &quot;llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h&quot;
-+#include &quot;llvm/Transforms/Coroutines/CoroCleanup.h&quot;
-+#include &quot;llvm/Transforms/Coroutines/CoroEarly.h&quot;
-+#include &quot;llvm/Transforms/Coroutines/CoroElide.h&quot;
-+#include &quot;llvm/Transforms/Coroutines/CoroSplit.h&quot;
-+#include &quot;llvm/Transforms/IPO/AlwaysInliner.h&quot;
-+#include &quot;llvm/Transforms/IPO/Annotation2Metadata.h&quot;
-+#include &quot;llvm/Transforms/IPO/ArgumentPromotion.h&quot;
-+#include &quot;llvm/Transforms/IPO/Attributor.h&quot;
-+#include &quot;llvm/Transforms/IPO/BlockExtractor.h&quot;
-+#include &quot;llvm/Transforms/IPO/CalledValuePropagation.h&quot;
-+#include &quot;llvm/Transforms/IPO/ConstantMerge.h&quot;
-+#include &quot;llvm/Transforms/IPO/CrossDSOCFI.h&quot;
-+#include &quot;llvm/Transforms/IPO/DeadArgumentElimination.h&quot;
-+#include &quot;llvm/Transforms/IPO/ElimAvailExtern.h&quot;
-+#include &quot;llvm/Transforms/IPO/ForceFunctionAttrs.h&quot;
-+#include &quot;llvm/Transforms/IPO/FunctionAttrs.h&quot;
-+#include &quot;llvm/Transforms/IPO/FunctionImport.h&quot;
-+#include &quot;llvm/Transforms/IPO/GlobalDCE.h&quot;
-+#include &quot;llvm/Transforms/IPO/GlobalOpt.h&quot;
-+#include &quot;llvm/Transforms/IPO/GlobalSplit.h&quot;
-+#include &quot;llvm/Transforms/IPO/HotColdSplitting.h&quot;
-+#include &quot;llvm/Transforms/IPO/IROutliner.h&quot;
-+#include &quot;llvm/Transforms/IPO/InferFunctionAttrs.h&quot;
-+#include &quot;llvm/Transforms/IPO/Inliner.h&quot;
-+#include &quot;llvm/Transforms/IPO/Internalize.h&quot;
-+#include &quot;llvm/Transforms/IPO/LoopExtractor.h&quot;
-+#include &quot;llvm/Transforms/IPO/LowerTypeTests.h&quot;
-+#include &quot;llvm/Transforms/IPO/MergeFunctions.h&quot;
-+#include &quot;llvm/Transforms/IPO/ModuleInliner.h&quot;
-+#include &quot;llvm/Transforms/IPO/OpenMPOpt.h&quot;
-+#include &quot;llvm/Transforms/IPO/PartialInlining.h&quot;
-+#include &quot;llvm/Transforms/IPO/SCCP.h&quot;
-+#include &quot;llvm/Transforms/IPO/SampleProfile.h&quot;
-+#include &quot;llvm/Transforms/IPO/SampleProfileProbe.h&quot;
-+#include &quot;llvm/Transforms/IPO/StripDeadPrototypes.h&quot;
-+#include &quot;llvm/Transforms/IPO/StripSymbols.h&quot;
-+#include &quot;llvm/Transforms/IPO/WholeProgramDevirt.h&quot;
- #include &quot;llvm/Transforms/InstCombine/InstCombine.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/AddressSanitizer.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/BoundsChecking.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/CGProfile.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/ControlHeightReduction.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/DataFlowSanitizer.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/GCOVProfiler.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/HWAddressSanitizer.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/InstrOrderFile.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/InstrProfiling.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/MemProfiler.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/MemorySanitizer.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/PGOInstrumentation.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/PoisonChecking.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/SanitizerCoverage.h&quot;
-+#include &quot;llvm/Transforms/Instrumentation/ThreadSanitizer.h&quot;
-+#include &quot;llvm/Transforms/ObjCARC.h&quot;
-+#include &quot;llvm/Transforms/Scalar/ADCE.h&quot;
-+#include &quot;llvm/Transforms/Scalar/AlignmentFromAssumptions.h&quot;
-+#include &quot;llvm/Transforms/Scalar/AnnotationRemarks.h&quot;
-+#include &quot;llvm/Transforms/Scalar/BDCE.h&quot;
-+#include &quot;llvm/Transforms/Scalar/CallSiteSplitting.h&quot;
-+#include &quot;llvm/Transforms/Scalar/ConstantHoisting.h&quot;
-+#include &quot;llvm/Transforms/Scalar/ConstraintElimination.h&quot;
-+#include &quot;llvm/Transforms/Scalar/CorrelatedValuePropagation.h&quot;
-+#include &quot;llvm/Transforms/Scalar/DCE.h&quot;
-+#include &quot;llvm/Transforms/Scalar/DFAJumpThreading.h&quot;
-+#include &quot;llvm/Transforms/Scalar/DeadStoreElimination.h&quot;
-+#include &quot;llvm/Transforms/Scalar/DivRemPairs.h&quot;
-+#include &quot;llvm/Transforms/Scalar/EarlyCSE.h&quot;
-+#include &quot;llvm/Transforms/Scalar/FlattenCFG.h&quot;
-+#include &quot;llvm/Transforms/Scalar/Float2Int.h&quot;
-+#include &quot;llvm/Transforms/Scalar/GVN.h&quot;
-+#include &quot;llvm/Transforms/Scalar/GuardWidening.h&quot;
-+#include &quot;llvm/Transforms/Scalar/IVUsersPrinter.h&quot;
-+#include &quot;llvm/Transforms/Scalar/IndVarSimplify.h&quot;
-+#include &quot;llvm/Transforms/Scalar/InductiveRangeCheckElimination.h&quot;
-+#include &quot;llvm/Transforms/Scalar/InferAddressSpaces.h&quot;
-+#include &quot;llvm/Transforms/Scalar/InstSimplifyPass.h&quot;
- #include &quot;llvm/Transforms/Scalar/JumpThreading.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LICM.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopBoundSplit.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopDataPrefetch.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopDeletion.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopDistribute.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopFlatten.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopFuse.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopIdiomRecognize.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopInstSimplify.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopInterchange.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopLoadElimination.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopPassManager.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopPredication.h&quot;
- #include &quot;llvm/Transforms/Scalar/LoopRotation.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopSimplifyCFG.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopSink.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopStrengthReduce.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopUnrollAndJamPass.h&quot;
- #include &quot;llvm/Transforms/Scalar/LoopUnrollPass.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LoopVersioningLICM.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LowerAtomicPass.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LowerConstantIntrinsics.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LowerExpectIntrinsic.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LowerGuardIntrinsic.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LowerMatrixIntrinsics.h&quot;
-+#include &quot;llvm/Transforms/Scalar/LowerWidenableCondition.h&quot;
-+#include &quot;llvm/Transforms/Scalar/MakeGuardsExplicit.h&quot;
-+#include &quot;llvm/Transforms/Scalar/MemCpyOptimizer.h&quot;
-+#include &quot;llvm/Transforms/Scalar/MergeICmps.h&quot;
-+#include &quot;llvm/Transforms/Scalar/MergedLoadStoreMotion.h&quot;
-+#include &quot;llvm/Transforms/Scalar/NaryReassociate.h&quot;
-+#include &quot;llvm/Transforms/Scalar/NewGVN.h&quot;
-+#include &quot;llvm/Transforms/Scalar/PartiallyInlineLibCalls.h&quot;
-+#include &quot;llvm/Transforms/Scalar/Reassociate.h&quot;
-+#include &quot;llvm/Transforms/Scalar/Reg2Mem.h&quot;
-+#include &quot;llvm/Transforms/Scalar/RewriteStatepointsForGC.h&quot;
-+#include &quot;llvm/Transforms/Scalar/SCCP.h&quot;
-+#include &quot;llvm/Transforms/Scalar/SROA.h&quot;
-+#include &quot;llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h&quot;
-+#include &quot;llvm/Transforms/Scalar/Scalarizer.h&quot;
-+#include &quot;llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h&quot;
-+#include &quot;llvm/Transforms/Scalar/SimpleLoopUnswitch.h&quot;
- #include &quot;llvm/Transforms/Scalar/SimplifyCFG.h&quot;
-+#include &quot;llvm/Transforms/Scalar/Sink.h&quot;
-+#include &quot;llvm/Transforms/Scalar/SpeculativeExecution.h&quot;
-+#include &quot;llvm/Transforms/Scalar/StraightLineStrengthReduce.h&quot;
-+#include &quot;llvm/Transforms/Scalar/StructurizeCFG.h&quot;
-+#include &quot;llvm/Transforms/Scalar/TLSVariableHoist.h&quot;
-+#include &quot;llvm/Transforms/Scalar/TailRecursionElimination.h&quot;
-+#include &quot;llvm/Transforms/Scalar/WarnMissedTransforms.h&quot;
-+#include &quot;llvm/Transforms/Utils/AddDiscriminators.h&quot;
-+#include &quot;llvm/Transforms/Utils/AssumeBundleBuilder.h&quot;
-+#include &quot;llvm/Transforms/Utils/BreakCriticalEdges.h&quot;
-+#include &quot;llvm/Transforms/Utils/CanonicalizeAliases.h&quot;
-+#include &quot;llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h&quot;
-+#include &quot;llvm/Transforms/Utils/Debugify.h&quot;
-+#include &quot;llvm/Transforms/Utils/EntryExitInstrumenter.h&quot;
-+#include &quot;llvm/Transforms/Utils/FixIrreducible.h&quot;
-+#include &quot;llvm/Transforms/Utils/HelloWorld.h&quot;
-+#include &quot;llvm/Transforms/Utils/InjectTLIMappings.h&quot;
-+#include &quot;llvm/Transforms/Utils/InstructionNamer.h&quot;
-+#include &quot;llvm/Transforms/Utils/LCSSA.h&quot;
-+#include &quot;llvm/Transforms/Utils/LibCallsShrinkWrap.h&quot;
-+#include &quot;llvm/Transforms/Utils/LoopSimplify.h&quot;
-+#include &quot;llvm/Transforms/Utils/LoopVersioning.h&quot;
-+#include &quot;llvm/Transforms/Utils/LowerGlobalDtors.h&quot;
-+#include &quot;llvm/Transforms/Utils/LowerInvoke.h&quot;
-+#include &quot;llvm/Transforms/Utils/LowerSwitch.h&quot;
-+#include &quot;llvm/Transforms/Utils/Mem2Reg.h&quot;
-+#include &quot;llvm/Transforms/Utils/MetaRenamer.h&quot;
-+#include &quot;llvm/Transforms/Utils/NameAnonGlobals.h&quot;
-+#include &quot;llvm/Transforms/Utils/PredicateInfo.h&quot;
-+#include &quot;llvm/Transforms/Utils/RelLookupTableConverter.h&quot;
-+#include &quot;llvm/Transforms/Utils/StripGCRelocates.h&quot;
-+#include &quot;llvm/Transforms/Utils/StripNonLineTableDebugInfo.h&quot;
-+#include &quot;llvm/Transforms/Utils/SymbolRewriter.h&quot;
-+#include &quot;llvm/Transforms/Utils/UnifyFunctionExitNodes.h&quot;
-+#include &quot;llvm/Transforms/Utils/UnifyLoopExits.h&quot;
-+#include &quot;llvm/Transforms/Vectorize/LoadStoreVectorizer.h&quot;
-+#include &quot;llvm/Transforms/Vectorize/LoopVectorize.h&quot;
-+#include &quot;llvm/Transforms/Vectorize/SLPVectorizer.h&quot;
-+#include &quot;llvm/Transforms/Vectorize/VectorCombine.h&quot;
- 
- 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 &lt; 16
--    StandardInstrumentations SI(DebugLogging, VerifyEach, PrintPassOpts);
--#else
-     StandardInstrumentations SI(M-&gt;getContext(), DebugLogging, VerifyEach,
-                                 PrintPassOpts);
--#endif
--    SI.registerCallbacks(*PB-&gt;getPassInstrumentationCallbacks(), &amp;FAM);
-+    // https://reviews.llvm.org/D146160
-+    SI.registerCallbacks(*PB-&gt;getPassInstrumentationCallbacks(), &amp;MAM);
- 
-     PB-&gt;registerLoopAnalyses(LAM);
-     PB-&gt;registerFunctionAnalyses(FAM);
-@@ -91,41 +303,6 @@ LLVMPY_RunNewModulePassManager(LLVMModulePassManagerRef MPMRef,
-     MPM-&gt;run(*M, MAM);
- }
- 
--API_EXPORT(void)
--LLVMPY_AddVerifierPass(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)-&gt;addPass(VerifierPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddAAEvalPass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)-&gt;addPass(
--        createModuleToFunctionPassAdaptor(AAEvaluator()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddSimplifyCFGPass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)-&gt;addPass(
--        createModuleToFunctionPassAdaptor(SimplifyCFGPass()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopUnrollPass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)-&gt;addPass(
--        createModuleToFunctionPassAdaptor(LoopUnrollPass()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopRotatePass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)-&gt;addPass(createModuleToFunctionPassAdaptor(
--        createFunctionToLoopPassAdaptor(LoopRotatePass())));
--}
--
--API_EXPORT(void)
--LLVMPY_AddInstructionCombinePass_module(LLVMModulePassManagerRef MPM) {
--    llvm::unwrap(MPM)-&gt;addPass(
--        createModuleToFunctionPassAdaptor(InstCombinePass()));
--}
--
- API_EXPORT(void)
- LLVMPY_AddJumpThreadingPass_module(LLVMModulePassManagerRef MPM, int T) {
-     llvm::unwrap(MPM)-&gt;addPass(
-@@ -168,13 +345,10 @@ LLVMPY_RunNewFunctionPassManager(LLVMFunctionPassManagerRef FPMRef,
-     // TODO: Can expose this in ffi layer
-     PrintPassOptions PrintPassOpts;
- 
--#if LLVM_VERSION_MAJOR &lt; 16
--    StandardInstrumentations SI(DebugLogging, VerifyEach, PrintPassOpts);
--#else
-     StandardInstrumentations SI(F-&gt;getContext(), DebugLogging, VerifyEach,
-                                 PrintPassOpts);
--#endif
--    SI.registerCallbacks(*PB-&gt;getPassInstrumentationCallbacks(), &amp;FAM);
-+    // https://reviews.llvm.org/D146160
-+    SI.registerCallbacks(*PB-&gt;getPassInstrumentationCallbacks(), &amp;MAM);
- 
-     PB-&gt;registerLoopAnalyses(LAM);
-     PB-&gt;registerFunctionAnalyses(FAM);
-@@ -184,32 +358,6 @@ LLVMPY_RunNewFunctionPassManager(LLVMFunctionPassManagerRef FPMRef,
-     FPM-&gt;run(*F, FAM);
- }
- 
--API_EXPORT(void)
--LLVMPY_AddAAEvalPass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)-&gt;addPass(AAEvaluator());
--}
--
--API_EXPORT(void)
--LLVMPY_AddSimplifyCFGPass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)-&gt;addPass(SimplifyCFGPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopUnrollPass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)-&gt;addPass(LoopUnrollPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopRotatePass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)-&gt;addPass(
--        createFunctionToLoopPassAdaptor(LoopRotatePass()));
--}
--
--API_EXPORT(void)
--LLVMPY_AddInstructionCombinePass_function(LLVMFunctionPassManagerRef FPM) {
--    llvm::unwrap(FPM)-&gt;addPass(InstCombinePass());
--}
--
- API_EXPORT(void)
- LLVMPY_AddJumpThreadingPass_function(LLVMFunctionPassManagerRef FPM, int T) {
-     llvm::unwrap(FPM)-&gt;addPass(JumpThreadingPass(T));
-@@ -267,16 +415,15 @@ LLVMPY_PTOSetLoopUnrolling(LLVMPipelineTuningOptionsRef PTO, bool value) {
-     llvm::unwrap(PTO)-&gt;LoopUnrolling = value;
- }
- 
--// FIXME: Available from llvm16
--// API_EXPORT(int)
--// LLVMPY_PTOGetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO) {
--//     return llvm::unwrap(PTO)-&gt;InlinerThreshold;
--// }
-+API_EXPORT(int)
-+LLVMPY_PTOGetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO) {
-+    return llvm::unwrap(PTO)-&gt;InlinerThreshold;
-+}
- 
--// API_EXPORT(void)
--// LLVMPY_PTOSetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO, bool value) {
--//     llvm::unwrap(PTO)-&gt;InlinerThreshold = value;
--// }
-+API_EXPORT(void)
-+LLVMPY_PTOSetInlinerThreshold(LLVMPipelineTuningOptionsRef PTO, bool value) {
-+    llvm::unwrap(PTO)-&gt;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 &lt; 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)-&gt;addPass(ModuleDebugInfoPrinterPass(llvm::outs()));
-+}
-+
-+#define CGSCC_PASS(NAME)                                                       \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)-&gt;addPass(                                            \
-+            createModuleToPostOrderCGSCCPassAdaptor(NAME()));                  \
-+    }
-+#include &quot;PASSREGISTRY.def&quot;
-+
-+#define MODULE_PASS(NAME)                                                      \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)-&gt;addPass(NAME());                                    \
-+    }
-+#include &quot;PASSREGISTRY.def&quot;
-+
-+#define FUNCTION_PASS(NAME)                                                    \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)-&gt;addPass(createModuleToFunctionPassAdaptor(NAME())); \
-+    }                                                                          \
-+    void LLVMPY_function_Add##NAME(LLVMFunctionPassManagerRef FPM) {           \
-+        llvm::unwrap(FPM)-&gt;addPass(NAME());                                    \
-+    }
-+#include &quot;PASSREGISTRY.def&quot;
-+
-+#define LOOP_PASS(NAME)                                                        \
-+    void LLVMPY_module_Add##NAME(LLVMModulePassManagerRef MPM) {               \
-+        llvm::unwrap(MPM)-&gt;addPass(createModuleToFunctionPassAdaptor(          \
-+            createFunctionToLoopPassAdaptor(NAME())));                         \
-+    }                                                                          \
-+    void LLVMPY_function_Add##NAME(LLVMFunctionPassManagerRef FPM) {           \
-+        llvm::unwrap(FPM)-&gt;addPass(createFunctionToLoopPassAdaptor(NAME()));   \
-+    }
-+#include &quot;PASSREGISTRY.def&quot;
-+
-+const char *LLVMPY_getModuleLevelPasses() {
-+    std::string module_passes;
-+
-+#define MODULE_PASS(NAME) module_passes = module_passes + &quot; &quot; + TOSTRING(NAME);
-+#define FUNCTION_PASS(NAME)                                                    \
-+    module_passes = module_passes + &quot; &quot; + TOSTRING(NAME);
-+#define LOOP_PASS(NAME) module_passes = module_passes + &quot; &quot; + TOSTRING(NAME);
-+#include &quot;PASSREGISTRY.def&quot;
-+
-+    return LLVMPY_CreateString(module_passes.c_str());
-+}
-+
-+const char *LLVMPY_getFunctionLevelPasses() {
-+    std::string function_passes;
-+
-+#define FUNCTION_PASS(NAME)                                                    \
-+    function_passes = function_passes + &quot; &quot; + TOSTRING(NAME);
-+#define LOOP_PASS(NAME)                                                        \
-+    function_passes = function_passes + &quot; &quot; + TOSTRING(NAME);
-+#include &quot;PASSREGISTRY.def&quot;
-+
-+    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(&amp;os);
-+    os.flush();
-+    *outmsg = LLVMPY_CreateString(os.str().c_str());
-+}
-+
- } // end extern &quot;C&quot;
-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 &quot;llvm/AsmParser/Parser.h&quot;
- #include &quot;llvm/ExecutionEngine/Orc/Core.h&quot;
--#include &quot;llvm/ExecutionEngine/Orc/DebuggerSupportPlugin.h&quot;
-+#include &quot;llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h&quot;
- #include &quot;llvm/ExecutionEngine/Orc/ExecutionUtils.h&quot;
- #include &quot;llvm/ExecutionEngine/Orc/LLJIT.h&quot;
- #include &quot;llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h&quot;
-@@ -92,7 +92,7 @@ LLVMPY_CreateLLJITCompiler(LLVMTargetMachineRef tm, bool suppressErrors,
-             auto linkingLayer =
-                 std::make_unique&lt;llvm::orc::ObjectLinkingLayer&gt;(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&lt;LLJIT&gt; *lljit, const char *libraryName,
-     for (size_t import_idx = 0; import_idx &lt; imports_length; import_idx++) {
-         SymbolStringPtr mangled =
-             (*lljit)-&gt;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-&gt;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 &lt;sstream&gt;
--
--#include &quot;core.h&quot;
--
--#include &quot;llvm-c/Transforms/IPO.h&quot;
--#include &quot;llvm-c/Transforms/Scalar.h&quot;
--#include &quot;llvm/ADT/STLExtras.h&quot;
--#include &quot;llvm/IR/DiagnosticInfo.h&quot;
--#include &quot;llvm/IR/DiagnosticPrinter.h&quot;
--#include &quot;llvm/IR/LegacyPassManager.h&quot;
--#include &quot;llvm/IR/Module.h&quot;
--#include &quot;llvm/Support/FileSystem.h&quot;
--#include &quot;llvm/Support/ToolOutputFile.h&quot;
--#include &quot;llvm/Support/YAMLTraits.h&quot;
--#include &quot;llvm/Support/raw_ostream.h&quot;
--
--#include &quot;llvm-c/Transforms/IPO.h&quot;
--#include &quot;llvm-c/Transforms/Scalar.h&quot;
--#include &quot;llvm/IR/LLVMRemarkStreamer.h&quot;
--#include &quot;llvm/IR/LegacyPassManager.h&quot;
--#include &quot;llvm/Remarks/RemarkStreamer.h&quot;
--#include &quot;llvm/Transforms/IPO.h&quot;
--#include &quot;llvm/Transforms/Scalar.h&quot;
--
--#include &lt;llvm/IR/PassTimingInfo.h&gt;
--
--#include &lt;llvm/Analysis/AliasAnalysisEvaluator.h&gt;
--#include &lt;llvm/Analysis/BasicAliasAnalysis.h&gt;
--#include &lt;llvm/Analysis/CFGPrinter.h&gt;
--#include &lt;llvm/Analysis/CallPrinter.h&gt;
--#include &lt;llvm/Analysis/DependenceAnalysis.h&gt;
--#include &lt;llvm/Analysis/DomPrinter.h&gt;
--#include &lt;llvm/Analysis/GlobalsModRef.h&gt;
--#include &lt;llvm/Analysis/IVUsers.h&gt;
--#include &lt;llvm/Analysis/Lint.h&gt;
--#include &lt;llvm/Analysis/Passes.h&gt;
--#include &lt;llvm/Analysis/ScalarEvolutionAliasAnalysis.h&gt;
--#include &lt;llvm/CodeGen/Passes.h&gt;
--#include &lt;llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h&gt;
--#include &lt;llvm/Transforms/IPO.h&gt;
--#include &lt;llvm/Transforms/IPO/AlwaysInliner.h&gt;
--#include &lt;llvm/Transforms/Scalar/SimpleLoopUnswitch.h&gt;
--#include &lt;llvm/Transforms/Utils.h&gt;
--#include &lt;llvm/Transforms/Utils/UnifyFunctionExitNodes.h&gt;
--using namespace llvm;
--
--/*
-- * Exposed API
-- */
--
--extern &quot;C&quot; {
--
--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(&amp;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)-&gt;getContext(), record_filename, remarks_filter,
--        remarks_format, true);
--    if (!setupResult) {
--        return -1;
--    }
--    auto optimisationFile = std::move(*setupResult);
--    auto r = LLVMRunPassManager(PM, M);
--
--    unwrap(M)-&gt;getContext().setMainRemarkStreamer(nullptr);
--    unwrap(M)-&gt;getContext().setLLVMRemarkStreamer(nullptr);
--
--    optimisationFile-&gt;keep();
--    optimisationFile-&gt;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)-&gt;getContext(), record_filename, remarks_filter,
--        remarks_format, true);
--    if (!setupResult) {
--        return -1;
--    }
--    auto optimisationFile = std::move(*setupResult);
--
--    auto r = LLVMRunFunctionPassManager(PM, F);
--
--    unwrap(F)-&gt;getContext().setMainRemarkStreamer(nullptr);
--    unwrap(F)-&gt;getContext().setLLVMRemarkStreamer(nullptr);
--
--    optimisationFile-&gt;keep();
--    optimisationFile-&gt;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)-&gt;add(llvm::createAAEvalPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddBasicAAWrapperPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createBasicAAWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDependenceAnalysisPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createDependenceAnalysisWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddCallGraphDOTPrinterPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createCallGraphDOTPrinterPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDotDomPrinterPass(LLVMPassManagerRef PM, bool showBody) {
--    unwrap(PM)-&gt;add(showBody ? llvm::createDomPrinterWrapperPassPass()
--                             : llvm::createDomOnlyPrinterWrapperPassPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddGlobalsModRefAAPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createGlobalsAAWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDotPostDomPrinterPass(LLVMPassManagerRef PM, bool showBody) {
--    unwrap(PM)-&gt;add(showBody ? llvm::createPostDomPrinterWrapperPassPass()
--                             : llvm::createPostDomOnlyPrinterWrapperPassPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddCFGPrinterPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createCFGPrinterLegacyPassPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddConstantMergePass(LLVMPassManagerRef PM) {
--    LLVMAddConstantMergePass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddDeadStoreEliminationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createDeadStoreEliminationPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddReversePostOrderFunctionAttrsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createReversePostOrderFunctionAttrsPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDeadArgEliminationPass(LLVMPassManagerRef PM) {
--    LLVMAddDeadArgEliminationPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddInstructionCountPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createInstCountPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddIVUsersPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createIVUsersPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLazyValueInfoPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createLazyValueInfoPass());
--}
--API_EXPORT(void)
--LLVMPY_AddLintPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createLintLegacyPassPass());
--}
--API_EXPORT(void)
--LLVMPY_AddModuleDebugInfoPrinterPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createModuleDebugInfoPrinterPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddRegionInfoPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createRegionInfoPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddScalarEvolutionAAPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createSCEVAAWrapperPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddAggressiveDCEPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createAggressiveDCEPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddAlwaysInlinerPass(LLVMPassManagerRef PM, bool insertLifetime) {
--    unwrap(PM)-&gt;add(llvm::createAlwaysInlinerLegacyPass(insertLifetime));
--}
--
--API_EXPORT(void)
--LLVMPY_AddBreakCriticalEdgesPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(llvm::createBreakCriticalEdgesPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddFunctionAttrsPass(LLVMPassManagerRef PM) {
--    LLVMAddFunctionAttrsPass(PM);
--}
--
--API_EXPORT(void)
--LLVMPY_AddFunctionInliningPass(LLVMPassManagerRef PM, int Threshold) {
--    unwrap(PM)-&gt;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)-&gt;add(createDeadCodeEliminationPass());
--}
--
--#if LLVM_VERSION_MAJOR &lt; 16
--API_EXPORT(void)
--LLVMPY_AddAggressiveInstructionCombiningPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createAggressiveInstCombinerPass());
--}
--#endif
--
--API_EXPORT(void)
--LLVMPY_AddInternalizePass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createInternalizePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddJumpThreadingPass(LLVMPassManagerRef PM, int threshold) {
--    unwrap(PM)-&gt;add(createJumpThreadingPass(threshold));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLCSSAPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createLCSSAPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopDeletionPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createLoopDeletionPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopExtractorPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createLoopExtractorPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddSingleLoopExtractorPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createSingleLoopExtractorPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopStrengthReducePass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createLoopStrengthReducePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLoopSimplificationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;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)-&gt;add(createSimpleLoopUnswitchLegacyPass(optimizeForSize));
--}
--
--API_EXPORT(void)
--LLVMPY_AddLowerAtomicPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createLowerAtomicPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLowerInvokePass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createLowerInvokePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddLowerSwitchPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createLowerSwitchPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddMemCpyOptimizationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createMemCpyOptPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddMergeFunctionsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createMergeFunctionsPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddMergeReturnsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createUnifyFunctionExitNodesPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddPartialInliningPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createPartialInliningPass());
--}
--
--#if LLVM_VERSION_MAJOR &lt; 16
--API_EXPORT(void)
--LLVMPY_AddPruneExceptionHandlingPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createPruneEHPass());
--}
--#endif
--
--API_EXPORT(void)
--LLVMPY_AddReassociatePass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createReassociatePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddDemoteRegisterToMemoryPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createDemoteRegisterToMemoryPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddSinkPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createSinkingPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripSymbolsPass(LLVMPassManagerRef PM, bool onlyDebugInfo) {
--    unwrap(PM)-&gt;add(createStripSymbolsPass(onlyDebugInfo));
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripDeadDebugInfoPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createStripDeadDebugInfoPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripDeadPrototypesPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createStripDeadPrototypesPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripDebugDeclarePrototypesPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createStripDebugDeclarePass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddStripNondebugSymbolsPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;add(createStripNonDebugSymbolsPass());
--}
--
--API_EXPORT(void)
--LLVMPY_AddTailCallEliminationPass(LLVMPassManagerRef PM) {
--    unwrap(PM)-&gt;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)-&gt;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)-&gt;add(createInstructionNamerPass());
--}
--
--} // end extern &quot;C&quot;
-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 &quot;core.h&quot;
- #include &quot;llvm-c/Target.h&quot;
- #include &quot;llvm-c/TargetMachine.h&quot;
--#include &quot;llvm/ADT/Optional.h&quot;
--#include &quot;llvm/ADT/Triple.h&quot;
-+#include &quot;llvm/TargetParser/Triple.h&quot;
- #include &quot;llvm/Analysis/TargetLibraryInfo.h&quot;
- #include &quot;llvm/IR/LegacyPassManager.h&quot;
- #include &quot;llvm/IR/Type.h&quot;
- #include &quot;llvm/MC/TargetRegistry.h&quot;
--#include &quot;llvm/Support/Host.h&quot;
-+#include &quot;llvm/TargetParser/Host.h&quot;
- #include &quot;llvm/Target/TargetMachine.h&quot;
- 
- #include &lt;cstdio&gt;
-@@ -60,9 +59,10 @@ LLVMPY_GetTripleParts(const char *triple_str, const char **arch_out,
-  */
- API_EXPORT(int)
- LLVMPY_GetHostCPUFeatures(const char **Out) {
--    llvm::StringMap&lt;bool&gt; features;
-+    // https://github.com/llvm/llvm-project/pull/97824
-+    llvm::StringMap&lt;bool&gt; features = llvm::sys::getHostCPUFeatures();
-     std::ostringstream buf;
--    if (llvm::sys::getHostCPUFeatures(features)) {
-+    if (!features.empty()) {
-         for (auto &amp;F : features) {
-             if (buf.tellp()) {
-                 buf &lt;&lt; ',';
-@@ -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&lt;Reloc::Model&gt; rm;
-+    // llvm::Optional removed in llvm17
-+    std::optional&lt;Reloc::Model&gt; rm;
-     std::string rms(RelocModel);
-     if (rms == &quot;static&quot;)
-         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 &quot;core.h&quot;
--#include &quot;llvm-c/Target.h&quot;
--#include &quot;llvm-c/Transforms/PassManagerBuilder.h&quot;
--#include &quot;llvm/Transforms/IPO/PassManagerBuilder.h&quot;
--
--extern &quot;C&quot; {
--
--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-&gt;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-&gt;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-&gt;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-&gt;LoopVectorize = Value;
--}
--
--API_EXPORT(int)
--LLVMPY_PassManagerBuilderGetLoopVectorize(LLVMPassManagerBuilderRef PMB) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    return pmb-&gt;LoopVectorize;
--}
--
--API_EXPORT(void)
--LLVMPY_PassManagerBuilderSetSLPVectorize(LLVMPassManagerBuilderRef PMB,
--                                         int Value) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    pmb-&gt;SLPVectorize = Value;
--}
--
--API_EXPORT(int)
--LLVMPY_PassManagerBuilderGetSLPVectorize(LLVMPassManagerBuilderRef PMB) {
--    llvm::PassManagerBuilder *pmb = llvm::unwrap(PMB);
--    return pmb-&gt;SLPVectorize;
--}
--
--} // end extern &quot;C&quot;
-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 &quot;llvm/Analysis/CFGPrinter.h&quot;
- #include &quot;llvm/Support/GraphWriter.h&quot;
-+#include &quot;llvm/IR/GlobalVariable.h&quot;
- 
- /* 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():
--    &quot;&quot;&quot;
--    Initialize the LLVM core.
--    &quot;&quot;&quot;
--    ffi.lib.LLVMPY_InitializeCore()
--
--
- def initialize_all_targets():
-     &quot;&quot;&quot;
-     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):
-+    &quot;&quot;&quot; Holds statistics from reference count pruning.
-+    &quot;&quot;&quot;
-+
-+    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):
-+    &quot;&quot;&quot; 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.
-+    &quot;&quot;&quot;
-+
-+    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):
-+    &quot;&quot;&quot;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.
-+    &quot;&quot;&quot;
-+    ffi.lib.LLVMPY_SetTimePasses(c_bool(enable))
-+
-+
-+def report_and_reset_timings():
-+    &quot;&quot;&quot;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.
-+    &quot;&quot;&quot;
-+    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) &gt; 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) &gt; 0]
-+    return passes
- 
--    def add_verifier(self):
--        ffi.lib.LLVMPY_AddVerifierPass(self)
-+
-+class NewPassManager():
-+
-+    def __init__(self):
-+        if type(self) is NewPassManager:
-+            raise TypeError(&quot;Cannot instantiate NewPassManager directly&quot;)
-+
-+    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):
--    &quot;&quot;&quot; Holds statistics from reference count pruning.
--    &quot;&quot;&quot;
--
--    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):
--    &quot;&quot;&quot; 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.
--    &quot;&quot;&quot;
--
--    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):
--    &quot;&quot;&quot;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.
--    &quot;&quot;&quot;
--    ffi.lib.LLVMPY_SetTimePasses(c_bool(enable))
--
--
--def report_and_reset_timings():
--    &quot;&quot;&quot;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.
--    &quot;&quot;&quot;
--    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):
--    &quot;&quot;&quot;PassManager
--    &quot;&quot;&quot;
--
--    def _dispose(self):
--        self._capi.LLVMPY_DisposePassManager(self)
--
--    def add_aa_eval_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#aa-eval-exhaustive-alias-analysis-precision-evaluator
--
--        LLVM 14: `llvm::createAAEvalPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddAAEvalPass(self)
--
--    def add_basic_aa_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#basic-aa-basic-alias-analysis-stateless-aa-impl
--
--        LLVM 14: `llvm::createBasicAAWrapperPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddBasicAAWrapperPass(self)
--
--    def add_constant_merge_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#constmerge-merge-duplicate-global-constants
--
--        LLVM 14: `LLVMAddConstantMergePass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddConstantMergePass(self)
--
--    def add_dead_arg_elimination_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#deadargelim-dead-argument-elimination
--
--        LLVM 14: `LLVMAddDeadArgEliminationPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddDeadArgEliminationPass(self)
--
--    def add_dependence_analysis_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#da-dependence-analysis
--
--        LLVM 14: `llvm::createDependenceAnalysisWrapperPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddDependenceAnalysisPass(self)
--
--    def add_dot_call_graph_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#dot-callgraph-print-call-graph-to-dot-file
--
--        LLVM 14: `llvm::createCallGraphDOTPrinterPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddCallGraphDOTPrinterPass(self)
--
--    def add_dot_cfg_printer_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#dot-cfg-print-cfg-of-function-to-dot-file
--
--        LLVM 14: `llvm::createCFGPrinterLegacyPassPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddCFGPrinterPass(self)
--
--    def add_dot_dom_printer_pass(self, show_body=False):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#dot-dom-print-dominance-tree-of-function-to-dot-file
--
--        LLVM 14: `llvm::createDomPrinterPass` and `llvm::createDomOnlyPrinterPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddDotDomPrinterPass(self, show_body)
--
--    def add_dot_postdom_printer_pass(self, show_body=False):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#dot-postdom-print-postdominance-tree-of-function-to-dot-file
--
--        LLVM 14: `llvm::createPostDomPrinterPass` and `llvm::createPostDomOnlyPrinterPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddDotPostDomPrinterPass(self, show_body)
--
--    def add_globals_mod_ref_aa_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#globalsmodref-aa-simple-mod-ref-analysis-for-globals
--
--        LLVM 14: `llvm::createGlobalsAAWrapperPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddGlobalsModRefAAPass(self)
--
--    def add_iv_users_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#iv-users-induction-variable-users
--
--        LLVM 14: `llvm::createIVUsersPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddIVUsersPass(self)
--
--    def add_lint_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#lint-statically-lint-checks-llvm-ir
--
--        LLVM 14: `llvm::createLintLegacyPassPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLintPass(self)
--
--    def add_lazy_value_info_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#lazy-value-info-lazy-value-information-analysis
--
--        LLVM 14: `llvm::createLazyValueInfoPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLazyValueInfoPass(self)
--
--    def add_module_debug_info_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#module-debuginfo-decodes-module-level-debug-info
--
--        LLVM 14: `llvm::createModuleDebugInfoPrinterPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddModuleDebugInfoPrinterPass(self)
--
--    def add_region_info_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#regions-detect-single-entry-single-exit-regions
--
--        LLVM 14: `llvm::createRegionInfoPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddRegionInfoPass(self)
--
--    def add_scalar_evolution_aa_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#scev-aa-scalarevolution-based-alias-analysis
--
--        LLVM 14: `llvm::createSCEVAAWrapperPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddScalarEvolutionAAPass(self)
--
--    def add_aggressive_dead_code_elimination_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#adce-aggressive-dead-code-elimination
--
--        LLVM 14: `llvm::createAggressiveDCEPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddAggressiveDCEPass(self)
--
--    def add_always_inliner_pass(self, insert_lifetime=True):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#always-inline-inliner-for-always-inline-functions
--
--        LLVM 14: `llvm::createAlwaysInlinerLegacyPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddAlwaysInlinerPass(self, insert_lifetime)
--
--    def add_arg_promotion_pass(self, max_elements=3):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#argpromotion-promote-by-reference-arguments-to-scalars
--
--        LLVM 14: `llvm::createArgumentPromotionPass`
--        &quot;&quot;&quot;  # noqa E501
--        raise RuntimeError('ArgumentPromotionPass unavailable in LLVM &gt; 14')
--
--    def add_break_critical_edges_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#break-crit-edges-break-critical-edges-in-cfg
--
--        LLVM 14: `llvm::createBreakCriticalEdgesPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddBreakCriticalEdgesPass(self)
--
--    def add_dead_store_elimination_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#dse-dead-store-elimination
--
--        LLVM 14: `llvm::createDeadStoreEliminationPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddDeadStoreEliminationPass(self)
--
--    def add_reverse_post_order_function_attrs_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#function-attrs-deduce-function-attributes
--
--        LLVM 14: `llvm::createReversePostOrderFunctionAttrsPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddReversePostOrderFunctionAttrsPass(self)
--
--    def add_function_attrs_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#functionattrs-deduce-function-attributes
--
--        LLVM 14: `LLVMAddFunctionAttrsPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddFunctionAttrsPass(self)
--
--    def add_function_inlining_pass(self, threshold):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#inline-function-integration-inlining
--
--        LLVM 14: `createFunctionInliningPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddFunctionInliningPass(self, threshold)
--
--    def add_global_dce_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#globaldce-dead-global-elimination
--
--        LLVM 14: `LLVMAddGlobalDCEPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddGlobalDCEPass(self)
--
--    def add_global_optimizer_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#globalopt-global-variable-optimizer
--
--        LLVM 14: `LLVMAddGlobalOptimizerPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddGlobalOptimizerPass(self)
--
--    def add_ipsccp_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#ipsccp-interprocedural-sparse-conditional-constant-propagation
--
--        LLVM 14: `LLVMAddIPSCCPPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddIPSCCPPass(self)
--
--    def add_dead_code_elimination_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#dce-dead-code-elimination
--        LLVM 14: `llvm::createDeadCodeEliminationPass`
--        &quot;&quot;&quot;
--        ffi.lib.LLVMPY_AddDeadCodeEliminationPass(self)
--
--    def add_aggressive_instruction_combining_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#aggressive-instcombine-combine-expression-patterns
--
--        LLVM 14: `llvm::createAggressiveInstCombinerPass`
--        &quot;&quot;&quot;  # noqa E501
--        if llvm_version_major &gt; 15:
--            msg = &quot;AggressiveInstrCombinerPass unavailable in LLVM &gt; 15&quot;
--            raise RuntimeError(msg)
--
--        ffi.lib.LLVMPY_AddAggressiveInstructionCombiningPass(self)
--
--    def add_internalize_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#internalize-internalize-global-symbols
--
--        LLVM 14: `llvm::createInternalizePass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddInternalizePass(self)
--
--    def add_cfg_simplification_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#simplifycfg-simplify-the-cfg
--
--        LLVM 14: `LLVMAddCFGSimplificationPass`
--        &quot;&quot;&quot;
--        ffi.lib.LLVMPY_AddCFGSimplificationPass(self)
--
--    def add_jump_threading_pass(self, threshold=-1):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#jump-threading-jump-threading
--
--        LLVM 14: `llvm::createJumpThreadingPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddJumpThreadingPass(self, threshold)
--
--    def add_lcssa_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#lcssa-loop-closed-ssa-form-pass
--
--        LLVM 14: `llvm::createLCSSAPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLCSSAPass(self)
--
--    def add_gvn_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#gvn-global-value-numbering
--
--        LLVM 14: `LLVMAddGVNPass`
--        &quot;&quot;&quot;
--        ffi.lib.LLVMPY_AddGVNPass(self)
--
--    def add_instruction_combining_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#passes-instcombine
--
--        LLVM 14: `LLVMAddInstructionCombiningPass`
--        &quot;&quot;&quot;
--        ffi.lib.LLVMPY_AddInstructionCombiningPass(self)
--
--    def add_licm_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#licm-loop-invariant-code-motion
--
--        LLVM 14: `LLVMAddLICMPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLICMPass(self)
--
--    def add_loop_deletion_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-deletion-delete-dead-loops
--
--        LLVM 14: `llvm::createLoopDeletionPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLoopDeletionPass(self)
--
--    def add_loop_extractor_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-extract-extract-loops-into-new-functions
--
--        LLVM 14: `llvm::createLoopExtractorPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLoopExtractorPass(self)
--
--    def add_single_loop_extractor_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-extract-single-extract-at-most-one-loop-into-a-new-function
--
--        LLVM 14: `llvm::createSingleLoopExtractorPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddSingleLoopExtractorPass(self)
--
--    def add_sccp_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/Passes.html#sccp-sparse-conditional-constant-propagation
--
--        LLVM 14: `LLVMAddSCCPPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddSCCPPass(self)
--
--    def add_loop_strength_reduce_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-reduce-loop-strength-reduction
--
--        LLVM 14: `llvm::createLoopStrengthReducePass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLoopStrengthReducePass(self)
--
--    def add_loop_simplification_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-simplify-canonicalize-natural-loops
--
--        LLVM 14: `llvm::createLoopSimplifyPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLoopSimplificationPass(self)
--
--    def add_loop_unroll_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-unroll-unroll-loops
--
--        LLVM 14: `LLVMAddLoopUnrollPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLoopUnrollPass(self)
--
--    def add_loop_unroll_and_jam_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-unroll-and-jam-unroll-and-jam-loops
--
--        LLVM 14: `LLVMAddLoopUnrollAndJamPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLoopUnrollAndJamPass(self)
--
--    def add_loop_unswitch_pass(self,
--                               optimize_for_size=False,
--                               has_branch_divergence=False):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loop-unswitch-unswitch-loops
--
--        LLVM 14: `llvm::createLoopUnswitchPass`
--        LLVM 15: `llvm::createSimpleLoopUnswitchLegacyPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLoopUnswitchPass(self, optimize_for_size,
--                                           has_branch_divergence)
--
--    def add_lower_atomic_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#loweratomic-lower-atomic-intrinsics-to-non-atomic-form
--
--        LLVM 14: `llvm::createLowerAtomicPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLowerAtomicPass(self)
--
--    def add_lower_invoke_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#lowerinvoke-lower-invokes-to-calls-for-unwindless-code-generators
--
--        LLVM 14: `llvm::createLowerInvokePass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLowerInvokePass(self)
--
--    def add_lower_switch_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#lowerswitch-lower-switchinsts-to-branches
--
--        LLVM 14: `llvm::createLowerSwitchPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddLowerSwitchPass(self)
--
--    def add_memcpy_optimization_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#memcpyopt-memcpy-optimization
--
--        LLVM 14: `llvm::createMemCpyOptPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddMemCpyOptimizationPass(self)
--
--    def add_merge_functions_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#mergefunc-merge-functions
--
--        LLVM 14: `llvm::createMergeFunctionsPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddMergeFunctionsPass(self)
--
--    def add_merge_returns_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#mergereturn-unify-function-exit-nodes
--
--        LLVM 14: `llvm::createUnifyFunctionExitNodesPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddMergeReturnsPass(self)
--
--    def add_partial_inlining_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#partial-inliner-partial-inliner
--
--        LLVM 14: `llvm::createPartialInliningPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddPartialInliningPass(self)
--
--    def add_prune_exception_handling_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#prune-eh-remove-unused-exception-handling-info
--
--        LLVM 14: `llvm::createPruneEHPass`
--        &quot;&quot;&quot;  # noqa E501
--        if llvm_version_major &gt; 15:
--            raise RuntimeError(&quot;PruneEHPass unavailable in LLVM &gt; 15&quot;)
--        ffi.lib.LLVMPY_AddPruneExceptionHandlingPass(self)
--
--    def add_reassociate_expressions_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#reassociate-reassociate-expressions
--
--        LLVM 14: `llvm::createReassociatePass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddReassociatePass(self)
--
--    def add_demote_register_to_memory_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#rel-lookup-table-converter-relative-lookup-table-converter
--
--        LLVM 14: `llvm::createDemoteRegisterToMemoryPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddDemoteRegisterToMemoryPass(self)
--
--    def add_sroa_pass(self):
--        &quot;&quot;&quot;
--        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`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddSROAPass(self)
--
--    def add_sink_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#sink-code-sinking
--
--        LLVM 14: `llvm::createSinkingPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddSinkPass(self)
--
--    def add_strip_symbols_pass(self, only_debug=False):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#strip-strip-all-symbols-from-a-module
--
--        LLVM 14: `llvm::createStripSymbolsPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddStripSymbolsPass(self, only_debug)
--
--    def add_strip_dead_debug_info_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#strip-dead-debug-info-strip-debug-info-for-unused-symbols
--
--        LLVM 14: `llvm::createStripDeadDebugInfoPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddStripDeadDebugInfoPass(self)
--
--    def add_strip_dead_prototypes_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#strip-dead-prototypes-strip-unused-function-prototypes
--
--        LLVM 14: `llvm::createStripDeadPrototypesPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddStripDeadPrototypesPass(self)
--
--    def add_strip_debug_declare_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#strip-debug-declare-strip-all-llvm-dbg-declare-intrinsics
--
--        LLVM 14: `llvm::createStripDebugDeclarePass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddStripDebugDeclarePrototypesPass(self)
--
--    def add_strip_nondebug_symbols_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#strip-nondebug-strip-all-symbols-except-dbg-symbols-from-a-module
--
--        LLVM 14: `llvm::createStripNonDebugSymbolsPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddStripNondebugSymbolsPass(self)
--
--    def add_tail_call_elimination_pass(self):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#tailcallelim-tail-call-elimination
--
--        LLVM 14: `llvm::createTailCallEliminationPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddTailCallEliminationPass(self)
--
--    def add_type_based_alias_analysis_pass(self):
--        &quot;&quot;&quot;
--        LLVM 14: `LLVMAddTypeBasedAliasAnalysisPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddTypeBasedAliasAnalysisPass(self)
--
--    def add_basic_alias_analysis_pass(self):
--        &quot;&quot;&quot;
--        See http://llvm.org/docs/AliasAnalysis.html#the-basicaa-pass
--
--        LLVM 14: `LLVMAddBasicAliasAnalysisPass`
--        &quot;&quot;&quot;
--        ffi.lib.LLVMPY_AddBasicAliasAnalysisPass(self)
--
--    def add_loop_rotate_pass(self):
--        &quot;&quot;&quot;http://llvm.org/docs/Passes.html#loop-rotate-rotate-loops.&quot;&quot;&quot;
--        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):
--        &quot;&quot;&quot;
--        See https://llvm.org/docs/Passes.html#instnamer-assign-names-to-anonymous-instructions.
--
--        LLVM 14: `llvm::createInstructionNamerPass`
--        &quot;&quot;&quot;  # noqa E501
--        ffi.lib.LLVMPY_AddInstructionNamerPass(self)
--
--    # Non-standard LLVM passes
--
--    def add_refprune_pass(self, subpasses_flags=RefPruneSubpasses.ALL,
--                          subgraph_limit=1000):
--        &quot;&quot;&quot;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.
--        &quot;&quot;&quot;
--        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=''):
--        &quot;&quot;&quot;
--        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.
--        &quot;&quot;&quot;
--        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(&quot;Failed to initialize remarks file.&quot;)
--            return r &gt; 0
--
--    def run_with_remarks(self, module, remarks_format='yaml',
--                         remarks_filter=''):
--        &quot;&quot;&quot;
--        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.
--        &quot;&quot;&quot;
--        remarkdesc, remarkfile = mkstemp()
--        try:
--            with os.fdopen(remarkdesc, 'r'):
--                pass
--            r = self.run(module, remarkfile, remarks_format, remarks_filter)
--            if r == -1:
--                raise IOError(&quot;Failed to initialize remarks file.&quot;)
--            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):
--        &quot;&quot;&quot;
--        Initialize the FunctionPassManager.  Returns True if it produced
--        any changes (?).
--        &quot;&quot;&quot;
--        return ffi.lib.LLVMPY_InitializeFunctionPassManager(self)
--
--    def finalize(self):
--        &quot;&quot;&quot;
--        Finalize the FunctionPassManager.  Returns True if it produced
--        any changes (?).
--        &quot;&quot;&quot;
--        return ffi.lib.LLVMPY_FinalizeFunctionPassManager(self)
--
--    def run(self, function, remarks_file=None, remarks_format='yaml',
--            remarks_filter=''):
--        &quot;&quot;&quot;
--        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.
--        &quot;&quot;&quot;
--        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(&quot;Failed to initialize remarks file.&quot;)
--            return bool(r)
--
--    def run_with_remarks(self, function, remarks_format='yaml',
--                         remarks_filter=''):
--        &quot;&quot;&quot;
--        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.
--        &quot;&quot;&quot;
--        # 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(&quot;Failed to initialize remarks file.&quot;)
--            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 &lt; 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 &lt; 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 &gt;= 15:
--    _object_formats = {
--        0: &quot;Unknown&quot;,
--        1: &quot;COFF&quot;,
--        2: &quot;DXContainer&quot;,
--        3: &quot;ELF&quot;,
--        4: &quot;GOFF&quot;,
--        5: &quot;MachO&quot;,
--        6: &quot;SPIRV&quot;,
--        7: &quot;Wasm&quot;,
--        8: &quot;XCOFF&quot;,
--    }
--else:
--    _object_formats = {
--        0: &quot;Unknown&quot;,
--        1: &quot;COFF&quot;,
--        2: &quot;ELF&quot;,
--        3: &quot;GOFF&quot;,
--        4: &quot;MachO&quot;,
--        5: &quot;Wasm&quot;,
--        6: &quot;XCOFF&quot;,
--    }
-+_object_formats = {
-+    0: &quot;Unknown&quot;,
-+    1: &quot;COFF&quot;,
-+    2: &quot;DXContainer&quot;,
-+    3: &quot;ELF&quot;,
-+    4: &quot;GOFF&quot;,
-+    5: &quot;MachO&quot;,
-+    6: &quot;SPIRV&quot;,
-+    7: &quot;Wasm&quot;,
-+    8: &quot;XCOFF&quot;,
-+}
- 
- 
- 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):
--        &quot;&quot;&quot;
--        The general optimization level as an integer between 0 and 3.
--        &quot;&quot;&quot;
--        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):
--        &quot;&quot;&quot;
--        Whether and how much to optimize for size.  An integer between 0 and 2.
--        &quot;&quot;&quot;
--        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):
--        &quot;&quot;&quot;
--        The integer threshold for inlining a function into another.  The higher,
--        the more likely inlining a function is.  This attribute is write-only.
--        &quot;&quot;&quot;
--        raise NotImplementedError(&quot;inlining_threshold is write-only&quot;)
--
--    @inlining_threshold.setter
--    def inlining_threshold(self, threshold):
--        ffi.lib.LLVMPY_PassManagerBuilderUseInlinerWithThreshold(
--            self, threshold)
--
--    @property
--    def disable_unroll_loops(self):
--        &quot;&quot;&quot;
--        If true, disable loop unrolling.
--        &quot;&quot;&quot;
--        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):
--        &quot;&quot;&quot;
--        If true, allow vectorizing loops.
--        &quot;&quot;&quot;
--        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):
--        &quot;&quot;&quot;
--        If true, enable the &quot;SLP vectorizer&quot;, which uses a different algorithm
--        from the loop vectorizer.  Both may be enabled at the same time.
--        &quot;&quot;&quot;
--        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(&quot;Type {} doesn't contain elements.&quot;.format(self))
-         return _TypeListIterator(ffi.lib.LLVMPY_ElementIter(self))
- 
--    # FIXME: Remove me once typed pointers support is removed.
--    @property
--    def element_type(self):
--        &quot;&quot;&quot;
--        Returns the pointed-to type. When the type is not a pointer,
--        raises exception.
--        &quot;&quot;&quot;
--        if not self.is_pointer:
--            raise ValueError(&quot;Type {} is not a pointer&quot;.format(self))
--        return TypeRef(ffi.lib.LLVMPY_GetElementType(self))
--
-     @property
-     def element_count(self):
-         &quot;&quot;&quot;
-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 = {
-+        &quot;entry:&quot;: [&quot;A&quot;],
-         &quot;A&quot;: [&quot;B&quot;, &quot;C&quot;],
-         &quot;B&quot;: [&quot;C&quot;],
-         &quot;C&quot;: [],
-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 = &quot;&quot;&quot;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 &gt; 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(&quot;expected tokens not found&quot;)
--                othertoken = (toks ^ {t}).pop()
--
--                self.assertIn(&quot;%.3&quot;, orig_asm)
--                self.assertNotIn(othertoken, opt_asm)
--                break
--        else:
--            raise RuntimeError(&quot;expected IR not found&quot;)
--
--    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(&quot;Passed&quot;, remarks)
--        self.assertIn(&quot;inlineme&quot;, 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(&quot;Missed&quot;, remarks)
--        self.assertIn(&quot;inlineme&quot;, remarks)
--        self.assertIn(&quot;noinline function attribute&quot;, 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=&quot;nothing&quot;)
--        self.assertTrue(status)
--        self.assertEqual(&quot;&quot;, 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=&quot;inlin.*&quot;)
--        self.assertTrue(status)
--        self.assertIn(&quot;Passed&quot;, remarks)
--        self.assertIn(&quot;inlineme&quot;, 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(&quot;sum&quot;)
--        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(&quot;%.4&quot;, orig_asm)
--        self.assertNotIn(&quot;%.4&quot;, opt_asm)
--
--    def test_run_with_remarks(self):
--        mod = self.module(licm_asm)
--        fn = mod.get_function(&quot;licm&quot;)
--        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(&quot;Passed&quot;, remarks)
--        self.assertIn(&quot;licm&quot;, remarks)
--
--    def test_run_with_remarks_filter_out(self):
--        mod = self.module(licm_asm)
--        fn = mod.get_function(&quot;licm&quot;)
--        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=&quot;nothing&quot;)
--        pm.finalize()
--        self.assertTrue(ok)
--        self.assertEqual(&quot;&quot;, remarks)
--
--    def test_run_with_remarks_filter_in(self):
--        mod = self.module(licm_asm)
--        fn = mod.get_function(&quot;licm&quot;)
--        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=&quot;licm&quot;)
--        pm.finalize()
--        self.assertTrue(ok)
--        self.assertIn(&quot;Passed&quot;, remarks)
--        self.assertIn(&quot;licm&quot;, 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(&quot;&quot;) # 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 &lt; 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 &lt; 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(&quot;x86&quot;), &quot;x86 only&quot;)
--    def test_target_library_info_behavior(self):
--        &quot;&quot;&quot;Test a specific situation that demonstrate TLI is affecting
--        optimization. See https://github.com/numba/numba/issues/8898.
--        &quot;&quot;&quot;
--        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 -&gt; ldexpf
--        mod = run(use_tli=True)
--        self.assertIn(&quot;call float @llvm.exp2.f32&quot;, str(mod))
--
--        # Run without TLI will enable the transformation
--        mod = run(use_tli=False)
--        self.assertNotIn(&quot;call float @llvm.exp2.f32&quot;, str(mod))
--        self.assertIn(&quot;call float @ldexpf&quot;, 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(&quot;Pass execution timing report&quot;), 1)
-+#         self.assertIsInstance(report, str)
-+#         self.assertEqual(report.count(&quot;Pass execution timing report&quot;), 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(&quot;acq&quot;, events)
-         self.assertIn(&quot;rel&quot;, 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 &gt;= 18 have been adds an extra empty block &quot;LoopExit&quot; 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 + &quot;_legacy&quot;] = 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&quot;{self.prologue}\n{irmod}&quot;)
--        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&quot;&quot;&quot;
- 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(&quot;call void @NRT_incref(ptr %ptr)&quot;, 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(&quot;call void @NRT_incref(ptr %ptr)&quot;, str(mod))
--
-     per_bb_ir_3 = r&quot;&quot;&quot;
- 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(&quot;call void @NRT_decref(ptr %other)&quot;, 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(&quot;call void @NRT_decref(ptr %other)&quot;, str(mod))
--
-     per_bb_ir_4 = r&quot;&quot;&quot;
- ; reordered
- define void @main(ptr %ptr, ptr %other) {
-@@ -304,12 +266,6 @@ def test_per_bb_4(self):
-         # not pruned
-         self.assertIn(&quot;call void @NRT_decref(ptr %other)&quot;, 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(&quot;call void @NRT_decref(ptr %other)&quot;, 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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):
-     &quot;&quot;&quot;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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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&quot;&quot;&quot;
- 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 &lt;stender@debian.org&gt;
-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, [&quot;--ldflags&quot;])
--    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'] = &quot;-static-libstdc++&quot;
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 @@
-         }}
-     &quot;&quot;&quot;
- 
-+    # 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 &lt;diane@ghic.org&gt;
-Description: Point intersphinx to copies of the sphinx objects.inv
- files built by debian for the referenced projects
+From: Diane Trout &lt;diane@ghic.org&gt;
+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=&quot;$(shell basename $(shell $(LLVM_CONFIG) --prefix))&quot;
+
+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=&quot;filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%llvmlite-$1.tar.gz%&quot; \
-    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

--===============6242040190130373143==--
]