AC_REQUIRE([AC_PROG_AWK])
 
   AC_ARG_VAR(LLVM_CONFIG, [path to llvm-config command])
-  PGAC_PATH_PROGS(LLVM_CONFIG, llvm-config llvm-config-7 llvm-config-6.0 llvm-config-5.0 llvm-config-4.0 llvm-config-3.9)
+  PGAC_PATH_PROGS(LLVM_CONFIG, llvm-config llvm-config-17 llvm-config-16 llvm-config-15 llvm-config-14 llvm-config-13 llvm-config-12 llvm-config-11 llvm-config-10)
 
   # no point continuing if llvm wasn't found
   if test -z "$LLVM_CONFIG"; then
     AC_MSG_ERROR([$LLVM_CONFIG does not work])
   fi
   # and whether the version is supported
-  if echo $pgac_llvm_version | $AWK -F '.' '{ if ([$]1 >= 4 || ([$]1 == 3 && [$]2 >= 9)) exit 1; else exit 0;}';then
-    AC_MSG_ERROR([$LLVM_CONFIG version is $pgac_llvm_version but at least 3.9 is required])
+  if echo $pgac_llvm_version | $AWK -F '.' '{ if ([$]1 >= 10) exit 1; else exit 0;}';then
+    AC_MSG_ERROR([$LLVM_CONFIG version is $pgac_llvm_version but at least 10 is required])
   fi
   AC_MSG_NOTICE([using llvm $pgac_llvm_version])
 
   # need clang to create some bitcode files
   AC_ARG_VAR(CLANG, [path to clang compiler to generate bitcode])
-  PGAC_PATH_PROGS(CLANG, clang clang-7 clang-6.0 clang-5.0 clang-4.0 clang-3.9)
+  PGAC_PATH_PROGS(CLANG, clang clang-17 clang-16 clang-15 clang-14 clang-13 clang-12 clang-11 clang-10)
   if test -z "$CLANG"; then
     AC_MSG_ERROR([clang not found, but required when compiling --with-llvm, specify with CLANG=])
   fi
   # Check which functionality is present
   SAVE_CPPFLAGS="$CPPFLAGS"
   CPPFLAGS="$CPPFLAGS $LLVM_CPPFLAGS"
