aboutsummaryrefslogtreecommitdiff
path: root/src/backend/jit/llvm/llvmjit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/jit/llvm/llvmjit.c')
-rw-r--r--src/backend/jit/llvm/llvmjit.c193
1 files changed, 97 insertions, 96 deletions
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 67ebf6248e9..3867ec589d2 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -89,18 +89,12 @@ LLVMTypeRef StructExprState;
LLVMTypeRef StructAggState;
LLVMTypeRef StructAggStatePerGroupData;
LLVMTypeRef StructAggStatePerTransData;
+LLVMTypeRef StructPlanState;
LLVMValueRef AttributeTemplate;
-LLVMValueRef FuncStrlen;
-LLVMValueRef FuncVarsizeAny;
-LLVMValueRef FuncSlotGetsomeattrsInt;
-LLVMValueRef FuncSlotGetmissingattrs;
-LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
-LLVMValueRef FuncExecEvalSubscriptingRef;
-LLVMValueRef FuncExecEvalSysVar;
-LLVMValueRef FuncExecAggTransReparent;
-LLVMValueRef FuncExecAggInitGroup;
+LLVMValueRef ExecEvalSubroutineTemplate;
+LLVMModuleRef llvm_types_module = NULL;
static bool llvm_session_initialized = false;
static size_t llvm_generation = 0;
@@ -382,26 +376,71 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
}
/*
- * Return declaration for passed function, adding it to the module if
- * necessary.
+ * Return type of a variable in llvmjit_types.c. This is useful to keep types
+ * in sync between plain C and JIT related code.
+ */
+LLVMTypeRef
+llvm_pg_var_type(const char *varname)
+{
+ LLVMValueRef v_srcvar;
+ LLVMTypeRef typ;
+
+ /* this'll return a *pointer* to the global */
+ v_srcvar = LLVMGetNamedGlobal(llvm_types_module, varname);
+ if (!v_srcvar)
+ elog(ERROR, "variable %s not in llvmjit_types.c", varname);
+
+ typ = LLVMGlobalGetValueType(v_srcvar);
+
+ return typ;
+}
+
+/*
+ * Return function type of a variable in llvmjit_types.c. This is useful to
+ * keep function types in sync between C and JITed code.
+ */
+LLVMTypeRef
+llvm_pg_var_func_type(const char *varname)
+{
+ LLVMValueRef v_srcvar;
+ LLVMTypeRef typ;
+
+ v_srcvar = LLVMGetNamedFunction(llvm_types_module, varname);
+ if (!v_srcvar)
+ elog(ERROR, "function %s not in llvmjit_types.c", varname);
+
+ typ = LLVMGetFunctionType(v_srcvar);
+
+ return typ;
+}
+
+/*
+ * Return declaration for a function referenced in llvmjit_types.c, adding it
+ * to the module if necessary.
*
- * This is used to make functions imported by llvm_create_types() known to the
- * module that's currently being worked on.
+ * This is used to make functions discovered via llvm_create_types() known to
+ * the module that's currently being worked on.
*/
LLVMValueRef
-llvm_get_decl(LLVMModuleRef mod, LLVMValueRef v_src)
+llvm_pg_func(LLVMModuleRef mod, const char *funcname)
{
+ LLVMValueRef v_srcfn;
LLVMValueRef v_fn;
/* don't repeatedly add function */
- v_fn = LLVMGetNamedFunction(mod, LLVMGetValueName(v_src));
+ v_fn = LLVMGetNamedFunction(mod, funcname);
if (v_fn)
return v_fn;
+ v_srcfn = LLVMGetNamedFunction(llvm_types_module, funcname);
+
+ if (!v_srcfn)
+ elog(ERROR, "function %s not in llvmjit_types.c", funcname);
+
v_fn = LLVMAddFunction(mod,
- LLVMGetValueName(v_src),
- LLVMGetElementType(LLVMTypeOf(v_src)));
- llvm_copy_attributes(v_src, v_fn);
+ funcname,
+ LLVMGetFunctionType(v_srcfn));
+ llvm_copy_attributes(v_srcfn, v_fn);
return v_fn;
}
@@ -496,7 +535,7 @@ llvm_function_reference(LLVMJitContext *context,
fcinfo->flinfo->fn_oid);
v_fn = LLVMGetNamedGlobal(mod, funcname);
if (v_fn != 0)
- return LLVMBuildLoad(builder, v_fn, "");
+ return l_load(builder, TypePGFunction, v_fn, "");
v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
@@ -506,7 +545,7 @@ llvm_function_reference(LLVMJitContext *context,
LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
LLVMSetUnnamedAddr(v_fn, true);
- return LLVMBuildLoad(builder, v_fn, "");
+ return l_load(builder, TypePGFunction, v_fn, "");
}
/* check if function already has been added */
@@ -514,7 +553,7 @@ llvm_function_reference(LLVMJitContext *context,
if (v_fn != 0)
return v_fn;
- v_fn = LLVMAddFunction(mod, funcname, LLVMGetElementType(TypePGFunction));
+ v_fn = LLVMAddFunction(mod, funcname, LLVMGetFunctionType(AttributeTemplate));
return v_fn;
}
@@ -766,12 +805,15 @@ llvm_session_initialize(void)
LLVMInitializeNativeAsmParser();
/*
- * When targeting an LLVM version with opaque pointers enabled by
- * default, turn them off for the context we build our code in. We don't
- * need to do so for other contexts (e.g. llvm_ts_context). Once the IR is
- * generated, it carries the necessary information.
+ * When targeting LLVM 15, turn off opaque pointers for the context we
+ * build our code in. We don't need to do so for other contexts (e.g.
+ * llvm_ts_context). Once the IR is generated, it carries the necessary
+ * information.
+ *
+ * For 16 and above, opaque pointers must be used, and we have special
+ * code for that.
*/
-#if LLVM_VERSION_MAJOR > 14
+#if LLVM_VERSION_MAJOR == 15
LLVMContextSetOpaquePointers(LLVMGetGlobalContext(), false);
#endif
@@ -921,26 +963,6 @@ llvm_shutdown(int code, Datum arg)
#endif /* LLVM_VERSION_MAJOR > 11 */
}
-/* helper for llvm_create_types, returning a global var's type */
-static LLVMTypeRef
-load_type(LLVMModuleRef mod, const char *name)
-{
- LLVMValueRef value;
- LLVMTypeRef typ;
-
- /* this'll return a *pointer* to the global */
- value = LLVMGetNamedGlobal(mod, name);
- if (!value)
- elog(ERROR, "type %s is unknown", name);
-
- /* therefore look at the contained type and return that */
- typ = LLVMTypeOf(value);
- Assert(typ != NULL);
- typ = LLVMGetElementType(typ);
- Assert(typ != NULL);
- return typ;
-}
-
/* helper for llvm_create_types, returning a function's return type */
static LLVMTypeRef
load_return_type(LLVMModuleRef mod, const char *name)
@@ -953,15 +975,7 @@ load_return_type(LLVMModuleRef mod, const char *name)
if (!value)
elog(ERROR, "function %s is unknown", name);
- /* get type of function pointer */
- typ = LLVMTypeOf(value);
- Assert(typ != NULL);
- /* dereference pointer */
- typ = LLVMGetElementType(typ);
- Assert(typ != NULL);
- /* and look at return type */
- typ = LLVMGetReturnType(typ);
- Assert(typ != NULL);
+ typ = LLVMGetFunctionReturnType(value); /* in llvmjit_wrap.cpp */
return typ;
}
@@ -978,7 +992,6 @@ llvm_create_types(void)
char path[MAXPGPATH];
LLVMMemoryBufferRef buf;
char *msg;
- LLVMModuleRef mod = NULL;
snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
@@ -990,7 +1003,7 @@ llvm_create_types(void)
}
/* eagerly load contents, going to need it all */
- if (LLVMParseBitcode2(buf, &mod))
+ if (LLVMParseBitcode2(buf, &llvm_types_module))
{
elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
}
@@ -1000,45 +1013,33 @@ llvm_create_types(void)
* Load triple & layout from clang emitted file so we're guaranteed to be
* compatible.
*/
- llvm_triple = pstrdup(LLVMGetTarget(mod));
- llvm_layout = pstrdup(LLVMGetDataLayoutStr(mod));
-
- TypeSizeT = load_type(mod, "TypeSizeT");
- TypeParamBool = load_return_type(mod, "FunctionReturningBool");
- TypeStorageBool = load_type(mod, "TypeStorageBool");
- TypePGFunction = load_type(mod, "TypePGFunction");
- StructNullableDatum = load_type(mod, "StructNullableDatum");
- StructExprContext = load_type(mod, "StructExprContext");
- StructExprEvalStep = load_type(mod, "StructExprEvalStep");
- StructExprState = load_type(mod, "StructExprState");
- StructFunctionCallInfoData = load_type(mod, "StructFunctionCallInfoData");
- StructMemoryContextData = load_type(mod, "StructMemoryContextData");
- StructTupleTableSlot = load_type(mod, "StructTupleTableSlot");
- StructHeapTupleTableSlot = load_type(mod, "StructHeapTupleTableSlot");
- StructMinimalTupleTableSlot = load_type(mod, "StructMinimalTupleTableSlot");
- StructHeapTupleData = load_type(mod, "StructHeapTupleData");
- StructTupleDescData = load_type(mod, "StructTupleDescData");
- StructAggState = load_type(mod, "StructAggState");
- StructAggStatePerGroupData = load_type(mod, "StructAggStatePerGroupData");
- StructAggStatePerTransData = load_type(mod, "StructAggStatePerTransData");
-
- AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate");
- FuncStrlen = LLVMGetNamedFunction(mod, "strlen");
- FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any");
- FuncSlotGetsomeattrsInt = LLVMGetNamedFunction(mod, "slot_getsomeattrs_int");
- FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs");
- FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");
- FuncExecEvalSubscriptingRef = LLVMGetNamedFunction(mod, "ExecEvalSubscriptingRef");
- FuncExecEvalSysVar = LLVMGetNamedFunction(mod, "ExecEvalSysVar");
- FuncExecAggTransReparent = LLVMGetNamedFunction(mod, "ExecAggTransReparent");
- FuncExecAggInitGroup = LLVMGetNamedFunction(mod, "ExecAggInitGroup");
-
- /*
- * Leave the module alive, otherwise references to function would be
- * dangling.
- */
-
- return;
+ llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
+ llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
+
+ TypeSizeT = llvm_pg_var_type("TypeSizeT");
+ TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
+ TypeStorageBool = llvm_pg_var_type("TypeStorageBool");
+ TypePGFunction = llvm_pg_var_type("TypePGFunction");
+ StructNullableDatum = llvm_pg_var_type("StructNullableDatum");
+ StructExprContext = llvm_pg_var_type("StructExprContext");
+ StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
+ StructExprState = llvm_pg_var_type("StructExprState");
+ StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
+ StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
+ StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
+ StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
+ StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot");
+ StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData");
+ StructHeapTupleHeaderData = llvm_pg_var_type("StructHeapTupleHeaderData");
+ StructTupleDescData = llvm_pg_var_type("StructTupleDescData");
+ StructAggState = llvm_pg_var_type("StructAggState");
+ StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
+ StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
+ StructPlanState = llvm_pg_var_type("StructPlanState");
+ StructMinimalTupleData = llvm_pg_var_type("StructMinimalTupleData");
+
+ AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
+ ExecEvalSubroutineTemplate = LLVMGetNamedFunction(llvm_types_module, "ExecEvalSubroutineTemplate");
}
/*