summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/jit/llvm/llvmjit.c310
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 */