-  AC_CHECK_DECLS([LLVMOrcGetSymbolAddressIn], [], [], [[#include <llvm-c/OrcBindings.h>]])
-  AC_CHECK_DECLS([LLVMGetHostCPUName, LLVMGetHostCPUFeatures], [], [], [[#include <llvm-c/TargetMachine.h>]])
   AC_CHECK_DECLS([LLVMCreateGDBRegistrationListener, LLVMCreatePerfJITEventListener], [], [], [[#include <llvm-c/ExecutionEngine.h>]])
   CPPFLAGS="$SAVE_CPPFLAGS"
 ])# PGAC_CHECK_LLVM_FUNCTIONS
 
 
 
   if test -z "$LLVM_CONFIG"; then
-  for ac_prog in llvm-config llvm-config-7 llvm-config-6.0 llvm-config-5.0 llvm-config-4.0 llvm-config-3.9
+  for ac_prog in llvm-config llvm-config-17 llvm-config-16 llvm-config-15 llvm-config-14 llvm-config-13 llvm-config-12 llvm-config-11 llvm-config-10
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
     as_fn_error $? "$LLVM_CONFIG does not work" "$LINENO" 5
   fi
   # and whether the version is supported
-  if echo $pgac_llvm_version | $AWK -F '.' '{ if ($1 >= 4 || ($1 == 3 && $2 >= 9)) exit 1; else exit 0;}';then
-    as_fn_error $? "$LLVM_CONFIG version is $pgac_llvm_version but at least 3.9 is required" "$LINENO" 5
+  if echo $pgac_llvm_version | $AWK -F '.' '{ if ($1 >= 10) exit 1; else exit 0;}';then
+    as_fn_error $? "$LLVM_CONFIG version is $pgac_llvm_version but at least 10 is required" "$LINENO" 5
   fi
   { $as_echo "$as_me:${as_lineno-$LINENO}: using llvm $pgac_llvm_version" >&5
 $as_echo "$as_me: using llvm $pgac_llvm_version" >&6;}
   # need clang to create some bitcode files
 
   if test -z "$CLANG"; then
-  for ac_prog in clang clang-7 clang-6.0 clang-5.0 clang-4.0 clang-3.9
+  for ac_prog in clang clang-17 clang-16 clang-15 clang-14 clang-13 clang-12 clang-11 clang-10
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
   # Check which functionality is present
   SAVE_CPPFLAGS="$CPPFLAGS"
   CPPFLAGS="$CPPFLAGS $LLVM_CPPFLAGS"
-  ac_fn_c_check_decl "$LINENO" "LLVMOrcGetSymbolAddressIn" "ac_cv_have_decl_LLVMOrcGetSymbolAddressIn" "#include <llvm-c/OrcBindings.h>
-"
-if test "x$ac_cv_have_decl_LLVMOrcGetSymbolAddressIn" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN $ac_have_decl
-_ACEOF
-
-  ac_fn_c_check_decl "$LINENO" "LLVMGetHostCPUName" "ac_cv_have_decl_LLVMGetHostCPUName" "#include <llvm-c/TargetMachine.h>
-"
-if test "x$ac_cv_have_decl_LLVMGetHostCPUName" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_LLVMGETHOSTCPUNAME $ac_have_decl
-_ACEOF
-ac_fn_c_check_decl "$LINENO" "LLVMGetHostCPUFeatures" "ac_cv_have_decl_LLVMGetHostCPUFeatures" "#include <llvm-c/TargetMachine.h>
-"
-if test "x$ac_cv_have_decl_LLVMGetHostCPUFeatures" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_LLVMGETHOSTCPUFEATURES $ac_have_decl
-_ACEOF
-
   ac_fn_c_check_decl "$LINENO" "LLVMCreateGDBRegistrationListener" "ac_cv_have_decl_LLVMCreateGDBRegistrationListener" "#include <llvm-c/ExecutionEngine.h>
 "
 if test "x$ac_cv_have_decl_LLVMCreateGDBRegistrationListener" = xyes; then :
 
          <acronym>JIT</acronym> compilation (see <xref linkend="jit"/>).  This
          requires the <productname>LLVM</productname> library to be installed.
          The minimum required version of <productname>LLVM</productname> is
-         currently 3.9.
+         currently 10.
         </para>
         <para>
          <command>llvm-config</command><indexterm><primary>llvm-config</primary></indexterm>
         <acronym>JIT</acronym> compilation (see <xref linkend="jit"/>).
         This requires the <productname>LLVM</productname> library to be
         installed.  The minimum required version of
-        <productname>LLVM</productname> is currently 3.9.  Disabled by
+        <productname>LLVM</productname> is currently 10.  Disabled by
         default.
        </para>
 
 
 llvmopt = get_option('llvm')
 llvm = not_found_dep
 if add_languages('cpp', required: llvmopt, native: false)
-  llvm = dependency('llvm', version: '>=3.9', method: 'config-tool', required: llvmopt)
+  llvm = dependency('llvm', version: '>=10', method: 'config-tool', required: llvmopt)
 
   if llvm.found()
 
 
 #include <llvm-c/Transforms/IPO.h>
 #include <llvm-c/Transforms/PassManagerBuilder.h>
 #include <llvm-c/Transforms/Scalar.h>
-#if LLVM_VERSION_MAJOR > 6
 #include <llvm-c/Transforms/Utils.h>
 #endif
-#endif
 
 #include "jit/llvmjit.h"
 #include "jit/llvmjit_emit.h"
 void *
 llvm_get_function(LLVMJitContext *context, const char *funcname)
 {
-#if LLVM_VERSION_MAJOR > 11 || \
-   defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
    ListCell   *lc;
-#endif
 
    llvm_assert_in_fatal_section();
 
        if (addr)
            return (void *) (uintptr_t) addr;
    }
-#elif defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
+#else
    foreach(lc, context->handles)
    {
        LLVMOrcTargetAddress addr;
        if (addr)
            return (void *) (uintptr_t) addr;
    }
-#elif LLVM_VERSION_MAJOR < 5
-   {
-       LLVMOrcTargetAddress addr;
-
-       if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
-           return (void *) (uintptr_t) addr;
-       if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
-           return (void *) (uintptr_t) addr;
-   }
-#else
-   {
-       LLVMOrcTargetAddress addr;
-
-       if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
-           elog(ERROR, "failed to look up symbol \"%s\"", funcname);
-       if (addr)
-           return (void *) (uintptr_t) addr;
-       if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
-           elog(ERROR, "failed to look up symbol \"%s\"", funcname);
-       if (addr)
-           return (void *) (uintptr_t) addr;
-   }
 #endif
 
    elog(ERROR, "failed to JIT: %s", funcname);
    int         num_attributes;
    LLVMAttributeRef *attrs;
 
-   num_attributes = LLVMGetAttributeCountAtIndexPG(v_from, index);
+   num_attributes = LLVMGetAttributeCountAtIndex(v_from, index);
 
-   /*
-    * Not just for efficiency: LLVM <= 3.9 crashes when
-    * LLVMGetAttributesAtIndex() is called for an index with 0 attributes.
-    */
    if (num_attributes == 0)
        return;
 
 
        /* LLVMOrcLLJITAddLLVMIRModuleWithRT takes ownership of the module */
    }
-#elif LLVM_VERSION_MAJOR > 6
+#else
    {
        handle->stack = compile_orc;
        if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, context->module,
 
        /* LLVMOrcAddEagerlyCompiledIR takes ownership of the module */
    }
-#elif LLVM_VERSION_MAJOR > 4
-   {
-       LLVMSharedModuleRef smod;
-
-       smod = LLVMOrcMakeSharedModule(context->module);
-       handle->stack = compile_orc;
-       if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, smod,
-                                       llvm_resolve_symbol, NULL))
-           elog(ERROR, "failed to JIT module");
-
-       LLVMOrcDisposeSharedModuleRef(smod);
-   }
-#else                          /* LLVM 4.0 and 3.9 */
-   {
-       handle->stack = compile_orc;
-       handle->orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
-                                                        llvm_resolve_symbol, NULL);
-
-       LLVMDisposeModule(context->module);
-   }
 #endif
 
    INSTR_TIME_SET_CURRENT(endtime);
 
 static std::new_handler old_new_handler = NULL;
 
 static void fatal_system_new_handler(void);
-#if LLVM_VERSION_MAJOR > 4
 static void fatal_llvm_new_handler(void *user_data, const char *reason, bool gen_crash_diag);
 #if LLVM_VERSION_MAJOR < 14
 static void fatal_llvm_new_handler(void *user_data, const std::string& reason, bool gen_crash_diag);
 #endif
-#endif
 static void fatal_llvm_error_handler(void *user_data, const char *reason, bool gen_crash_diag);
 #if LLVM_VERSION_MAJOR < 14
 static void fatal_llvm_error_handler(void *user_data, const std::string& reason, bool gen_crash_diag);
    if (fatal_new_handler_depth == 0)
    {
        old_new_handler = std::set_new_handler(fatal_system_new_handler);
-#if LLVM_VERSION_MAJOR > 4
        llvm::install_bad_alloc_error_handler(fatal_llvm_new_handler);
-#endif
        llvm::install_fatal_error_handler(fatal_llvm_error_handler);
    }
    fatal_new_handler_depth++;
    if (fatal_new_handler_depth == 0)
    {
        std::set_new_handler(old_new_handler);
-#if LLVM_VERSION_MAJOR > 4
        llvm::remove_bad_alloc_error_handler();
-#endif
        llvm::remove_fatal_error_handler();
    }
 }
    if (fatal_new_handler_depth != 0)
    {
        std::set_new_handler(old_new_handler);
-#if LLVM_VERSION_MAJOR > 4
        llvm::remove_bad_alloc_error_handler();
-#endif
        llvm::remove_fatal_error_handler();
    }
    fatal_new_handler_depth = 0;
             errdetail("while in LLVM")));
 }
 
