diff options
author | Andres Freund | 2020-10-19 22:53:37 +0000 |
---|---|---|
committer | Andres Freund | 2020-10-20 00:28:21 +0000 |
commit | a639edc964e03bfd1b7018266bc1e51059b849af (patch) | |
tree | 78b30ddac97b2b89d800617084ca6cd7ff046fce | |
parent | 8e5793ab60bba65ffaa0f2237b39c9580d8972c7 (diff) |
WIP: llvmjit: Support new ORC interface.llvm-12
Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
-rw-r--r-- | src/backend/jit/llvm/llvmjit.c | 310 |
1 files changed, 290 insertions, 20 deletions
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index 4c026d37d0..4ebfc3c410 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -18,7 +18,13 @@ #include <llvm-c/BitWriter.h> #include <llvm-c/Core.h> #include <llvm-c/ExecutionEngine.h> +#if LLVM_VERSION_MAJOR > 11 +#include <llvm-c/Orc.h> +#include <llvm-c/OrcEE.h> +#include <llvm-c/LLJIT.h> +#else #include <llvm-c/OrcBindings.h> +#endif #include <llvm-c/Support.h> #include <llvm-c/Target.h> #include <llvm-c/Transforms/IPO.h> @@ -39,8 +45,13 @@ /* Handle of a module emitted via ORC JIT */ typedef struct LLVMJitHandle { +#if LLVM_VERSION_MAJOR > 11 + LLVMOrcLLJITRef lljit; + LLVMOrcResourceTrackerRef rt; +#else LLVMOrcJITStackRef stack; LLVMOrcModuleHandle orc_handle; +#endif } LLVMJitHandle; @@ -89,9 +100,14 @@ static LLVMTargetMachineRef llvm_opt0_targetmachine; static LLVMTargetMachineRef llvm_opt3_targetmachine; static LLVMTargetRef llvm_targetref; +#if LLVM_VERSION_MAJOR > 11 +static LLVMOrcThreadSafeContextRef llvm_ts_context; +static LLVMOrcLLJITRef llvm_opt0_orc; +static LLVMOrcLLJITRef llvm_opt3_orc; +#else static LLVMOrcJITStackRef llvm_opt0_orc; static LLVMOrcJITStackRef llvm_opt3_orc; - +#endif static void llvm_release_context(JitContext *context); static void llvm_session_initialize(void); @@ -176,7 +192,16 @@ llvm_release_context(JitContext *context) jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles); llvm_context->handles = list_delete_first(llvm_context->handles); +#if LLVM_VERSION_MAJOR > 11 + LLVMOrcResourceTrackerRemove(jit_handle->rt); + LLVMOrcReleaseResourceTracker(jit_handle->rt); + jit_handle->rt = NULL; + + LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcExecutionSessionGetSymbolStringPool( + LLVMOrcLLJITGetExecutionSession(jit_handle->lljit))); +#else LLVMOrcRemoveModule(jit_handle->stack, jit_handle->orc_handle); +#endif pfree(jit_handle); } } @@ -234,8 +259,15 @@ llvm_expand_funcname(struct LLVMJitContext *context, const char *basename) void * llvm_get_function(LLVMJitContext *context, const char *funcname) { +#if LLVM_VERSION_MAJOR > 11 + LLVMOrcJITTargetAddress addr = 0; + instr_time starttime; + instr_time endtime; +#else LLVMOrcTargetAddress addr = 0; -#if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN +#endif + +#if LLVM_VERSION_MAJOR > 11 || defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN ListCell *lc; #endif @@ -255,7 +287,34 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) * to mangle here. */ -#if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN +#if LLVM_VERSION_MAJOR > 11 + foreach(lc, context->handles) + { + LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc); + LLVMErrorRef error; + + INSTR_TIME_SET_CURRENT(starttime); + + addr = 0; + error = LLVMOrcLLJITLookup(handle->lljit, &addr, funcname); + if (error) + { + char *llvmerrmsg_orig = LLVMGetErrorMessage(error); + char *llvmerrmsg = pstrdup(llvmerrmsg_orig); + + LLVMDisposeErrorMessage(llvmerrmsg_orig); + elog(ERROR, "failed to look up symbol \"%s\": %s", funcname, llvmerrmsg); + } + + INSTR_TIME_SET_CURRENT(endtime); + INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter, + endtime, starttime); + + if (addr) + return (void *) (uintptr_t) addr; + } + +#elif defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN foreach(lc, context->handles) { LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc); @@ -270,19 +329,23 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) #else #if LLVM_VERSION_MAJOR < 5 - if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname))) - return (void *) (uintptr_t) addr; - if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname))) - return (void *) (uintptr_t) 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 - 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; + { + 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 /* LLVM_VERSION_MAJOR */ #endif /* HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN */ @@ -420,6 +483,8 @@ llvm_function_reference(LLVMJitContext *context, v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname); LLVMSetInitializer(v_fn, v_fn_addr); LLVMSetGlobalConstant(v_fn, true); + LLVMSetLinkage(v_fn, LLVMPrivateLinkage); + LLVMSetUnnamedAddr(v_fn, true); return LLVMBuildLoad(builder, v_fn, ""); } @@ -511,9 +576,14 @@ llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module) static void llvm_compile_module(LLVMJitContext *context) { - LLVMOrcModuleHandle orc_handle; MemoryContext oldcontext; - static LLVMOrcJITStackRef compile_orc; +#if LLVM_VERSION_MAJOR > 11 + LLVMOrcLLJITRef compile_orc; + LLVMOrcResourceTrackerRef rt; +#else + LLVMOrcModuleHandle orc_handle; + LLVMOrcJITStackRef compile_orc; +#endif instr_time starttime; instr_time endtime; @@ -569,7 +639,27 @@ llvm_compile_module(LLVMJitContext *context) * faster instruction selection mechanism is used. */ INSTR_TIME_SET_CURRENT(starttime); -#if LLVM_VERSION_MAJOR > 6 +#if LLVM_VERSION_MAJOR > 11 + { + LLVMOrcThreadSafeModuleRef ts_module; + LLVMErrorRef error; + LLVMOrcJITDylibRef jd = LLVMOrcLLJITGetMainJITDylib(compile_orc); + + ts_module = LLVMOrcCreateNewThreadSafeModule(context->module, llvm_ts_context); + context->module = NULL; + rt = LLVMOrcJITDylibCreateResourceTracker(jd); + error = LLVMOrcLLJITAddLLVMIRModuleWithRT(compile_orc, rt, ts_module); + + if (error) + { + char *llvmerrmsg_orig = LLVMGetErrorMessage(error); + char *llvmerrmsg = pstrdup(llvmerrmsg_orig); + + LLVMDisposeErrorMessage(llvmerrmsg_orig); + elog(ERROR, "failed to JIT module: %s", llvmerrmsg); + } + } +#elif LLVM_VERSION_MAJOR > 6 { if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &orc_handle, context->module, llvm_resolve_symbol, NULL)) @@ -611,9 +701,13 @@ llvm_compile_module(LLVMJitContext *context) LLVMJitHandle *handle; handle = (LLVMJitHandle *) palloc(sizeof(LLVMJitHandle)); +#if LLVM_VERSION_MAJOR > 11 + handle->lljit = compile_orc; + handle->rt = rt; +#else handle->stack = compile_orc; handle->orc_handle = orc_handle; - +#endif context->handles = lappend(context->handles, handle); } MemoryContextSwitchTo(oldcontext); @@ -627,6 +721,72 @@ llvm_compile_module(LLVMJitContext *context) errhidecontext(true))); } +#if LLVM_VERSION_MAJOR > 11 +static void +llvm_report_jit_error(void *ctx, LLVMErrorRef error) +{ + char *msg = LLVMGetErrorMessage(error); + + elog(WARNING, "error during JITing: %s", msg); + LLVMDisposeErrorMessage(msg); +} + +static LLVMErrorRef +llvmjit_resolve_symbols(LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx, + LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind, + LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags, + LLVMOrcCLookupSet LookupSet, size_t LookupSetSize) +{ + LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMJITCSymbolMapPair) * LookupSetSize); + LLVMErrorRef error; + LLVMOrcMaterializationUnitRef mu; + + for (int i = 0; i < LookupSetSize; i++) + { + const char *Name = LLVMOrcSymbolStringPoolEntryStr(LookupSet[i].Name); + elog(LOG, "looking up %s", Name); + symbols[i].Name = LookupSet[i].Name; + symbols[i].Sym.Address = llvm_resolve_symbol(Name, NULL); + symbols[i].Sym.Flags.GenericFlags = LLVMJITSymbolGenericFlagsExported; + } + + mu = LLVMOrcAbsoluteSymbols(symbols, LookupSetSize); + error = LLVMOrcJITDylibDefine(JD, mu); + if (error != LLVMErrorSuccess) + LLVMOrcDisposeMaterializationUnit(mu); + + pfree(symbols); + return error; +} + +static LLVMOrcObjectLayerRef +llvm_create_object_layer(void *Ctx, LLVMOrcExecutionSessionRef ES, const char *Triple) +{ + LLVMOrcObjectLayerRef objlayer = + LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(ES); + + if (jit_debugging_support) + { + LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener(); + + LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l); + } + +#if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER + if (jit_profiling_support) + { + LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener(); + + LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l); + } +#endif + + return objlayer; +} + +#endif + + /* * Per session initialization. */ @@ -688,6 +848,101 @@ llvm_session_initialize(void) /* force symbols in main binary to be loaded */ LLVMLoadLibraryPermanently(NULL); +#if LLVM_VERSION_MAJOR > 11 + { + LLVMOrcJITTargetMachineBuilderRef tm_builder; + LLVMOrcLLJITBuilderRef lljit_builder; + LLVMErrorRef error; + LLVMOrcDefinitionGeneratorRef def_gen; + + llvm_ts_context = LLVMOrcCreateNewThreadSafeContext(); + + /* + * Fixme: deduplicate + */ + + lljit_builder = LLVMOrcCreateLLJITBuilder(); + tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(llvm_opt0_targetmachine); + llvm_opt0_targetmachine = NULL; + LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(lljit_builder, tm_builder); + + LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(lljit_builder, + llvm_create_object_layer, NULL); + + error = LLVMOrcCreateLLJIT(&llvm_opt0_orc, lljit_builder); + if (error) + { + char *llvmerrmsg_orig = LLVMGetErrorMessage(error); + char *llvmerrmsg = pstrdup(llvmerrmsg_orig); + + LLVMDisposeErrorMessage(llvmerrmsg_orig); + elog(ERROR, "failed to create lljit: %s", llvmerrmsg); + } + + LLVMOrcExecutionSessionSetErrorReporter( + LLVMOrcLLJITGetExecutionSession(llvm_opt0_orc), + llvm_report_jit_error, NULL); + + error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(&def_gen, + LLVMOrcLLJITGetGlobalPrefix(llvm_opt0_orc), + 0, NULL); + if (error) + { + char *llvmerrmsg_orig = LLVMGetErrorMessage(error); + char *llvmerrmsg = pstrdup(llvmerrmsg_orig); + + LLVMDisposeErrorMessage(llvmerrmsg_orig); + elog(ERROR, "failed to create generator: %s", llvmerrmsg); + } + + LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(llvm_opt0_orc), def_gen); + def_gen = NULL; + + def_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvmjit_resolve_symbols, NULL); + LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(llvm_opt0_orc), def_gen); + def_gen = NULL; + + + lljit_builder = LLVMOrcCreateLLJITBuilder(); + tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(llvm_opt3_targetmachine); + llvm_opt3_targetmachine = NULL; + LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(lljit_builder, tm_builder); + + error = LLVMOrcCreateLLJIT(&llvm_opt3_orc, lljit_builder); + if (error) + { + char *llvmerrmsg_orig = LLVMGetErrorMessage(error); + char *llvmerrmsg = pstrdup(llvmerrmsg_orig); + + LLVMDisposeErrorMessage(llvmerrmsg_orig); + elog(ERROR, "failed to create lljit: %s", llvmerrmsg); + } + + + LLVMOrcExecutionSessionSetErrorReporter( + LLVMOrcLLJITGetExecutionSession(llvm_opt3_orc), + llvm_report_jit_error, NULL); + + error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(&def_gen, + LLVMOrcLLJITGetGlobalPrefix(llvm_opt3_orc), + 0, NULL); + if (error) + { + char *llvmerrmsg_orig = LLVMGetErrorMessage(error); + char *llvmerrmsg = pstrdup(llvmerrmsg_orig); + + LLVMDisposeErrorMessage(llvmerrmsg_orig); + elog(ERROR, "failed to create generator: %s", llvmerrmsg); + } + LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(llvm_opt3_orc), def_gen); + def_gen = NULL; + + def_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvmjit_resolve_symbols, NULL); + LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(llvm_opt3_orc), def_gen); + def_gen = NULL; + } +#else + llvm_opt0_orc = LLVMOrcCreateInstance(llvm_opt0_targetmachine); llvm_opt3_orc = LLVMOrcCreateInstance(llvm_opt3_targetmachine); @@ -710,6 +965,8 @@ llvm_session_initialize(void) } #endif +#endif /* LLVM_VERSION_MAJOR > 11 */ + on_proc_exit(llvm_shutdown, 0); llvm_session_initialized = true; @@ -721,14 +978,18 @@ static void llvm_shutdown(int code, Datum arg) { /* unregister profiling support, needs to be flushed to be useful */ - if (llvm_opt3_orc) { #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF if (jit_profiling_support) LLVMOrcUnregisterPerf(llvm_opt3_orc); #endif + +#if LLVM_VERSION_MAJOR > 11 + LLVMOrcDisposeLLJIT(llvm_opt3_orc); +#else LLVMOrcDisposeInstance(llvm_opt3_orc); +#endif llvm_opt3_orc = NULL; } @@ -738,9 +999,18 @@ llvm_shutdown(int code, Datum arg) if (jit_profiling_support) LLVMOrcUnregisterPerf(llvm_opt0_orc); #endif + +#if LLVM_VERSION_MAJOR > 11 + LLVMOrcDisposeLLJIT(llvm_opt0_orc); +#else LLVMOrcDisposeInstance(llvm_opt0_orc); +#endif llvm_opt0_orc = NULL; } + +#if LLVM_VERSION_MAJOR > 11 + LLVMOrcDisposeThreadSafeContext(llvm_ts_context); +#endif } /* helper for llvm_create_types, returning a global var's type */ |