From 33e39a376fdbcceb6d4e757f4a798b3922e7068c Mon Sep 17 00:00:00 2001 From: Dmitrii Dolgov <9erthalion6@gmail.com> Date: Sun, 4 Jun 2023 11:10:41 +0200 Subject: [PATCH 2/2] LLVM 17 --- src/backend/jit/llvm/llvmjit.c | 73 ++++++++------------------- src/backend/jit/llvm/llvmjit_wrap.cpp | 4 ++ 2 files changed, 25 insertions(+), 52 deletions(-) diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index b83bc04ae3a..b701e167abd 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -18,6 +18,9 @@ #include #include #include +#if LLVM_VERSION_MAJOR > 16 +#include +#endif #if LLVM_VERSION_MAJOR > 11 #include #include @@ -27,12 +30,14 @@ #endif #include #include +#if LLVM_VERSION_MAJOR < 17 #include #include #include #if LLVM_VERSION_MAJOR > 6 #include #endif +#endif #include "jit/llvmjit.h" #include "jit/llvmjit_emit.h" @@ -559,69 +564,33 @@ llvm_function_reference(LLVMJitContext *context, static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module) { - LLVMPassManagerBuilderRef llvm_pmb; - LLVMPassManagerRef llvm_mpm; - LLVMPassManagerRef llvm_fpm; - LLVMValueRef func; + LLVMPassBuilderOptionsRef options; + LLVMErrorRef err; int compile_optlevel; + char *passes; if (context->base.flags & PGJIT_OPT3) compile_optlevel = 3; else compile_optlevel = 0; - /* - * Have to create a new pass manager builder every pass through, as the - * inliner has some per-builder state. Otherwise one ends up only inlining - * a function the first time though. - */ - llvm_pmb = LLVMPassManagerBuilderCreate(); - LLVMPassManagerBuilderSetOptLevel(llvm_pmb, compile_optlevel); - llvm_fpm = LLVMCreateFunctionPassManagerForModule(module); + passes = psprintf("default,mem2reg,function(no-op-function),no-op-module", + compile_optlevel); - if (context->base.flags & PGJIT_OPT3) - { - /* TODO: Unscientifically determined threshold */ - LLVMPassManagerBuilderUseInlinerWithThreshold(llvm_pmb, 512); - } - else - { - /* we rely on mem2reg heavily, so emit even in the O0 case */ - LLVMAddPromoteMemoryToRegisterPass(llvm_fpm); - } + options = LLVMCreatePassBuilderOptions(); - LLVMPassManagerBuilderPopulateFunctionPassManager(llvm_pmb, llvm_fpm); +#ifdef LLVM_PASS_DEBUG + LLVMPassBuilderOptionsSetDebugLogging(options, 1); +#endif - /* - * Do function level optimization. This could be moved to the point where - * functions are emitted, to reduce memory usage a bit. - */ - LLVMInitializeFunctionPassManager(llvm_fpm); - for (func = LLVMGetFirstFunction(context->module); - func != NULL; - func = LLVMGetNextFunction(func)) - LLVMRunFunctionPassManager(llvm_fpm, func); - LLVMFinalizeFunctionPassManager(llvm_fpm); - LLVMDisposePassManager(llvm_fpm); + LLVMPassBuilderOptionsSetInlinerThreshold(options, 512); - /* - * Perform module level optimization. We do so even in the non-optimized - * case, so always-inline functions etc get inlined. It's cheap enough. - */ - llvm_mpm = LLVMCreatePassManager(); - LLVMPassManagerBuilderPopulateModulePassManager(llvm_pmb, - llvm_mpm); - /* always use always-inliner pass */ - if (!(context->base.flags & PGJIT_OPT3)) - LLVMAddAlwaysInlinerPass(llvm_mpm); - /* if doing inlining, but no expensive optimization, add inlining pass */ - if (context->base.flags & PGJIT_INLINE - && !(context->base.flags & PGJIT_OPT3)) - LLVMAddFunctionInliningPass(llvm_mpm); - LLVMRunPassManager(llvm_mpm, context->module); - LLVMDisposePassManager(llvm_mpm); - - LLVMPassManagerBuilderDispose(llvm_pmb); + err = LLVMRunPasses(module, passes, NULL, options); + + if (err) + elog(ERROR, "failed to JIT module: %s", llvm_error_message(err)); + + LLVMDisposePassBuilderOptions(options); } /* diff --git a/src/backend/jit/llvm/llvmjit_wrap.cpp b/src/backend/jit/llvm/llvmjit_wrap.cpp index 997a2c02789..7b51f3d825c 100644 --- a/src/backend/jit/llvm/llvmjit_wrap.cpp +++ b/src/backend/jit/llvm/llvmjit_wrap.cpp @@ -24,7 +24,11 @@ extern "C" #include #include #include +#if LLVM_VERSION_MAJOR > 16 +#include +#else #include +#endif #include "jit/llvmjit.h" -- 2.32.0