-#if LLVM_VERSION_MAJOR > 4
 static void
 fatal_llvm_new_handler(void *user_data,
                       const char *reason,
    fatal_llvm_new_handler(user_data, reason.c_str(), gen_crash_diag);
 }
 #endif
-#endif
 
 static void
 fatal_llvm_error_handler(void *user_data,
 
    LLVMTypeRef param_types[2];
    LLVMContextRef lc;
 
-   /* LLVM 5+ has a variadic pointer argument */
-#if LLVM_VERSION_MAJOR < 5
-   const char *nm = "llvm.lifetime.end";
-#else
+   /* variadic pointer argument */
    const char *nm = "llvm.lifetime.end.p0i8";
-#endif
 
    fn = LLVMGetNamedFunction(mod, nm);
    if (fn)
 
 #include <llvm/ADT/StringSet.h>
 #include <llvm/ADT/StringMap.h>
 #include <llvm/Analysis/ModuleSummaryAnalysis.h>
-#if LLVM_VERSION_MAJOR > 3
 #include <llvm/Bitcode/BitcodeReader.h>
-#else
-#include <llvm/Bitcode/ReaderWriter.h>
-#include <llvm/Support/Error.h>
-#endif
 #include <llvm/IR/Attributes.h>
 #include <llvm/IR/DebugInfo.h>
 #include <llvm/IR/IntrinsicInst.h>
 
            fs = llvm::cast<llvm::FunctionSummary>(gvs);
 
-#if LLVM_VERSION_MAJOR > 3
            if (gvs->notEligibleToImport())
            {
                ilog(DEBUG1, "ineligibile to import %s due to summary",
                     symbolName.data());
                continue;
            }
-#endif
 
            if ((int) fs->instCount() > inlineState.costLimit)
            {
 
        }
 
-#if LLVM_VERSION_MAJOR > 4
-#define IRMOVE_PARAMS , /*IsPerformingImport=*/false
-#elif LLVM_VERSION_MAJOR > 3
-#define IRMOVE_PARAMS , /*LinkModuleInlineAsm=*/false, /*IsPerformingImport=*/false
-#else
-#define IRMOVE_PARAMS
-#endif
        if (Mover.move(std::move(importMod), GlobalsToImport.getArrayRef(),
-                      [](llvm::GlobalValue &, llvm::IRMover::ValueAdder) {}
-                      IRMOVE_PARAMS))
+                      [](llvm::GlobalValue &, llvm::IRMover::ValueAdder) {},
+                      /*IsPerformingImport=*/false))
            elog(FATAL, "function import failed with linker error");
    }
 }
    {
        llvm::MemoryBufferRef ref(*MBOrErr.get().get());
 
-#if LLVM_VERSION_MAJOR > 3
        llvm::Expected<std::unique_ptr<llvm::ModuleSummaryIndex> > IndexOrErr =
            llvm::getModuleSummaryIndex(ref);
        if (IndexOrErr)
        elog(FATAL, "failed to load summary \"%s\": %s",
             path.data(),
             toString(IndexOrErr.takeError()).c_str());
-#else
-       llvm::ErrorOr<std::unique_ptr<llvm::ModuleSummaryIndex> > IndexOrErr =
-           llvm::getModuleSummaryIndex(ref, [](const llvm::DiagnosticInfo &) {});
-       if (IndexOrErr)
-           return std::move(IndexOrErr.get());
-       elog(FATAL, "failed to load summary \"%s\": %s",
-            path.data(),
-            IndexOrErr.getError().message().c_str());
-#endif
    }
    return nullptr;
 }
 
    for (auto index : path)
    {
-#if LLVM_VERSION_MAJOR > 4
        llvm::ValueInfo funcVI = index->getValueInfo(guid);
 
        /* if index doesn't know function, we don't have a body, continue */
        if (funcVI)
            for (auto &gv : funcVI.getSummaryList())
                matches.push_back(gv.get());
-#else
-       const llvm::const_gvsummary_iterator &I =
-           index->findGlobalValueSummaryList(guid);
-       if (I != index->end())
-       {
-           for (auto &gv : I->second)
-               matches.push_back(gv.get());
-       }
-#endif
    }
 
    return matches;
 
 /* Avoid macro clash with LLVM's C++ headers */
 #undef Min
 
