On Monday, January 29, 2018 10:53:50 AM CET Andres Freund wrote: > Hi, > > On 2018-01-23 23:20:38 -0800, Andres Freund wrote: > > == Code == > > > > As the patchset is large (500kb) and I'm still quickly evolving it, I do > > not yet want to attach it. The git tree is at > > > > https://git.postgresql.org/git/users/andresfreund/postgres.git > > > > in the jit branch > > > > https://git.postgresql.org/gitweb/?p=users/andresfreund/postgres.git;a=s > > hortlog;h=refs/heads/jit > I've just pushed an updated and rebased version of the tree: > - Split the large "jit infrastructure" commits into a number of smaller > commits > - Split the C++ file > - Dropped some of the performance stuff done to heaptuple.c - that was > mostly to make performance comparisons a bit more interesting, but > doesn't seem important enough to deal with. > - Added a commit renaming datetime.h symbols so they don't conflict with > LLVM variables anymore, removing ugly #undef PM/#define PM dance > around includes. Will post separately. > - Reduced the number of pointer constants in the generated LLVM IR, by > doing more getelementptr accesses (stem from before the time types > were automatically synced) > - Increased number of comments a bit > > There's a jit-before-rebase-2018-01-29 tag, for the state of the tree > before the rebase. > > Regards, > > Andres
Hi I have successfully built the JIT branch against LLVM 4.0.1 on Debian testing. This is not enough for Debian stable (LLVM 3.9 is the latest available there), but it's a first step. I've split the patch in four files. The first three fix the build issues, the last one fixes a runtime issue. I think they are small enough to not be a burden for you in your developments. But if you don't want to carry these ifdefs right now, I maintain them in a branch on a personal git and rebase as frequently as I can. LLVM 3.9 support isn't going to be hard, but I prefer splitting. I also hope this will help more people test this wonderful toy… :) Regards Pierre
>From 770104331a36a8d207053227b850396f1392939a Mon Sep 17 00:00:00 2001 From: Pierre <pierre.ducroq...@people-doc.com> Date: Fri, 2 Feb 2018 09:11:55 +0100 Subject: [PATCH 1/4] Add support for LLVM4 in llvmjit.c --- src/backend/lib/llvmjit.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/backend/lib/llvmjit.c b/src/backend/lib/llvmjit.c index 8e5ba94c98..d0c5537610 100644 --- a/src/backend/lib/llvmjit.c +++ b/src/backend/lib/llvmjit.c @@ -230,12 +230,19 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) addr = 0; if (LLVMOrcGetSymbolAddressIn(handle->stack, &addr, handle->orc_handle, mangled)) - elog(ERROR, "failed to lookup symbol"); + elog(ERROR, "failed to lookup symbol %s", mangled); if (addr) return (void *) addr; } #endif +#if LLVM_VERSION_MAJOR < 5 + if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, mangled))) + return (void *) addr; + if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, mangled))) + return (void *) addr; + elog(ERROR, "failed to lookup symbol %s for %s", mangled, funcname); +#else if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, mangled)) elog(ERROR, "failed to lookup symbol"); if (addr) @@ -244,7 +251,7 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) elog(ERROR, "failed to lookup symbol"); if (addr) return (void *) addr; - +#endif elog(ERROR, "failed to JIT: %s", funcname); return NULL; @@ -380,11 +387,21 @@ llvm_compile_module(LLVMJitContext *context) * faster instruction selection mechanism is used. */ { - LLVMSharedModuleRef smod; instr_time tb, ta; /* emit the code */ INSTR_TIME_SET_CURRENT(ta); +#if LLVM_VERSION < 5 + orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module, + llvm_resolve_symbol, NULL); + if (!orc_handle) + { + elog(ERROR, "failed to jit module"); + } +#else + LLVMSharedModuleRef smod; + + LLVMSharedModuleRef smod; smod = LLVMOrcMakeSharedModule(context->module); if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &orc_handle, smod, llvm_resolve_symbol, NULL)) @@ -392,6 +409,7 @@ llvm_compile_module(LLVMJitContext *context) elog(ERROR, "failed to jit module"); } LLVMOrcDisposeSharedModuleRef(smod); +#endif INSTR_TIME_SET_CURRENT(tb); INSTR_TIME_SUBTRACT(tb, ta); ereport(DEBUG1, (errmsg("time to emit: %.3fs", -- 2.15.1
>From 079ad7087e2ab106c0f04fa9056c93afa9a43b7c Mon Sep 17 00:00:00 2001 From: Pierre <pierre.ducroq...@people-doc.com> Date: Fri, 2 Feb 2018 09:13:40 +0100 Subject: [PATCH 2/4] Add LLVM4 support in llvmjit_error.cpp --- src/backend/lib/llvmjit_error.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backend/lib/llvmjit_error.cpp b/src/backend/lib/llvmjit_error.cpp index 70cecd114b..04e51b2a31 100644 --- a/src/backend/lib/llvmjit_error.cpp +++ b/src/backend/lib/llvmjit_error.cpp @@ -56,7 +56,9 @@ llvm_enter_fatal_on_oom(void) 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++; @@ -72,7 +74,9 @@ llvm_leave_fatal_on_oom(void) 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(); } } @@ -87,7 +91,9 @@ llvm_reset_fatal_on_oom(void) 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; -- 2.15.1
>From 51cc99259dc28120309e2a99f8585907d0baae06 Mon Sep 17 00:00:00 2001 From: Pierre <pierre.ducroq...@people-doc.com> Date: Fri, 2 Feb 2018 09:23:56 +0100 Subject: [PATCH 3/4] Add LLVM4 support in llvmjit_inline.cpp --- src/backend/lib/llvmjit_inline.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/backend/lib/llvmjit_inline.cpp b/src/backend/lib/llvmjit_inline.cpp index 151198547a..8a747cbfc0 100644 --- a/src/backend/lib/llvmjit_inline.cpp +++ b/src/backend/lib/llvmjit_inline.cpp @@ -100,6 +100,13 @@ llvm_inline(LLVMModuleRef M) llvm_execute_inline_plan(mod, globalsToInline.get()); } +#if LLVM_VERSION_MAJOR < 5 +bool operator!(const llvm::ValueInfo &vi) { + return !( (vi.Kind == llvm::ValueInfo::VI_GUID && vi.TheValue.Id) + || (vi.Kind == llvm::ValueInfo::VI_Value && vi.TheValue.GV)); +} +#endif + /* * Build information necessary for inlining external function references in * mod. @@ -146,7 +153,14 @@ llvm_build_inline_plan(llvm::Module *mod) if (threshold == -1) continue; +#if LLVM_VERSION_MAJOR > 4 llvm::ValueInfo funcVI = llvm_index->getValueInfo(funcGUID); +#else + const llvm::const_gvsummary_iterator &I = llvm_index->findGlobalValueSummaryList(funcGUID); + if (I == llvm_index->end()) + continue; + llvm::ValueInfo funcVI = llvm::ValueInfo(I->first); +#endif /* if index doesn't know function, we don't have a body, continue */ if (!funcVI) @@ -157,7 +171,12 @@ llvm_build_inline_plan(llvm::Module *mod) * look up module(s), check if function actually is defined (there * could be hash conflicts). */ +#if LLVM_VERSION_MAJOR > 4 for (const auto &gvs : funcVI.getSummaryList()) +#else + auto it_gvs = llvm_index->findGlobalValueSummaryList(funcVI.getGUID()); + for (const auto &gvs: it_gvs->second) +#endif { const llvm::FunctionSummary *fs; llvm::StringRef modPath = gvs->modulePath(); @@ -318,9 +337,14 @@ llvm_execute_inline_plan(llvm::Module *mod, ImportMapTy *globalsToInline) } +#if LLVM_VERSION_MAJOR > 4 +#define IRMOVE_PARAMS , /*IsPerformingImport=*/false +#else +#define IRMOVE_PARAMS , /*LinkModuleInlineAsm=*/false, /*IsPerformingImport=*/false +#endif if (Mover.move(std::move(importMod), GlobalsToImport.getArrayRef(), - [](llvm::GlobalValue &, llvm::IRMover::ValueAdder) {}, - /*IsPerformingImport=*/false)) + [](llvm::GlobalValue &, llvm::IRMover::ValueAdder) {} + IRMOVE_PARAMS)) elog(ERROR, "function import failed with linker error"); } } @@ -619,9 +643,17 @@ llvm_load_index(void) elog(ERROR, "failed to open %s: %s", subpath, EC.message().c_str()); llvm::MemoryBufferRef ref(*MBOrErr.get().get()); +#if LLVM_VERSION_MAJOR > 4 llvm::Error e = llvm::readModuleSummaryIndex(ref, *index, 0); if (e) elog(ERROR, "could not load summary at %s", subpath); +#else + std::unique_ptr<llvm::ModuleSummaryIndex> subindex = std::move(llvm::getModuleSummaryIndex(ref).get()); + if (!subindex) + elog(ERROR, "could not load summary at %s", subpath); + else + index->mergeFrom(std::move(subindex), 0); +#endif } } -- 2.15.1
>From 77ee0a7bf15b2c962006b8a1d585f35830280eaf Mon Sep 17 00:00:00 2001 From: Pierre <pierre.ducroq...@people-doc.com> Date: Fri, 2 Feb 2018 10:34:09 +0100 Subject: [PATCH 4/4] Don't emit bitcode depending on an LLVM 5+ function --- src/backend/executor/execExprCompile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backend/executor/execExprCompile.c b/src/backend/executor/execExprCompile.c index 4d6304f748..d129ea7828 100644 --- a/src/backend/executor/execExprCompile.c +++ b/src/backend/executor/execExprCompile.c @@ -173,7 +173,11 @@ get_LifetimeEnd(LLVMModuleRef mod) LLVMTypeRef sig; LLVMValueRef fn; LLVMTypeRef param_types[2]; +#if LLVM_VERSION_MAJOR > 4 const char *nm = "llvm.lifetime.end.p0i8"; +#else + const char *nm = "llvm.lifetime.end"; +#endif fn = LLVMGetNamedFunction(mod, nm); if (fn) -- 2.15.1