summaryrefslogtreecommitdiff
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.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index eaede90cca0..21d36605a48 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -14,6 +14,7 @@
#include "postgres.h"
#include "jit/llvmjit.h"
+#include "jit/llvmjit_emit.h"
#include "miscadmin.h"
@@ -114,6 +115,7 @@ _PG_jit_provider_init(JitProviderCallbacks *cb)
{
cb->reset_after_error = llvm_reset_after_error;
cb->release_context = llvm_release_context;
+ cb->compile_expr = llvm_compile_expr;
}
/*
@@ -340,6 +342,68 @@ llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
}
/*
+ * Return a callable LLVMValueRef for fcinfo.
+ */
+LLVMValueRef
+llvm_function_reference(LLVMJitContext *context,
+ LLVMBuilderRef builder,
+ LLVMModuleRef mod,
+ FunctionCallInfo fcinfo)
+{
+ char *modname;
+ char *basename;
+ char *funcname;
+
+ LLVMValueRef v_fn;
+
+ fmgr_symbol(fcinfo->flinfo->fn_oid, &modname, &basename);
+
+ if (modname != NULL && basename != NULL)
+ {
+ /* external function in loadable library */
+ funcname = psprintf("pgextern.%s.%s", modname, basename);
+ }
+ else if (basename != NULL)
+ {
+ /* internal function */
+ funcname = psprintf("%s", basename);
+ }
+ else
+ {
+ /*
+ * Function we don't know to handle, return pointer. We do so by
+ * creating a global constant containing a pointer to the function.
+ * Makes IR more readable.
+ */
+ LLVMValueRef v_fn_addr;
+
+ funcname = psprintf("pgoidextern.%u",
+ fcinfo->flinfo->fn_oid);
+ v_fn = LLVMGetNamedGlobal(mod, funcname);
+ if (v_fn != 0)
+ return LLVMBuildLoad(builder, v_fn, "");
+
+ v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
+
+ v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
+ LLVMSetInitializer(v_fn, v_fn_addr);
+ LLVMSetGlobalConstant(v_fn, true);
+
+ return LLVMBuildLoad(builder, v_fn, "");
+ return v_fn;
+ }
+
+ /* check if function already has been added */
+ v_fn = LLVMGetNamedFunction(mod, funcname);
+ if (v_fn != 0)
+ return v_fn;
+
+ v_fn = LLVMAddFunction(mod, funcname, LLVMGetElementType(TypePGFunction));
+
+ return v_fn;
+}
+
+/*
* Optimize code in module using the flags set in context.
*/
static void