-#include <llvm/IR/Attributes.h>
 #include <llvm/IR/Function.h>
-#if LLVM_VERSION_MAJOR < 17
-#include <llvm/MC/SubtargetFeature.h>
-#endif
-#if LLVM_VERSION_MAJOR > 16
-#include <llvm/TargetParser/Host.h>
-#else
-#include <llvm/Support/Host.h>
-#endif
 
 #include "jit/llvmjit.h"
 
 /*
  * C-API extensions.
  */
-#if defined(HAVE_DECL_LLVMGETHOSTCPUNAME) && !HAVE_DECL_LLVMGETHOSTCPUNAME
-char *LLVMGetHostCPUName(void) {
-   return strdup(llvm::sys::getHostCPUName().data());
-}
-#endif
-
-
-#if defined(HAVE_DECL_LLVMGETHOSTCPUFEATURES) && !HAVE_DECL_LLVMGETHOSTCPUFEATURES
-char *LLVMGetHostCPUFeatures(void) {
-   llvm::SubtargetFeatures Features;
-   llvm::StringMap<bool> HostFeatures;
-
-   if (llvm::sys::getHostCPUFeatures(HostFeatures))
-       for (auto &F : HostFeatures)
-           Features.AddFeature(F.first(), F.second);
-
-   return strdup(Features.getString().c_str());
-}
-#endif
-
-/*
- * Like LLVM's LLVMGetAttributeCountAtIndex(), works around a bug in LLVM 3.9.
- *
- * In LLVM <= 3.9, LLVMGetAttributeCountAtIndex() segfaults if there are no
- * attributes at an index (fixed in LLVM commit ce9bb1097dc2).
- */
-unsigned
-LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx)
-{
-   /*
-    * This is more expensive, so only do when using a problematic LLVM
-    * version.
-    */
-#if LLVM_VERSION_MAJOR < 4
-   if (!llvm::unwrap<llvm::Function>(F)->getAttributes().hasAttributes(Idx))
-       return 0;
-#endif
-
-   /*
-    * There is no nice public API to determine the count nicely, so just
-    * always fall back to LLVM's C API.
-    */
-   return LLVMGetAttributeCountAtIndex(F, Idx);
-}
 
 LLVMTypeRef
 LLVMGetFunctionReturnType(LLVMValueRef r)
 {
    return llvm::wrap(llvm::unwrap<llvm::Function>(r)->getFunctionType());
 }
-
-#if LLVM_VERSION_MAJOR < 8
-LLVMTypeRef
-LLVMGlobalGetValueType(LLVMValueRef g)
-{
-   return llvm::wrap(llvm::unwrap<llvm::GlobalValue>(g)->getValueType());
-}
-#endif
 
  * Error handling related functions.
  ****************************************************************************
  */
-#if defined(HAVE_DECL_LLVMGETHOSTCPUNAME) && !HAVE_DECL_LLVMGETHOSTCPUNAME
-/** Get the host CPU as a string. The result needs to be disposed with
-  LLVMDisposeMessage. */
-extern char *LLVMGetHostCPUName(void);
-#endif
-
-#if defined(HAVE_DECL_LLVMGETHOSTCPUFEATURES) && !HAVE_DECL_LLVMGETHOSTCPUFEATURES
-/** Get the host CPU features as a string. The result needs to be disposed
-  with LLVMDisposeMessage. */
-extern char *LLVMGetHostCPUFeatures(void);
-#endif
-
-extern unsigned LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx);
 extern LLVMTypeRef LLVMGetFunctionReturnType(LLVMValueRef r);
 extern LLVMTypeRef LLVMGetFunctionType(LLVMValueRef r);
 
-#if LLVM_MAJOR_VERSION < 8
-extern LLVMTypeRef LLVMGlobalGetValueType(LLVMValueRef g);
-#endif
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
 
    `LLVMCreatePerfJITEventListener', and to 0 if you don't. */
 #undef HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
 
-/* Define to 1 if you have the declaration of `LLVMGetHostCPUFeatures', and to
-   0 if you don't. */
-#undef HAVE_DECL_LLVMGETHOSTCPUFEATURES
-
-/* Define to 1 if you have the declaration of `LLVMGetHostCPUName', and to 0
-   if you don't. */
-#undef HAVE_DECL_LLVMGETHOSTCPUNAME
-
-/* Define to 1 if you have the declaration of `LLVMOrcGetSymbolAddressIn', and
-   to 0 if you don't. */
-#undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
-
 /* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you
    don't. */
 #undef HAVE_DECL_POSIX_FADVISE