PoC. The saving of the compiled jit-code in the plan cache
Dear colleagues,
I implemented the patch to store in the plan cache an already compiled
jit
code. If a query is executed many times, the query time can be decreased
by
20-30% for long queries with big share of expressions in the code.
This patch can be applied to the current master and passes tests, but it
is
only the Proof of the Concept, and I need to get opinions and advice for
nexts
steps. It is not ready for commitfest, does not cover all scenarios
(craches
in some sutuation that need special solution), and source code is not
clean.
The code source has removed old code marked by // comments to easier
compare,
what was changed, especially in llvmjit_expr.c and llvmjit_deform.c
Implementation details.
1. Changes in jit-code generation.
a) the load of the absolute address (as const) changed to the load of
this
address from a struct member:
old version:
v_resvaluep = l_ptr_const(op->resvalue, l_ptr(TypeSizeT));
new version
v_resvaluep = l_load_struct_gep( b, g->StructExprEvalStep, v_op,
FIELDNO_EXPREVALSTEP_RESVALUE, "v_resvaluep");
b) the load of the absolute address or the value from union changed to
the load of the union value using the offset of the union member
old version
fcinfo - the union member value
v_fcinfo = l_ptr_const(fcinfo, l_ptr(g->StructFunctionCallInfoData));
new version
v_fcinfo = l_load_member_value_by_offset(b,lc, v_op,
l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep,
d.func.fcinfo_data ));
c) every cached plan has own LLVM-context and 1 module in it. As result,
some functions require context parameter to correctly address it instead
of the global llvm_context variable.
d) llvm_types moved from global variables to the struct LLVMJitTypes.
Not cached queries use old setup, but all types definitions are stored
in global struct LLVMJitTypes llvm_jit_types_struct, instead of many
global variables. Chached queries allocate struct LLVMJitTypes during
query
executon, and pfree it when cached plan is deallocated. llvm_types
module is
read for every cached statement (not 1 time during global context
creation).
e) llvm_function_reference still uses l_ptr_const with the absolute
address
of the function, it needs to be checked, as the function can change
address.
f) new GUC variabe jit_cached is added, off by default.
2. Changes in cached plan.
To store cached context I use struct PlannedStmt (in ExprState
state->parent->state->es_plannedstmt).
New member struct CachedJitContext *jit_context added to store
information
about jit context. In new plans this field in NULL. If plan is stored to
cache,
it filled by CACHED_JITCONTEXT_EMPTY and replaced by actual jit context
pointer
in llvmjit_expr.c .
When cached plan is deallocated, this member used to free jit resources
and
memory.
3. Current problems.
When module is compiled, it needs to connect ExprState and function
addresses.
In old implementation funcname is stored in ExprState.
In cached implementation the fuction will be called second and more
times,
and calling code does not have information about function name for
ExprState.
a) The current cached implementation uses the number of the call to
connect
f.e. 1st expresion and 1st function. It does not work for queries, that
generates an expression after module compilation (f.e. HashJoin) and
tries
to compile it.
b) Also query with aggregate functions generates an expresion every
time, when
executed. It work with current approach, but these expressions should be
considered, as they have different expression address every time.
One of the solution for a) and b) - generate jit-code for Expr pointers
only
in cached plan. Every new created expression either should be ignored by
the compiler and executed by the standard interpreter, or compiled in
the
standard (not cached) jit (it will run compilation every query run and
eliminate all gain from jit-cache).
c) new jit-code generation (use the stuct member instead of the direct
absolute address) slightly decreases the jit-code performance. It is
possible
to compile old version for not cached queries, and new code for cached
queries.
In this case two big 3000 lines funtions llvm_compile_expr() need to be
maintained in similar way, when new expresiions or features are added.
Attached files have
1) the patch (branched from 83ea6c54025bea67bcd4949a6d58d3fc11c3e21b
master),
2 and 3) benchmark files jitinit.sql to create jitbench database and
bash
script jitbench.sh (change to own user and password if you need) to run
banchmark.
4) chart for this benchmark and the query in the benchmark (comparison
with jit=off as 1 unit). It is easy to find query, where jit is higher
or
lower than jit-off. Here I demonstate the difference of standard and new
jit-code (the decrease of the performance with compilation without
optimization), and high gain of cached version with optimization and
high lost of not cached version with optimization due to the running
of the optimization for every the query.
--
Best regards,
Vladlen Popolitov.
Attachments:
v4-0001-jit-saved-for-cached-plans.patchtext/x-diff; name=v4-0001-jit-saved-for-cached-plans.patchDownload
From a3be11abb36120ba25aaa0dd8eff26ae84fadaa7 Mon Sep 17 00:00:00 2001
From: Vladlen Popolitov <v.popolitov@postgrespro.ru>
Date: Wed, 12 Feb 2025 21:41:48 +0700
Subject: [PATCH v4] jit saved for cached plans
---
src/backend/jit/jit.c | 1 +
src/backend/jit/llvm/llvmjit.c | 202 +++--
src/backend/jit/llvm/llvmjit_deform.c | 88 +-
src/backend/jit/llvm/llvmjit_expr.c | 1065 +++++++++++++++----------
src/backend/jit/llvm/llvmjit_types.c | 1 +
src/backend/nodes/copyfuncs.c | 3 +
src/backend/nodes/equalfuncs.c | 6 +
src/backend/nodes/gen_node_support.pl | 13 +
src/backend/nodes/outfuncs.c | 4 +
src/backend/nodes/readfuncs.c | 6 +
src/backend/utils/cache/plancache.c | 19 +
src/backend/utils/misc/guc_tables.c | 12 +
src/include/executor/execExpr.h | 2 +
src/include/jit/jit.h | 1 +
src/include/jit/llvmjit.h | 91 ++-
src/include/jit/llvmjit_emit.h | 74 +-
src/include/nodes/execnodes.h | 3 +
src/include/nodes/plannodes.h | 4 +-
18 files changed, 1039 insertions(+), 556 deletions(-)
diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c
index d2ccef9de85..3927f7c5f73 100644
--- a/src/backend/jit/jit.c
+++ b/src/backend/jit/jit.c
@@ -30,6 +30,7 @@
/* GUCs */
bool jit_enabled = true;
+bool jit_cached = false;
char *jit_provider = NULL;
bool jit_debugging_support = false;
bool jit_dump_bitcode = false;
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 614926720fb..e34fa2b11e7 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -53,6 +53,7 @@ typedef struct LLVMJitHandle
/* types & functions commonly needed for JITing */
+/*
LLVMTypeRef TypeSizeT;
LLVMTypeRef TypeParamBool;
LLVMTypeRef TypeStorageBool;
@@ -74,10 +75,14 @@ LLVMTypeRef StructAggState;
LLVMTypeRef StructAggStatePerGroupData;
LLVMTypeRef StructAggStatePerTransData;
LLVMTypeRef StructPlanState;
+LLVMTypeRef StructWindowFuncExprState;
LLVMValueRef AttributeTemplate;
LLVMValueRef ExecEvalSubroutineTemplate;
LLVMValueRef ExecEvalBoolSubroutineTemplate;
+*/
+char * llvm_expand_funcname_general(struct LLVMJitContext *context, const char *basename, int *counter);
+LLVMJitTypes llvm_jit_types_struct;
static LLVMModuleRef llvm_types_module = NULL;
@@ -99,7 +104,8 @@ static LLVMOrcThreadSafeContextRef llvm_ts_context;
static LLVMOrcLLJITRef llvm_opt0_orc;
static LLVMOrcLLJITRef llvm_opt3_orc;
-
+static void llvm_create_types_context(LLVMJitTypes *jit_types_struct,
+ LLVMModuleRef *llvm_types_module, LLVMContextRef llvm_context);
static void llvm_release_context(JitContext *context);
static void llvm_session_initialize(void);
static void llvm_shutdown(int code, Datum arg);
@@ -232,6 +238,8 @@ llvm_create_context(int jitFlags)
context = MemoryContextAllocZero(TopMemoryContext,
sizeof(LLVMJitContext));
context->base.flags = jitFlags;
+ context->jit_types = &llvm_jit_types_struct;
+ context->llvm_types_module = llvm_types_module;
/* ensure cleanup */
context->resowner = CurrentResourceOwner;
@@ -242,6 +250,51 @@ llvm_create_context(int jitFlags)
return context;
}
+/*
+ * Create a cached context for JITing work.
+ *
+ * The context, including subsidiary resources, will be cleaned up either when
+ * the context is explicitly released.
+ */
+LLVMJitContext *
+llvm_create_cached_context(int jitFlags)
+{
+ LLVMJitContext *context;
+
+ llvm_assert_in_fatal_section();
+
+ llvm_session_initialize();
+
+ context = MemoryContextAllocZero(TopMemoryContext,
+ sizeof(LLVMJitContext));
+ context->base.flags = jitFlags;
+ context->llvm_context = LLVMContextCreate();
+ context->jit_types = MemoryContextAllocZero(TopMemoryContext,
+ sizeof(LLVMJitTypes));
+
+
+
+ /// llvm_recreate_llvm_context();
+ /*
+ * Synchronize types early, as that also includes inferring the target
+ * triple.
+ */
+ llvm_create_types_context(context->jit_types, &context->llvm_types_module, context->llvm_context);
+
+ ///ResourceOwnerEnlarge(CurrentResourceOwner);
+
+
+
+ /* ensure cleanup */
+ ///context->resowner = CurrentResourceOwner;
+ ///ResourceOwnerRememberJIT(CurrentResourceOwner, context);
+
+ llvm_jit_context_in_use_count++;
+
+ return context;
+}
+
+
/*
* Release resources required by one llvm context.
*/
@@ -272,6 +325,11 @@ llvm_release_context(JitContext *context)
LLVMDisposeModule(llvm_jit_context->module);
llvm_jit_context->module = NULL;
}
+ if (llvm_jit_context->llvm_context && llvm_jit_context->llvm_types_module)
+ {
+ LLVMDisposeModule(llvm_jit_context->llvm_types_module);
+ llvm_jit_context->llvm_types_module = NULL;
+ }
foreach(lc, llvm_jit_context->handles)
{
@@ -304,6 +362,12 @@ llvm_release_context(JitContext *context)
if (llvm_jit_context->resowner)
ResourceOwnerForgetJIT(llvm_jit_context->resowner, llvm_jit_context);
+
+ if (llvm_jit_context->llvm_context)
+ {
+ LLVMContextDispose(llvm_context);
+ llvm_jit_context->llvm_context = NULL;
+ }
}
/*
@@ -321,7 +385,8 @@ llvm_mutable_module(LLVMJitContext *context)
{
context->compiled = false;
context->module_generation = llvm_generation++;
- context->module = LLVMModuleCreateWithNameInContext("pg", llvm_context);
+ context->module = LLVMModuleCreateWithNameInContext("pg",
+ context->llvm_context? context->llvm_context : llvm_context);
LLVMSetTarget(context->module, llvm_triple);
LLVMSetDataLayout(context->module, llvm_layout);
}
@@ -335,9 +400,9 @@ llvm_mutable_module(LLVMJitContext *context)
* a Module.
*/
char *
-llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
+llvm_expand_funcname_general(struct LLVMJitContext *context, const char *basename, int *counter)
{
- Assert(context->module != NULL);
+ ///Assert(context->module != NULL);
context->base.instr.created_functions++;
@@ -348,9 +413,18 @@ llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
return psprintf("%s_%zu_%d",
basename,
context->module_generation,
- context->counter++);
+ (*counter)++);
+}
+char *
+llvm_expand_funcname_expr(struct LLVMJitContext *context, const char *basename)
+{
+ return llvm_expand_funcname_general(context, basename, &context->counter_expr);
+}
+char *
+llvm_expand_funcname_deform(struct LLVMJitContext *context, const char *basename)
+{
+ return llvm_expand_funcname_general(context, basename, &context->counter_deform);
}
-
/*
* Return pointer to function funcname, which has to exist. If there's pending
* code to be optimized and emitted, do so first.
@@ -416,7 +490,7 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
* in sync between plain C and JIT related code.
*/
LLVMTypeRef
-llvm_pg_var_type(const char *varname)
+llvm_pg_var_type(LLVMModuleRef llvm_types_module, const char *varname)
{
LLVMValueRef v_srcvar;
LLVMTypeRef typ;
@@ -436,12 +510,12 @@ llvm_pg_var_type(const char *varname)
* keep function types in sync between C and JITed code.
*/
LLVMTypeRef
-llvm_pg_var_func_type(const char *varname)
+llvm_pg_var_func_type(LLVMJitContext *context, const char *varname)
{
LLVMValueRef v_srcvar;
LLVMTypeRef typ;
- v_srcvar = LLVMGetNamedFunction(llvm_types_module, varname);
+ v_srcvar = LLVMGetNamedFunction(context->llvm_types_module, varname);
if (!v_srcvar)
elog(ERROR, "function %s not in llvmjit_types.c", varname);
@@ -458,22 +532,22 @@ llvm_pg_var_func_type(const char *varname)
* the module that's currently being worked on.
*/
LLVMValueRef
-llvm_pg_func(LLVMModuleRef mod, const char *funcname)
+llvm_pg_func(LLVMJitContext *context /*LLVMModuleRef mod*/, const char *funcname)
{
LLVMValueRef v_srcfn;
LLVMValueRef v_fn;
/* don't repeatedly add function */
- v_fn = LLVMGetNamedFunction(mod, funcname);
+ v_fn = LLVMGetNamedFunction(context->module, funcname);
if (v_fn)
return v_fn;
- v_srcfn = LLVMGetNamedFunction(llvm_types_module, funcname);
+ v_srcfn = LLVMGetNamedFunction(context->llvm_types_module ? context->llvm_types_module : llvm_types_module, funcname);
if (!v_srcfn)
elog(ERROR, "function %s not in llvmjit_types.c", funcname);
- v_fn = LLVMAddFunction(mod,
+ v_fn = LLVMAddFunction(context->module,
funcname,
LLVMGetFunctionType(v_srcfn));
llvm_copy_attributes(v_srcfn, v_fn);
@@ -537,7 +611,8 @@ LLVMValueRef
llvm_function_reference(LLVMJitContext *context,
LLVMBuilderRef builder,
LLVMModuleRef mod,
- FunctionCallInfo fcinfo)
+ FunctionCallInfo fcinfo,
+ LLVMValueRef v_fcinfo)
{
char *modname;
char *basename;
@@ -570,17 +645,22 @@ llvm_function_reference(LLVMJitContext *context,
fcinfo->flinfo->fn_oid);
v_fn = LLVMGetNamedGlobal(mod, funcname);
if (v_fn != 0)
- return l_load(builder, TypePGFunction, v_fn, "");
-
- v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
-
- v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
+ return l_load(builder, context->jit_types->TypePGFunction, v_fn, "");
+
+ v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, context->jit_types->TypePGFunction, context->jit_types->TypeSizeT);
+ ///tmp = l_ptr_const_step(d.hashdatum.iresult, l_ptr(g->StructNullableDatum));
+ ///tmp = l_struct_gep(b, g->StructNullableDatum, tmp, FIELDNO_NULLABLE_DATUM_DATUM, "");
+ /// params[1] = ///l_ptr_const(fcinfo->args, l_ptr(LLVMInt8TypeInContext(lc)));
+ /// l_load_member_value_by_offset(b, lc , v_fcinfo, l_ptr(LLVMInt8TypeInContext(lc)), offsetof(FunctionCallInfoBaseData, args));
+ ////v_fn_addr = l_load_member_value_by_offset(builder, lc , v_fcinfo, l_ptr(LLVMInt8TypeInContext(lc)), offsetof(FunctionCallInfoBaseData, flinfo));
+ ////v_fn_addr = l_load_member_value_by_offset(builder, lc , v_fn_addr, context->jit_types->TypePGFunction, offsetof(FmgrInfo, fn_addr));
+ v_fn = LLVMAddGlobal(mod, context->jit_types->TypePGFunction, funcname);
LLVMSetInitializer(v_fn, v_fn_addr);
LLVMSetGlobalConstant(v_fn, true);
LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
LLVMSetUnnamedAddr(v_fn, true);
- return l_load(builder, TypePGFunction, v_fn, "");
+ return l_load(builder, context->jit_types->TypePGFunction, v_fn, "");
}
/* check if function already has been added */
@@ -588,7 +668,7 @@ llvm_function_reference(LLVMJitContext *context,
if (v_fn != 0)
return v_fn;
- v_fn = LLVMAddFunction(mod, funcname, LLVMGetFunctionType(AttributeTemplate));
+ v_fn = LLVMAddFunction(mod, funcname, LLVMGetFunctionType(context->jit_types->AttributeTemplate));
return v_fn;
}
@@ -779,6 +859,9 @@ llvm_compile_module(LLVMJitContext *context)
*/
context->module = NULL; /* will be owned by LLJIT */
+ context->counter_expr = 0;
+ context->counter_deform = 0;
+
error = LLVMOrcLLJITAddLLVMIRModuleWithRT(compile_orc,
handle->resource_tracker,
ts_module);
@@ -795,6 +878,8 @@ llvm_compile_module(LLVMJitContext *context)
endtime, starttime);
context->module = NULL;
+ context->counter_expr = 0;
+ context->counter_deform = 0;
context->compiled = true;
/* remember emitted code for cleanup and lookups */
@@ -980,12 +1065,10 @@ llvm_set_target(void)
/*
* Load required information, types, function signatures from llvmjit_types.c
- * and make them available in global variables.
- *
- * Those global variables are then used while emitting code.
+ * and save it in LLVMJitTypes struct.
*/
static void
-llvm_create_types(void)
+llvm_create_types_context(LLVMJitTypes *jit_types_struct, LLVMModuleRef *llvm_types_module, LLVMContextRef llvm_context)
{
char path[MAXPGPATH];
LLVMMemoryBufferRef buf;
@@ -1001,39 +1084,56 @@ llvm_create_types(void)
}
/* eagerly load contents, going to need it all */
- if (LLVMParseBitcodeInContext2(llvm_context, buf, &llvm_types_module))
+ if (LLVMParseBitcodeInContext2(llvm_context, buf, llvm_types_module))
{
elog(ERROR, "LLVMParseBitcodeInContext2 of %s failed", path);
}
LLVMDisposeMemoryBuffer(buf);
- 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");
- ExecEvalBoolSubroutineTemplate = LLVMGetNamedFunction(llvm_types_module, "ExecEvalBoolSubroutineTemplate");
+ jit_types_struct->TypeSizeT = llvm_pg_var_type(*llvm_types_module, "TypeSizeT");
+ jit_types_struct->TypeParamBool = load_return_type(*llvm_types_module, "FunctionReturningBool");
+ jit_types_struct->TypeStorageBool = llvm_pg_var_type(*llvm_types_module, "TypeStorageBool");
+ jit_types_struct->TypePGFunction = llvm_pg_var_type(*llvm_types_module, "TypePGFunction");
+ jit_types_struct->StructNullableDatum = llvm_pg_var_type(*llvm_types_module, "StructNullableDatum");
+ jit_types_struct->StructExprContext = llvm_pg_var_type(*llvm_types_module, "StructExprContext");
+ jit_types_struct->StructExprEvalStep = llvm_pg_var_type(*llvm_types_module, "StructExprEvalStep");
+ jit_types_struct->StructExprState = llvm_pg_var_type(*llvm_types_module, "StructExprState");
+ jit_types_struct->StructFunctionCallInfoData = llvm_pg_var_type(*llvm_types_module, "StructFunctionCallInfoData");
+ jit_types_struct->StructMemoryContextData = llvm_pg_var_type(*llvm_types_module, "StructMemoryContextData");
+ jit_types_struct->StructTupleTableSlot = llvm_pg_var_type(*llvm_types_module, "StructTupleTableSlot");
+ jit_types_struct->StructHeapTupleTableSlot = llvm_pg_var_type(*llvm_types_module, "StructHeapTupleTableSlot");
+ jit_types_struct->StructMinimalTupleTableSlot = llvm_pg_var_type(*llvm_types_module, "StructMinimalTupleTableSlot");
+ jit_types_struct->StructHeapTupleData = llvm_pg_var_type(*llvm_types_module, "StructHeapTupleData");
+ jit_types_struct->StructHeapTupleHeaderData = llvm_pg_var_type(*llvm_types_module, "StructHeapTupleHeaderData");
+ jit_types_struct->StructTupleDescData = llvm_pg_var_type(*llvm_types_module, "StructTupleDescData");
+ jit_types_struct->StructAggState = llvm_pg_var_type(*llvm_types_module, "StructAggState");
+ jit_types_struct->StructAggStatePerGroupData = llvm_pg_var_type(*llvm_types_module, "StructAggStatePerGroupData");
+ jit_types_struct->StructAggStatePerTransData = llvm_pg_var_type(*llvm_types_module, "StructAggStatePerTransData");
+ jit_types_struct->StructPlanState = llvm_pg_var_type(*llvm_types_module, "StructPlanState");
+ jit_types_struct->StructMinimalTupleData = llvm_pg_var_type(*llvm_types_module, "StructMinimalTupleData");
+ jit_types_struct->StructWindowFuncExprState = llvm_pg_var_type(*llvm_types_module, "StructWindowFuncExprState");
+
+ jit_types_struct->AttributeTemplate = LLVMGetNamedFunction(*llvm_types_module, "AttributeTemplate");
+ jit_types_struct->ExecEvalSubroutineTemplate = LLVMGetNamedFunction(*llvm_types_module, "ExecEvalSubroutineTemplate");
+ jit_types_struct->ExecEvalBoolSubroutineTemplate = LLVMGetNamedFunction(*llvm_types_module, "ExecEvalBoolSubroutineTemplate");
+ {
+ char *error = NULL;
+ LLVMVerifyModule(*llvm_types_module, LLVMAbortProcessAction, &error);
+ LLVMDisposeMessage(error);
+ }
}
+/*
+ * Load required information, types, function signatures from llvmjit_types.c
+ * and make them available in global variables.
+ *
+ * Those global variables are then used while emitting code.
+ */
+static void
+llvm_create_types(void)
+{
+ llvm_create_types_context(&llvm_jit_types_struct, &llvm_types_module, llvm_context);
+}
/*
* Split a symbol into module / function parts. If the function is in the
* main binary (or an external library) *modname will be NULL.
diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c
index 5d169c7a40b..98b32a4954c 100644
--- a/src/backend/jit/llvm/llvmjit_deform.c
+++ b/src/backend/jit/llvm/llvmjit_deform.c
@@ -78,6 +78,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
LLVMValueRef v_hoff;
LLVMValueRef v_hasnulls;
+ LLVMJitTypes *g;
/* last column (0 indexed) guaranteed to exist */
int guaranteed_column_number = -1;
@@ -101,8 +102,9 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
mod = llvm_mutable_module(context);
lc = LLVMGetModuleContext(mod);
+ g = context->jit_types;
- funcname = llvm_expand_funcname(context, "deform");
+ funcname = llvm_expand_funcname_deform(context, "deform");
/*
* Check which columns have to exist, so we don't have to check the row's
@@ -133,7 +135,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
{
LLVMTypeRef param_types[1];
- param_types[0] = l_ptr(StructTupleTableSlot);
+ param_types[0] = l_ptr(g->StructTupleTableSlot);
deform_sig = LLVMFunctionType(LLVMVoidTypeInContext(lc),
param_types, lengthof(param_types), 0);
@@ -141,7 +143,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_deform_fn = LLVMAddFunction(mod, funcname, deform_sig);
LLVMSetLinkage(v_deform_fn, LLVMInternalLinkage);
LLVMSetParamAlignment(LLVMGetParam(v_deform_fn, 0), MAXIMUM_ALIGNOF);
- llvm_copy_attributes(AttributeTemplate, v_deform_fn);
+ llvm_copy_attributes(g->AttributeTemplate, v_deform_fn);
b_entry =
LLVMAppendBasicBlockInContext(lc, v_deform_fn, "entry");
@@ -168,18 +170,18 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
LLVMPositionBuilderAtEnd(b, b_entry);
/* perform allocas first, llvm only converts those to registers */
- v_offp = LLVMBuildAlloca(b, TypeSizeT, "v_offp");
+ v_offp = LLVMBuildAlloca(b, g->TypeSizeT, "v_offp");
v_slot = LLVMGetParam(v_deform_fn, 0);
v_tts_values =
- l_load_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_VALUES,
+ l_load_struct_gep(b, g->StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_VALUES,
"tts_values");
v_tts_nulls =
- l_load_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_ISNULL,
+ l_load_struct_gep(b, g->StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_ISNULL,
"tts_ISNULL");
- v_flagsp = l_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_FLAGS, "");
- v_nvalidp = l_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_NVALID, "");
+ v_flagsp = l_struct_gep(b, g->StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_FLAGS, "");
+ v_nvalidp = l_struct_gep(b, g->StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_NVALID, "");
if (ops == &TTSOpsHeapTuple || ops == &TTSOpsBufferHeapTuple)
{
@@ -188,11 +190,11 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_heapslot =
LLVMBuildBitCast(b,
v_slot,
- l_ptr(StructHeapTupleTableSlot),
+ l_ptr(g->StructHeapTupleTableSlot),
"heapslot");
- v_slotoffp = l_struct_gep(b, StructHeapTupleTableSlot, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_OFF, "");
+ v_slotoffp = l_struct_gep(b, g->StructHeapTupleTableSlot, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_OFF, "");
v_tupleheaderp =
- l_load_struct_gep(b, StructHeapTupleTableSlot, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_TUPLE,
+ l_load_struct_gep(b, g->StructHeapTupleTableSlot, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_TUPLE,
"tupleheader");
}
else if (ops == &TTSOpsMinimalTuple)
@@ -202,15 +204,15 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_minimalslot =
LLVMBuildBitCast(b,
v_slot,
- l_ptr(StructMinimalTupleTableSlot),
+ l_ptr(g->StructMinimalTupleTableSlot),
"minimalslot");
v_slotoffp = l_struct_gep(b,
- StructMinimalTupleTableSlot,
+ g->StructMinimalTupleTableSlot,
v_minimalslot,
FIELDNO_MINIMALTUPLETABLESLOT_OFF, "");
v_tupleheaderp =
l_load_struct_gep(b,
- StructMinimalTupleTableSlot,
+ g->StructMinimalTupleTableSlot,
v_minimalslot,
FIELDNO_MINIMALTUPLETABLESLOT_TUPLE,
"tupleheader");
@@ -223,14 +225,14 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_tuplep =
l_load_struct_gep(b,
- StructHeapTupleData,
+ g->StructHeapTupleData,
v_tupleheaderp,
FIELDNO_HEAPTUPLEDATA_DATA,
"tuple");
v_bits =
LLVMBuildBitCast(b,
l_struct_gep(b,
- StructHeapTupleHeaderData,
+ g->StructHeapTupleHeaderData,
v_tuplep,
FIELDNO_HEAPTUPLEHEADERDATA_BITS,
""),
@@ -238,13 +240,13 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
"t_bits");
v_infomask1 =
l_load_struct_gep(b,
- StructHeapTupleHeaderData,
+ g->StructHeapTupleHeaderData,
v_tuplep,
FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK,
"infomask1");
v_infomask2 =
l_load_struct_gep(b,
- StructHeapTupleHeaderData,
+ g->StructHeapTupleHeaderData,
v_tuplep, FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2,
"infomask2");
@@ -270,7 +272,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_hoff =
LLVMBuildZExt(b,
l_load_struct_gep(b,
- StructHeapTupleHeaderData,
+ g->StructHeapTupleHeaderData,
v_tuplep,
FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
""),
@@ -293,7 +295,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
LLVMValueRef v_off_start;
v_off_start = l_load(b, LLVMInt32TypeInContext(lc), v_slotoffp, "v_slot_off");
- v_off_start = LLVMBuildZExt(b, v_off_start, TypeSizeT, "");
+ v_off_start = LLVMBuildZExt(b, v_off_start, g->TypeSizeT, "");
LLVMBuildStore(b, v_off_start, v_offp);
}
@@ -349,7 +351,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_params[0] = v_slot;
v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32TypeInContext(lc), "");
v_params[2] = l_int32_const(lc, natts);
- f = llvm_pg_func(mod, "slot_getmissingattrs");
+ f = llvm_pg_func(context, "slot_getmissingattrs");
l_call(b,
LLVMGetFunctionType(f), f,
v_params, lengthof(v_params), "");
@@ -409,7 +411,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
*/
if (attnum == 0)
{
- LLVMBuildStore(b, l_sizet_const(0), v_offp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_offp);
}
/*
@@ -479,8 +481,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
l_gep(b, LLVMInt8TypeInContext(lc), v_tts_nulls, &l_attno, 1, ""));
/* store zero datum */
LLVMBuildStore(b,
- l_sizet_const(0),
- l_gep(b, TypeSizeT, v_tts_values, &l_attno, 1, ""));
+ LLVMConstInt(g->TypeSizeT, 0, false),
+ l_gep(b, g->TypeSizeT, v_tts_values, &l_attno, 1, ""));
LLVMBuildBr(b, b_next);
attguaranteedalign = false;
@@ -524,7 +526,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* don't know if short varlena or not */
attguaranteedalign = false;
- v_off = l_load(b, TypeSizeT, v_offp, "");
+ v_off = l_load(b, g->TypeSizeT, v_offp, "");
v_possible_padbyte =
l_load_gep1(b, LLVMInt8TypeInContext(lc), v_tupdata_base, v_off, "padbyte");
@@ -546,16 +548,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* translation of alignment code (cf TYPEALIGN()) */
{
LLVMValueRef v_off_aligned;
- LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
+ LLVMValueRef v_off = l_load(b, g->TypeSizeT, v_offp, "");
/* ((ALIGNVAL) - 1) */
- LLVMValueRef v_alignval = l_sizet_const(alignto - 1);
+ LLVMValueRef v_alignval = LLVMConstInt(g->TypeSizeT, alignto - 1, false);
/* ((uintptr_t) (LEN) + ((ALIGNVAL) - 1)) */
LLVMValueRef v_lh = LLVMBuildAdd(b, v_off, v_alignval, "");
/* ~((uintptr_t) ((ALIGNVAL) - 1)) */
- LLVMValueRef v_rh = l_sizet_const(~(alignto - 1));
+ LLVMValueRef v_rh = LLVMConstInt(g->TypeSizeT, ~(alignto - 1), false);
v_off_aligned = LLVMBuildAnd(b, v_lh, v_rh, "aligned_offset");
@@ -594,7 +596,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
if (attguaranteedalign)
{
Assert(known_alignment >= 0);
- LLVMBuildStore(b, l_sizet_const(known_alignment), v_offp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, known_alignment, false), v_offp);
}
/* compute what following columns are aligned to */
@@ -635,18 +637,18 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* compute address to load data from */
{
- LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
+ LLVMValueRef v_off = l_load(b, g->TypeSizeT, v_offp, "");
v_attdatap =
l_gep(b, LLVMInt8TypeInContext(lc), v_tupdata_base, &v_off, 1, "");
}
/* compute address to store value at */
- v_resultp = l_gep(b, TypeSizeT, v_tts_values, &l_attno, 1, "");
+ v_resultp = l_gep(b, g->TypeSizeT, v_tts_values, &l_attno, 1, "");
/* store null-byte (false) */
LLVMBuildStore(b, l_int8_const(lc, 0),
- l_gep(b, TypeStorageBool, v_tts_nulls, &l_attno, 1, ""));
+ l_gep(b, g->TypeStorageBool, v_tts_nulls, &l_attno, 1, ""));
/*
* Store datum. For byval: datums copy the value, extend to Datum's
@@ -661,7 +663,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_tmp_loaddata =
LLVMBuildPointerCast(b, v_attdatap, vartypep, "");
v_tmp_loaddata = l_load(b, vartype, v_tmp_loaddata, "attr_byval");
- v_tmp_loaddata = LLVMBuildZExt(b, v_tmp_loaddata, TypeSizeT, "");
+ v_tmp_loaddata = LLVMBuildZExt(b, v_tmp_loaddata, g->TypeSizeT, "");
LLVMBuildStore(b, v_tmp_loaddata, v_resultp);
}
@@ -673,7 +675,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_tmp_loaddata =
LLVMBuildPtrToInt(b,
v_attdatap,
- TypeSizeT,
+ g->TypeSizeT,
"attr_ptr");
LLVMBuildStore(b, v_tmp_loaddata, v_resultp);
}
@@ -681,13 +683,13 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* increment data pointer */
if (att->attlen > 0)
{
- v_incby = l_sizet_const(att->attlen);
+ v_incby = LLVMConstInt(g->TypeSizeT, att->attlen, false);
}
else if (att->attlen == -1)
{
v_incby = l_call(b,
- llvm_pg_var_func_type("varsize_any"),
- llvm_pg_func(mod, "varsize_any"),
+ llvm_pg_var_func_type(context, "varsize_any"),
+ llvm_pg_func(context, "varsize_any"),
&v_attdatap, 1,
"varsize_any");
l_callsite_ro(v_incby);
@@ -696,14 +698,14 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
else if (att->attlen == -2)
{
v_incby = l_call(b,
- llvm_pg_var_func_type("strlen"),
- llvm_pg_func(mod, "strlen"),
+ llvm_pg_var_func_type(context, "strlen"),
+ llvm_pg_func(context, "strlen"),
&v_attdatap, 1, "strlen");
l_callsite_ro(v_incby);
/* add 1 for NUL byte */
- v_incby = LLVMBuildAdd(b, v_incby, l_sizet_const(1), "");
+ v_incby = LLVMBuildAdd(b, v_incby, LLVMConstInt(g->TypeSizeT, 1, false), "");
}
else
{
@@ -714,11 +716,11 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
if (attguaranteedalign)
{
Assert(known_alignment >= 0);
- LLVMBuildStore(b, l_sizet_const(known_alignment), v_offp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, known_alignment, false), v_offp);
}
else
{
- LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
+ LLVMValueRef v_off = l_load(b, g->TypeSizeT, v_offp, "");
v_off = LLVMBuildAdd(b, v_off, v_incby, "increment_offset");
LLVMBuildStore(b, v_off, v_offp);
@@ -744,7 +746,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
LLVMPositionBuilderAtEnd(b, b_out);
{
- LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
+ LLVMValueRef v_off = l_load(b, g->TypeSizeT, v_offp, "");
LLVMValueRef v_flags;
LLVMBuildStore(b, l_int16_const(lc, natts), v_nvalidp);
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index f0f5c3bd49f..91968ea248f 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -17,6 +17,7 @@
#include <llvm-c/Core.h>
#include <llvm-c/Target.h>
+#include <llvm-c/Analysis.h>
#include "access/htup_details.h"
#include "access/nbtree.h"
@@ -57,16 +58,22 @@ static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *
static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
LLVMModuleRef mod, FunctionCallInfo fcinfo,
LLVMValueRef *v_fcinfo_isnull);
+static LLVMValueRef BuildV1CallLLVM(LLVMJitContext *context, LLVMBuilderRef b,
+ LLVMModuleRef mod, FunctionCallInfo fcinfo,
+ LLVMValueRef v_fcinfo, LLVMValueRef *v_fcinfo_isnull);
static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod,
const char *funcname,
LLVMValueRef v_state,
ExprEvalStep *op,
int natts, LLVMValueRef *v_args);
+static LLVMValueRef build_EvalXFuncIntLLVM(LLVMBuilderRef b, LLVMJitContext *context, const char *funcname,
+ LLVMValueRef v_state, LLVMValueRef v_op,
+ int nargs, LLVMValueRef *v_args);
static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod);
/* macro making it easier to call ExecEval* functions */
-#define build_EvalXFunc(b, mod, funcname, v_state, op, ...) \
- build_EvalXFuncInt(b, mod, funcname, v_state, op, \
+#define build_EvalXFunc(b, context, funcname, v_state, op, ...) \
+ build_EvalXFuncIntLLVM(b, context, funcname, v_state, op, \
lengthof(((LLVMValueRef[]){__VA_ARGS__})), \
((LLVMValueRef[]){__VA_ARGS__}))
@@ -84,6 +91,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuilderRef b;
LLVMModuleRef mod;
+ LLVMModuleRef typesmod;
LLVMContextRef lc;
LLVMValueRef eval_fn;
LLVMBasicBlockRef entry;
@@ -93,6 +101,7 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_state;
LLVMValueRef v_econtext;
LLVMValueRef v_parent;
+ LLVMValueRef v_steps;
/* returnvalue */
LLVMValueRef v_isnullp;
@@ -132,6 +141,9 @@ llvm_compile_expr(ExprState *state)
instr_time endtime;
instr_time deform_endtime;
+ bool cached_plan;
+ LLVMJitTypes *g;
+
llvm_enter_fatal_on_oom();
/*
@@ -141,29 +153,82 @@ llvm_compile_expr(ExprState *state)
Assert(parent);
/* get or create JIT context */
- if (parent->state->es_jit)
- context = (LLVMJitContext *) parent->state->es_jit;
- else
+ if (parent->state->es_plannedstmt->jit_context == NULL || !jit_cached)
{
- context = llvm_create_context(parent->state->es_jit_flags);
- parent->state->es_jit = &context->base;
+ if (parent->state->es_jit)
+ context = (LLVMJitContext *) parent->state->es_jit;
+ else
+ {
+ context = llvm_create_context(parent->state->es_jit_flags);
+ parent->state->es_jit = &context->base;
+ }
+ mod = llvm_mutable_module(context);
+ funcname = llvm_expand_funcname_expr(context, "evalexpr");
+
+ cached_plan = false;
+ g = context->jit_types;
}
+ else
+ {
+ cached_plan = true;
+ if (parent->state->es_plannedstmt->jit_context == CACHED_JITCONTEXT_EMPTY)
+ {
+ parent->state->es_plannedstmt->jit_context = llvm_create_cached_context(parent->state->es_jit_flags);
+ parent->state->es_plannedstmt->jit_context->jit.first_expr = state->expr;
+
+ }
+
+ context = &parent->state->es_plannedstmt->jit_context->jit;
+ context->first_expr = state->expr;
+
+ g = context->jit_types;
+ if (!parent->state->es_plannedstmt->jit_context->jit.compiled)
+ {
+ mod = llvm_mutable_module(context);
+ funcname = llvm_expand_funcname_expr(context, "evalexpr");
+ context->max_counter_expr = context->counter_expr;
+ ///elog(NOTICE,"Compile %s max %d counter %d, context=%zx", funcname, context->max_counter_expr , context->counter_expr, (Size)context);
+ }
+ else
+ {
+ ExprStateEvalFunc func;
+ /* find and assign binary function: first call - first expression
+ Attention!
+ This alogorithm is wrong and will fail, if query compiles additional
+ expressions after the module compilation (f.e. for HashJoin). Needs new implementation
+ to assign expressions and compiled functions
+ */
+ ///elog(NOTICE,"1 Look for Compiled before max %d counter %d, context=%zx", context->max_counter_expr , context->counter_expr, (Size)context);
+ if (context->max_counter_expr == context->counter_expr)
+ {
+ context->counter_expr = 0;
+ context->counter_deform = 0;
+ }
+ funcname = llvm_expand_funcname_expr(context, "evalexpr");
+ func = (ExprStateEvalFunc) llvm_get_function(context,funcname);
+ llvm_leave_fatal_on_oom();
+ Assert(func);
+ /* remove indirection via this function for future calls */
+ state->evalfunc = func;
+ pfree(funcname);
+ return true;
+ }
+ }
INSTR_TIME_SET_CURRENT(starttime);
- mod = llvm_mutable_module(context);
lc = LLVMGetModuleContext(mod);
+ typesmod = context->llvm_types_module;
b = LLVMCreateBuilderInContext(lc);
- funcname = llvm_expand_funcname(context, "evalexpr");
/* create function */
eval_fn = LLVMAddFunction(mod, funcname,
- llvm_pg_var_func_type("ExecInterpExprStillValid"));
+ llvm_pg_var_func_type(context, "ExecInterpExprStillValid"));
LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
- llvm_copy_attributes(AttributeTemplate, eval_fn);
+ llvm_copy_attributes(g->AttributeTemplate, eval_fn);
entry = LLVMAppendBasicBlockInContext(lc, eval_fn, "entry");
@@ -175,123 +240,128 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, entry);
v_tmpvaluep = l_struct_gep(b,
- StructExprState,
+ g->StructExprState,
v_state,
FIELDNO_EXPRSTATE_RESVALUE,
"v.state.resvalue");
v_tmpisnullp = l_struct_gep(b,
- StructExprState,
+ g->StructExprState,
v_state,
FIELDNO_EXPRSTATE_RESNULL,
"v.state.resnull");
v_parent = l_load_struct_gep(b,
- StructExprState,
+ g->StructExprState,
v_state,
FIELDNO_EXPRSTATE_PARENT,
"v.state.parent");
+ v_steps = l_load_struct_gep(b,
+ g->StructExprState,
+ v_state,
+ FIELDNO_EXPRSTATE_STEPS,
+ "v_state_steps");
/* build global slots */
v_scanslot = l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_SCANTUPLE,
"v_scanslot");
v_innerslot = l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_INNERTUPLE,
"v_innerslot");
v_outerslot = l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_OUTERTUPLE,
"v_outerslot");
v_oldslot = l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_OLDTUPLE,
"v_oldslot");
v_newslot = l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_NEWTUPLE,
"v_newslot");
v_resultslot = l_load_struct_gep(b,
- StructExprState,
+ g->StructExprState,
v_state,
FIELDNO_EXPRSTATE_RESULTSLOT,
"v_resultslot");
/* build global values/isnull pointers */
v_scanvalues = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_scanslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_scanvalues");
v_scannulls = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_scanslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_scannulls");
v_innervalues = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_innerslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_innervalues");
v_innernulls = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_innerslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_innernulls");
v_outervalues = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_outerslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_outervalues");
v_outernulls = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_outerslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_outernulls");
v_oldvalues = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_oldslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_oldvalues");
v_oldnulls = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_oldslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_oldnulls");
v_newvalues = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_newslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_newvalues");
v_newnulls = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_newslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_newnulls");
v_resultvalues = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_resultslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_resultvalues");
v_resultnulls = l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_resultslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_resultnulls");
/* aggvalues/aggnulls */
v_aggvalues = l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_AGGVALUES,
"v.econtext.aggvalues");
v_aggnulls = l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_AGGNULLS,
"v.econtext.aggnulls");
@@ -308,16 +378,22 @@ llvm_compile_expr(ExprState *state)
{
ExprEvalStep *op;
ExprEvalOp opcode;
+ LLVMValueRef v_op;
+ LLVMValueRef v_opno;
LLVMValueRef v_resvaluep;
LLVMValueRef v_resnullp;
+
LLVMPositionBuilderAtEnd(b, opblocks[opno]);
op = &state->steps[opno];
opcode = ExecEvalStepOp(state, op);
-
- v_resvaluep = l_ptr_const(op->resvalue, l_ptr(TypeSizeT));
- v_resnullp = l_ptr_const(op->resnull, l_ptr(TypeStorageBool));
+ v_opno = l_int32_const(lc, opno);
+ v_op = l_gep(b, g->StructExprEvalStep, v_steps, &v_opno, 1, "v_op_step");
+ ///v_resvaluep = l_ptr_const(op->resvalue, l_ptr(TypeSizeT));
+ ///v_resnullp = l_ptr_const(op->resnull, l_ptr(g->TypeStorageBool));
+ v_resvaluep = l_load_struct_gep( b, g->StructExprEvalStep, v_op, FIELDNO_EXPREVALSTEP_RESVALUE, "v_resvaluep");
+ v_resnullp = l_load_struct_gep( b, g->StructExprEvalStep, v_op, FIELDNO_EXPREVALSTEP_RESNULL, "v_resnullp");
switch (opcode)
{
@@ -326,8 +402,8 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_tmpisnull;
LLVMValueRef v_tmpvalue;
- v_tmpvalue = l_load(b, TypeSizeT, v_tmpvaluep, "");
- v_tmpisnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
+ v_tmpvalue = l_load(b, g->TypeSizeT, v_tmpvaluep, "");
+ v_tmpisnull = l_load(b, g->TypeStorageBool, v_tmpisnullp, "");
LLVMBuildStore(b, v_tmpisnull, v_isnullp);
@@ -377,7 +453,7 @@ llvm_compile_expr(ExprState *state)
*/
v_nvalid =
l_load_struct_gep(b,
- StructTupleTableSlot,
+ g->StructTupleTableSlot,
v_slot,
FIELDNO_TUPLETABLESLOT_NVALID,
"");
@@ -426,8 +502,8 @@ llvm_compile_expr(ExprState *state)
params[1] = l_int32_const(lc, op->d.fetch.last_var);
l_call(b,
- llvm_pg_var_func_type("slot_getsomeattrs_int"),
- llvm_pg_func(mod, "slot_getsomeattrs_int"),
+ llvm_pg_var_func_type(context, "slot_getsomeattrs_int"),
+ llvm_pg_func(context, "slot_getsomeattrs_int"),
params, lengthof(params), "");
}
@@ -474,8 +550,8 @@ llvm_compile_expr(ExprState *state)
}
v_attnum = l_int32_const(lc, op->d.var.attnum);
- value = l_load_gep1(b, TypeSizeT, v_values, v_attnum, "");
- isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
+ value = l_load_gep1(b, g->TypeSizeT, v_values, v_attnum, "");
+ isnull = l_load_gep1(b, g->TypeStorageBool, v_nulls, v_attnum, "");
LLVMBuildStore(b, value, v_resvaluep);
LLVMBuildStore(b, isnull, v_resnullp);
@@ -502,16 +578,16 @@ llvm_compile_expr(ExprState *state)
else
v_slot = v_newslot;
- build_EvalXFunc(b, mod, "ExecEvalSysVar",
- v_state, op, v_econtext, v_slot);
+ build_EvalXFunc(b, context, "ExecEvalSysVar",
+ v_state, v_op, v_econtext, v_slot);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
}
case EEOP_WHOLEROW:
- build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalWholeRowVar",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -558,17 +634,17 @@ llvm_compile_expr(ExprState *state)
/* load data */
v_attnum = l_int32_const(lc, op->d.assign_var.attnum);
- v_value = l_load_gep1(b, TypeSizeT, v_values, v_attnum, "");
- v_isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
+ v_value = l_load_gep1(b, g->TypeSizeT, v_values, v_attnum, "");
+ v_isnull = l_load_gep1(b, g->TypeStorageBool, v_nulls, v_attnum, "");
/* compute addresses of targets */
v_resultnum = l_int32_const(lc, op->d.assign_var.resultnum);
v_rvaluep = l_gep(b,
- TypeSizeT,
+ g->TypeSizeT,
v_resultvalues,
&v_resultnum, 1, "");
v_risnullp = l_gep(b,
- TypeStorageBool,
+ g->TypeStorageBool,
v_resultnulls,
&v_resultnum, 1, "");
@@ -591,15 +667,15 @@ llvm_compile_expr(ExprState *state)
size_t resultnum = op->d.assign_tmp.resultnum;
/* load data */
- v_value = l_load(b, TypeSizeT, v_tmpvaluep, "");
- v_isnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
+ v_value = l_load(b, g->TypeSizeT, v_tmpvaluep, "");
+ v_isnull = l_load(b, g->TypeStorageBool, v_tmpisnullp, "");
/* compute addresses of targets */
v_resultnum = l_int32_const(lc, resultnum);
v_rvaluep =
- l_gep(b, TypeSizeT, v_resultvalues, &v_resultnum, 1, "");
+ l_gep(b, g->TypeSizeT, v_resultvalues, &v_resultnum, 1, "");
v_risnullp =
- l_gep(b, TypeStorageBool, v_resultnulls, &v_resultnum, 1, "");
+ l_gep(b, g->TypeStorageBool, v_resultnulls, &v_resultnum, 1, "");
/* store nullness */
LLVMBuildStore(b, v_isnull, v_risnullp);
@@ -616,7 +692,7 @@ llvm_compile_expr(ExprState *state)
/* check if value is NULL */
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_isnull,
- l_sbool_const(0), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false), ""),
b_notnull, opblocks[opno + 1]);
/* if value is not null, convert to RO datum */
@@ -624,8 +700,8 @@ llvm_compile_expr(ExprState *state)
v_params[0] = v_value;
v_value =
l_call(b,
- llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
- llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_var_func_type(context, "MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_func(context, "MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), "");
/*
@@ -646,8 +722,8 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_constvalue,
v_constnull;
- v_constvalue = l_sizet_const(op->d.constval.value);
- v_constnull = l_sbool_const(op->d.constval.isnull);
+ v_constvalue = LLVMConstInt(g->TypeSizeT, op->d.constval.value, false);
+ v_constnull = LLVMConstInt(g->TypeStorageBool, (int)(op->d.constval.isnull), false);
LLVMBuildStore(b, v_constvalue, v_resvaluep);
LLVMBuildStore(b, v_constnull, v_resnullp);
@@ -662,12 +738,12 @@ llvm_compile_expr(ExprState *state)
FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
LLVMValueRef v_fcinfo_isnull;
LLVMValueRef v_retval;
+ LLVMValueRef v_fcinfo;
if (opcode == EEOP_FUNCEXPR_STRICT)
{
LLVMBasicBlockRef b_nonull;
LLVMBasicBlockRef *b_checkargnulls;
- LLVMValueRef v_fcinfo;
/*
* Block for the actual function call, if args are
@@ -680,14 +756,18 @@ llvm_compile_expr(ExprState *state)
if (op->d.func.nargs == 0)
elog(ERROR, "argumentless strict functions are pointless");
+ ///v_fcinfo =
+ /// l_ptr_const(fcinfo, l_ptr(g->StructFunctionCallInfoData));
v_fcinfo =
- l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
+ ///l_struct_member_ptr_by_offset(b,lc, v_op, offsetof(ExprEvalStep ,d.func.fcinfo_data ));
+ l_load_member_value_by_offset(b,lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep ,d.func.fcinfo_data ));
/*
* set resnull to true, if the function is actually
* called, it'll be reset
*/
- LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_resnullp);
/* create blocks for checking args, one for each */
b_checkargnulls =
@@ -718,11 +798,11 @@ llvm_compile_expr(ExprState *state)
b_argnotnull = b_checkargnulls[argno + 1];
/* and finally load & check NULLness of arg */
- v_argisnull = l_funcnull(b, v_fcinfo, argno);
+ v_argisnull = l_funcnull(b, v_fcinfo, argno, g);
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ,
v_argisnull,
- l_sbool_const(1),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false),
""),
opblocks[opno + 1],
b_argnotnull);
@@ -730,8 +810,13 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_nonull);
}
+ else
+ {
+ v_fcinfo = l_load_member_value_by_offset(b,lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep ,d.func.fcinfo_data ));
+ }
- v_retval = BuildV1Call(context, b, mod, fcinfo,
+ v_retval = BuildV1CallLLVM(context, b, mod, fcinfo, v_fcinfo,
&v_fcinfo_isnull);
LLVMBuildStore(b, v_retval, v_resvaluep);
LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
@@ -741,15 +826,15 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_FUNCEXPR_FUSAGE:
- build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalFuncExprFusage",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_FUNCEXPR_STRICT_FUSAGE:
- build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalFuncExprStrictFusage",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -783,26 +868,28 @@ llvm_compile_expr(ExprState *state)
b_boolcont = l_bb_before_v(opblocks[opno + 1],
"b.%d.boolcont", opno);
- v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
- l_ptr(TypeStorageBool));
+ v_boolanynullp = ///l_ptr_const(op->d.boolexpr.anynull,
+ /// l_ptr(g->TypeStorageBool));
+ l_load_member_value_by_offset(b,lc, v_op,
+ l_ptr(g->TypeStorageBool), offsetof(ExprEvalStep ,d.boolexpr.anynull ));
if (opcode == EEOP_BOOL_AND_STEP_FIRST)
- LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_boolanynullp);
- v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
- v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
+ v_boolnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
+ v_boolvalue = l_load(b, g->TypeSizeT, v_resvaluep, "");
/* check if current input is NULL */
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
b_boolisnull,
b_boolcheckfalse);
/* build block that sets anynull */
LLVMPositionBuilderAtEnd(b, b_boolisnull);
/* set boolanynull to true */
- LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_boolanynullp);
/* and jump to next block */
LLVMBuildBr(b, b_boolcont);
@@ -810,7 +897,7 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_boolcheckfalse);
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
- l_sizet_const(0), ""),
+ LLVMConstInt(g->TypeSizeT, 0, false), ""),
b_boolisfalse,
b_boolcont);
@@ -826,19 +913,19 @@ llvm_compile_expr(ExprState *state)
/* Build block that continues if bool is TRUE. */
LLVMPositionBuilderAtEnd(b, b_boolcont);
- v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
+ v_boolanynull = l_load(b, g->TypeStorageBool, v_boolanynullp, "");
/* set value to NULL if any previous values were NULL */
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
- l_sbool_const(0), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false), ""),
opblocks[opno + 1], b_boolisanynull);
LLVMPositionBuilderAtEnd(b, b_boolisanynull);
/* set resnull to true */
- LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_resnullp);
/* reset resvalue */
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -875,24 +962,26 @@ llvm_compile_expr(ExprState *state)
b_boolcont = l_bb_before_v(opblocks[opno + 1],
"b.%d.boolcont", opno);
- v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
- l_ptr(TypeStorageBool));
+ v_boolanynullp = ///l_ptr_const(op->d.boolexpr.anynull,
+ /// l_ptr(g->TypeStorageBool));
+ l_ptr_const_step(d.boolexpr.anynull,
+ l_ptr(g->TypeStorageBool));
if (opcode == EEOP_BOOL_OR_STEP_FIRST)
- LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
- v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
- v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_boolanynullp);
+ v_boolnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
+ v_boolvalue = l_load(b, g->TypeSizeT, v_resvaluep, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
b_boolisnull,
b_boolchecktrue);
/* build block that sets anynull */
LLVMPositionBuilderAtEnd(b, b_boolisnull);
/* set boolanynull to true */
- LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_boolanynullp);
/* and jump to next block */
LLVMBuildBr(b, b_boolcont);
@@ -900,7 +989,7 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_boolchecktrue);
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
- l_sizet_const(1), ""),
+ LLVMConstInt(g->TypeSizeT, 1, false), ""),
b_boolistrue,
b_boolcont);
@@ -916,19 +1005,19 @@ llvm_compile_expr(ExprState *state)
/* build block that continues if bool is FALSE */
LLVMPositionBuilderAtEnd(b, b_boolcont);
- v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
+ v_boolanynull = l_load(b, g->TypeStorageBool, v_boolanynullp, "");
/* set value to NULL if any previous values were NULL */
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
- l_sbool_const(0), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false), ""),
opblocks[opno + 1], b_boolisanynull);
LLVMPositionBuilderAtEnd(b, b_boolisanynull);
/* set resnull to true */
- LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_resnullp);
/* reset resvalue */
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -940,13 +1029,13 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_negbool;
/* compute !boolvalue */
- v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
+ v_boolvalue = l_load(b, g->TypeSizeT, v_resvaluep, "");
v_negbool = LLVMBuildZExt(b,
LLVMBuildICmp(b, LLVMIntEQ,
v_boolvalue,
- l_sizet_const(0),
+ LLVMConstInt(g->TypeSizeT, 0, false),
""),
- TypeSizeT, "");
+ g->TypeSizeT, "");
/*
* Store it back in resvalue. We can ignore resnull here;
@@ -969,15 +1058,15 @@ llvm_compile_expr(ExprState *state)
b_qualfail = l_bb_before_v(opblocks[opno + 1],
"op.%d.qualfail", opno);
- v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
- v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_resvalue = l_load(b, g->TypeSizeT, v_resvaluep, "");
+ v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
v_nullorfalse =
LLVMBuildOr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
- l_sizet_const(0), ""),
+ LLVMConstInt(g->TypeSizeT, 0, false), ""),
"");
LLVMBuildCondBr(b,
@@ -988,9 +1077,9 @@ llvm_compile_expr(ExprState *state)
/* build block handling NULL or false */
LLVMPositionBuilderAtEnd(b, b_qualfail);
/* set resnull to false */
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
/* set resvalue to false */
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
/* and jump out */
LLVMBuildBr(b, opblocks[op->d.qualexpr.jumpdone]);
break;
@@ -1008,11 +1097,11 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is null */
- v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
opblocks[op->d.jump.jumpdone],
opblocks[opno + 1]);
break;
@@ -1024,11 +1113,11 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is non-null */
- v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(0), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false), ""),
opblocks[op->d.jump.jumpdone],
opblocks[opno + 1]);
break;
@@ -1043,15 +1132,15 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is null or false */
- v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
- v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_resvalue = l_load(b, g->TypeSizeT, v_resvaluep, "");
+ v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
v_nullorfalse =
LLVMBuildOr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
- l_sizet_const(0), ""),
+ LLVMConstInt(g->TypeSizeT, 0, false), ""),
"");
LLVMBuildCondBr(b,
@@ -1063,18 +1152,18 @@ llvm_compile_expr(ExprState *state)
case EEOP_NULLTEST_ISNULL:
{
- LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ LLVMValueRef v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
LLVMValueRef v_resvalue;
v_resvalue =
LLVMBuildSelect(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(1), ""),
- l_sizet_const(1),
- l_sizet_const(0),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
+ LLVMConstInt(g->TypeSizeT, 1, false),
+ LLVMConstInt(g->TypeSizeT, 0, false),
"");
LLVMBuildStore(b, v_resvalue, v_resvaluep);
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1082,32 +1171,32 @@ llvm_compile_expr(ExprState *state)
case EEOP_NULLTEST_ISNOTNULL:
{
- LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ LLVMValueRef v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
LLVMValueRef v_resvalue;
v_resvalue =
LLVMBuildSelect(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(1), ""),
- l_sizet_const(0),
- l_sizet_const(1),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
+ LLVMConstInt(g->TypeSizeT, 0, false),
+ LLVMConstInt(g->TypeSizeT, 1, false),
"");
LLVMBuildStore(b, v_resvalue, v_resvaluep);
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
}
case EEOP_NULLTEST_ROWISNULL:
- build_EvalXFunc(b, mod, "ExecEvalRowNull",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalRowNull",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_NULLTEST_ROWISNOTNULL:
- build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalRowNotNull",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1118,7 +1207,7 @@ llvm_compile_expr(ExprState *state)
{
LLVMBasicBlockRef b_isnull,
b_notnull;
- LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ LLVMValueRef v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
b_isnull = l_bb_before_v(opblocks[opno + 1],
"op.%d.isnull", opno);
@@ -1128,23 +1217,23 @@ llvm_compile_expr(ExprState *state)
/* check if value is NULL */
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
b_isnull, b_notnull);
/* if value is NULL, return false */
LLVMPositionBuilderAtEnd(b, b_isnull);
/* result is not null */
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
if (opcode == EEOP_BOOLTEST_IS_TRUE ||
opcode == EEOP_BOOLTEST_IS_FALSE)
{
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
}
else
{
- LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 1, false), v_resvaluep);
}
LLVMBuildBr(b, opblocks[opno + 1]);
@@ -1162,14 +1251,14 @@ llvm_compile_expr(ExprState *state)
else
{
LLVMValueRef v_value =
- l_load(b, TypeSizeT, v_resvaluep, "");
+ l_load(b, g->TypeSizeT, v_resvaluep, "");
v_value = LLVMBuildZExt(b,
LLVMBuildICmp(b, LLVMIntEQ,
v_value,
- l_sizet_const(0),
+ LLVMConstInt(g->TypeSizeT, 0, false),
""),
- TypeSizeT, "");
+ g->TypeSizeT, "");
LLVMBuildStore(b, v_value, v_resvaluep);
}
LLVMBuildBr(b, opblocks[opno + 1]);
@@ -1177,14 +1266,14 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_PARAM_EXEC:
- build_EvalXFunc(b, mod, "ExecEvalParamExec",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalParamExec",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_PARAM_EXTERN:
- build_EvalXFunc(b, mod, "ExecEvalParamExtern",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalParamExtern",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1193,14 +1282,17 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_func;
LLVMValueRef v_params[3];
- v_func = l_ptr_const(op->d.cparam.paramfunc,
- llvm_pg_var_type("TypeExecEvalSubroutine"));
+ v_func = ///l_ptr_const(op->d.cparam.paramfunc,
+ /// llvm_pg_var_type("TypeExecEvalSubroutine"));
+ l_ptr_const_step(d.cparam.paramfunc,
+ llvm_pg_var_type(typesmod, "TypeExecEvalSubroutine"));
v_params[0] = v_state;
- v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
+ v_params[1] = ///l_ptr_const(op, l_ptr(g->StructExprEvalStep));
+ v_op;
v_params[2] = v_econtext;
l_call(b,
- LLVMGetFunctionType(ExecEvalSubroutineTemplate),
+ LLVMGetFunctionType(g->ExecEvalSubroutineTemplate),
v_func,
v_params, lengthof(v_params), "");
@@ -1209,8 +1301,8 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_PARAM_SET:
- build_EvalXFunc(b, mod, "ExecEvalParamSet",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalParamSet",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1221,21 +1313,23 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_params[3];
LLVMValueRef v_ret;
- v_func = l_ptr_const(op->d.sbsref_subscript.subscriptfunc,
- llvm_pg_var_type("TypeExecEvalBoolSubroutine"));
+ v_func = ///l_ptr_const(op->d.sbsref_subscript.subscriptfunc,
+ /// llvm_pg_var_type("TypeExecEvalBoolSubroutine"));
+ l_ptr_const_step(d.sbsref_subscript.subscriptfunc,
+ llvm_pg_var_type(typesmod, "TypeExecEvalBoolSubroutine"));
v_params[0] = v_state;
- v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
+ v_params[1] = v_op; /// l_ptr_const(op, l_ptr(g->StructExprEvalStep));
v_params[2] = v_econtext;
v_ret = l_call(b,
- LLVMGetFunctionType(ExecEvalBoolSubroutineTemplate),
+ LLVMGetFunctionType(g->ExecEvalBoolSubroutineTemplate),
v_func,
v_params, lengthof(v_params), "");
- v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
+ v_ret = LLVMBuildZExt(b, v_ret, g->TypeStorageBool, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_ret,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
opblocks[opno + 1],
opblocks[jumpdone]);
break;
@@ -1248,14 +1342,16 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_func;
LLVMValueRef v_params[3];
- v_func = l_ptr_const(op->d.sbsref.subscriptfunc,
- llvm_pg_var_type("TypeExecEvalSubroutine"));
+ v_func = ///l_ptr_const(op->d.sbsref.subscriptfunc,
+ /// llvm_pg_var_type("TypeExecEvalSubroutine"));
+ l_ptr_const_step(d.sbsref.subscriptfunc,
+ llvm_pg_var_type(typesmod, "TypeExecEvalSubroutine"));
v_params[0] = v_state;
- v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
+ v_params[1] = v_op; ///l_ptr_const(op, l_ptr(g->StructExprEvalStep));
v_params[2] = v_econtext;
l_call(b,
- LLVMGetFunctionType(ExecEvalSubroutineTemplate),
+ LLVMGetFunctionType(g->ExecEvalSubroutineTemplate),
v_func,
v_params, lengthof(v_params), "");
@@ -1270,13 +1366,17 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_casenullp,
v_casenull;
- v_casevaluep = l_ptr_const(op->d.casetest.value,
- l_ptr(TypeSizeT));
- v_casenullp = l_ptr_const(op->d.casetest.isnull,
- l_ptr(TypeStorageBool));
-
- v_casevalue = l_load(b, TypeSizeT, v_casevaluep, "");
- v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
+ v_casevaluep = ///l_ptr_const(op->d.casetest.value,
+ /// l_ptr(TypeSizeT));
+ l_ptr_const_step(d.casetest.value,
+ l_ptr(g->TypeSizeT));
+ v_casenullp = ///l_ptr_const(op->d.casetest.isnull,
+ /// l_ptr(g->TypeStorageBool));
+ l_ptr_const_step(d.casetest.isnull,
+ l_ptr(g->TypeStorageBool));
+
+ v_casevalue = l_load(b, g->TypeSizeT, v_casevaluep, "");
+ v_casenull = l_load(b, g->TypeStorageBool, v_casenullp, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp);
@@ -1291,12 +1391,12 @@ llvm_compile_expr(ExprState *state)
v_casevalue =
l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_CASEDATUM, "");
v_casenull =
l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_CASENULL, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep);
@@ -1319,10 +1419,12 @@ llvm_compile_expr(ExprState *state)
b_notnull = l_bb_before_v(opblocks[opno + 1],
"op.%d.readonly.notnull", opno);
- v_nullp = l_ptr_const(op->d.make_readonly.isnull,
- l_ptr(TypeStorageBool));
+ v_nullp = ///l_ptr_const(op->d.make_readonly.isnull,
+ /// l_ptr(g->TypeStorageBool));
+ l_ptr_const_step(d.make_readonly.isnull,
+ l_ptr(g->TypeStorageBool));
- v_null = l_load(b, TypeStorageBool, v_nullp, "");
+ v_null = l_load(b, g->TypeStorageBool, v_nullp, "");
/* store null isnull value in result */
LLVMBuildStore(b, v_null, v_resnullp);
@@ -1330,22 +1432,24 @@ llvm_compile_expr(ExprState *state)
/* check if value is NULL */
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_null,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
opblocks[opno + 1], b_notnull);
/* if value is not null, convert to RO datum */
LLVMPositionBuilderAtEnd(b, b_notnull);
- v_valuep = l_ptr_const(op->d.make_readonly.value,
- l_ptr(TypeSizeT));
+ v_valuep = ///l_ptr_const(op->d.make_readonly.value,
+ /// l_ptr(TypeSizeT));
+ l_ptr_const_step(d.make_readonly.value,
+ l_ptr(g->TypeSizeT));
- v_value = l_load(b, TypeSizeT, v_valuep, "");
+ v_value = l_load(b, g->TypeSizeT, v_valuep, "");
v_params[0] = v_value;
v_ret =
l_call(b,
- llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
- llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_var_func_type(context, "MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_func(context, "MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), "");
LLVMBuildStore(b, v_ret, v_resvaluep);
@@ -1386,40 +1490,43 @@ llvm_compile_expr(ExprState *state)
b_inputcall = l_bb_before_v(opblocks[opno + 1],
"op.%d.inputcall", opno);
- v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out);
- v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in);
- v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData));
- v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData));
-
+ v_fcinfo_out = l_load_member_value_by_offset(b,lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep ,d.iocoerce.fcinfo_data_out ));
+ v_fcinfo_in = l_load_member_value_by_offset(b,lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep ,d.iocoerce.fcinfo_data_in ));
+ v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out, v_fcinfo_out);
+ v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in, v_fcinfo_in);
+ ///v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(g->StructFunctionCallInfoData));
+ ///v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(g->StructFunctionCallInfoData));
v_fcinfo_in_isnullp =
l_struct_gep(b,
- StructFunctionCallInfoData,
+ g->StructFunctionCallInfoData,
v_fcinfo_in,
FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
"v_fcinfo_in_isnull");
/* output functions are not called on nulls */
- v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_resnull = l_load(b, g->TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
b_skipoutput,
b_calloutput);
LLVMPositionBuilderAtEnd(b, b_skipoutput);
- v_output_skip = l_sizet_const(0);
+ v_output_skip = LLVMConstInt(g->TypeSizeT, 0, false);
LLVMBuildBr(b, b_input);
LLVMPositionBuilderAtEnd(b, b_calloutput);
- v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
+ v_resvalue = l_load(b, g->TypeSizeT, v_resvaluep, "");
/* set arg[0] */
LLVMBuildStore(b,
v_resvalue,
- l_funcvaluep(b, v_fcinfo_out, 0));
+ l_funcvaluep(b, v_fcinfo_out, 0, g));
LLVMBuildStore(b,
- l_sbool_const(0),
- l_funcnullp(b, v_fcinfo_out, 0));
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false),
+ l_funcnullp(b, v_fcinfo_out, 0, g));
/* and call output function (can never return NULL) */
v_output = l_call(b,
LLVMGetFunctionType(v_fn_out),
@@ -1441,7 +1548,7 @@ llvm_compile_expr(ExprState *state)
incoming_values[1] = v_output;
incoming_blocks[1] = b_calloutput;
- v_output = LLVMBuildPhi(b, TypeSizeT, "output");
+ v_output = LLVMBuildPhi(b, g->TypeSizeT, "output");
LLVMAddIncoming(v_output,
incoming_values, incoming_blocks,
lengthof(incoming_blocks));
@@ -1455,7 +1562,7 @@ llvm_compile_expr(ExprState *state)
{
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_output,
- l_sizet_const(0), ""),
+ LLVMConstInt(g->TypeSizeT, 0, false), ""),
opblocks[opno + 1],
b_inputcall);
}
@@ -1468,15 +1575,15 @@ llvm_compile_expr(ExprState *state)
/* set arguments */
/* arg0: output */
LLVMBuildStore(b, v_output,
- l_funcvaluep(b, v_fcinfo_in, 0));
+ l_funcvaluep(b, v_fcinfo_in, 0, g));
LLVMBuildStore(b, v_resnull,
- l_funcnullp(b, v_fcinfo_in, 0));
+ l_funcnullp(b, v_fcinfo_in, 0, g));
/* arg1: ioparam: preset in execExpr.c */
/* arg2: typmod: preset in execExpr.c */
/* reset fcinfo_in->isnull */
- LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_fcinfo_in_isnullp);
/* and call function */
v_retval = l_call(b,
LLVMGetFunctionType(v_fn_in),
@@ -1490,8 +1597,8 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_IOCOERCE_SAFE:
- build_EvalXFunc(b, mod, "ExecEvalCoerceViaIOSafe",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalCoerceViaIOSafe",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1523,15 +1630,17 @@ llvm_compile_expr(ExprState *state)
b_bothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.bothargnull", opno);
b_anyargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.anyargnull", opno);
- v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
+ v_fcinfo = /// l_ptr_const(fcinfo, l_ptr(g->StructFunctionCallInfoData));
+ l_load_member_value_by_offset(b,lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep ,d.func.fcinfo_data ));
/* load args[0|1].isnull for both arguments */
- v_argnull0 = l_funcnull(b, v_fcinfo, 0);
+ v_argnull0 = l_funcnull(b, v_fcinfo, 0, g);
v_argisnull0 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
- l_sbool_const(1), "");
- v_argnull1 = l_funcnull(b, v_fcinfo, 1);
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), "");
+ v_argnull1 = l_funcnull(b, v_fcinfo, 1, g);
v_argisnull1 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
- l_sbool_const(1), "");
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), "");
v_anyargisnull = LLVMBuildOr(b, v_argisnull0, v_argisnull1, "");
v_bothargisnull = LLVMBuildAnd(b, v_argisnull0, v_argisnull1, "");
@@ -1554,27 +1663,27 @@ llvm_compile_expr(ExprState *state)
/* Both NULL? Then is not distinct... */
LLVMPositionBuilderAtEnd(b, b_bothargnull);
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
if (opcode == EEOP_NOT_DISTINCT)
- LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 1, false), v_resvaluep);
else
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
LLVMBuildBr(b, opblocks[opno + 1]);
/* Only one is NULL? Then is distinct... */
LLVMPositionBuilderAtEnd(b, b_anyargnull);
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
if (opcode == EEOP_NOT_DISTINCT)
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
else
- LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 1, false), v_resvaluep);
LLVMBuildBr(b, opblocks[opno + 1]);
/* neither argument is null: compare */
LLVMPositionBuilderAtEnd(b, b_noargnull);
- v_result = BuildV1Call(context, b, mod, fcinfo,
+ v_result = BuildV1CallLLVM(context, b, mod, fcinfo, v_fcinfo,
&v_fcinfo_isnull);
if (opcode == EEOP_DISTINCT)
@@ -1584,8 +1693,8 @@ llvm_compile_expr(ExprState *state)
LLVMBuildZExt(b,
LLVMBuildICmp(b, LLVMIntEQ,
v_result,
- l_sizet_const(0), ""),
- TypeSizeT, "");
+ LLVMConstInt(g->TypeSizeT, 0, false), ""),
+ g->TypeSizeT, "");
}
LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
@@ -1618,21 +1727,23 @@ llvm_compile_expr(ExprState *state)
b_argsequal = l_bb_before_v(opblocks[opno + 1],
"b.%d.argsequal", opno);
- v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
+ v_fcinfo = /// l_ptr_const(fcinfo, l_ptr(g->StructFunctionCallInfoData));
+ l_load_member_value_by_offset(b,lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep ,d.func.fcinfo_data));
/* save original arg[0] */
- v_arg0 = l_funcvalue(b, v_fcinfo, 0);
+ v_arg0 = l_funcvalue(b, v_fcinfo, 0, g);
/* if either argument is NULL they can't be equal */
- v_argnull0 = l_funcnull(b, v_fcinfo, 0);
- v_argnull1 = l_funcnull(b, v_fcinfo, 1);
+ v_argnull0 = l_funcnull(b, v_fcinfo, 0, g);
+ v_argnull1 = l_funcnull(b, v_fcinfo, 1, g);
v_anyargisnull =
LLVMBuildOr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
"");
LLVMBuildCondBr(b, v_anyargisnull, b_hasnull, b_nonull);
@@ -1662,14 +1773,14 @@ llvm_compile_expr(ExprState *state)
v_params[0] = v_arg0;
v_arg0_ro =
l_call(b,
- llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
- llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_var_func_type(context, "MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_func(context, "MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), "");
LLVMBuildStore(b, v_arg0_ro,
- l_funcvaluep(b, v_fcinfo, 0));
+ l_funcvaluep(b, v_fcinfo, 0, g));
}
- v_retval = BuildV1Call(context, b, mod, fcinfo, &v_fcinfo_isnull);
+ v_retval = BuildV1CallLLVM(context, b, mod, fcinfo, v_fcinfo, &v_fcinfo_isnull);
/*
* If result not null and arguments are equal return null,
@@ -1679,39 +1790,39 @@ llvm_compile_expr(ExprState *state)
v_argsequal = LLVMBuildAnd(b,
LLVMBuildICmp(b, LLVMIntEQ,
v_fcinfo_isnull,
- l_sbool_const(0),
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false),
""),
LLVMBuildICmp(b, LLVMIntEQ,
v_retval,
- l_sizet_const(1),
+ LLVMConstInt(g->TypeSizeT, 1, false),
""),
"");
LLVMBuildCondBr(b, v_argsequal, b_argsequal, b_hasnull);
/* build block setting result to NULL, if args are equal */
LLVMPositionBuilderAtEnd(b, b_argsequal);
- LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
}
case EEOP_SQLVALUEFUNCTION:
- build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalSQLValueFunction",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_CURRENTOFEXPR:
- build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalCurrentOfExpr",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_NEXTVALUEEXPR:
- build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalNextValueExpr",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1730,11 +1841,11 @@ llvm_compile_expr(ExprState *state)
* OLD/NEW row doesn't exist, skip that and return NULL.
*/
v_flagsp = l_struct_gep(b,
- StructExprState,
+ g->StructExprState,
v_state,
FIELDNO_EXPRSTATE_FLAGS,
"v.state.flags");
- v_flags = l_load(b, TypeStorageBool, v_flagsp, "");
+ v_flags = l_load(b, g->TypeStorageBool, v_flagsp, "");
v_nullflag = l_int8_const(lc, op->d.returningexpr.nullflag);
@@ -1742,33 +1853,33 @@ llvm_compile_expr(ExprState *state)
LLVMBuildICmp(b, LLVMIntEQ,
LLVMBuildAnd(b, v_flags,
v_nullflag, ""),
- l_sbool_const(0), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false), ""),
opblocks[opno + 1], b_isnull);
LLVMPositionBuilderAtEnd(b, b_isnull);
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
- LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_resnullp);
LLVMBuildBr(b, opblocks[op->d.returningexpr.jumpdone]);
break;
}
case EEOP_ARRAYEXPR:
- build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalArrayExpr",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_ARRAYCOERCE:
- build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalArrayCoerce",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_ROW:
- build_EvalXFunc(b, mod, "ExecEvalRow",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalRow",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1779,6 +1890,7 @@ llvm_compile_expr(ExprState *state)
LLVMBasicBlockRef b_null;
LLVMBasicBlockRef b_compare;
LLVMBasicBlockRef b_compare_result;
+ LLVMValueRef v_fcinfo;
LLVMValueRef v_retval;
@@ -1790,34 +1902,34 @@ llvm_compile_expr(ExprState *state)
l_bb_before_v(opblocks[opno + 1],
"op.%d.row-compare-result",
opno);
-
+ v_fcinfo = l_load_member_value_by_offset(b, lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep ,d.rowcompare_step.fcinfo_data));
/*
* If function is strict, and either arg is null, we're
* done.
*/
if (op->d.rowcompare_step.finfo->fn_strict)
{
- LLVMValueRef v_fcinfo;
LLVMValueRef v_argnull0;
LLVMValueRef v_argnull1;
LLVMValueRef v_anyargisnull;
- v_fcinfo = l_ptr_const(fcinfo,
- l_ptr(StructFunctionCallInfoData));
+ ///v_fcinfo = l_ptr_const(fcinfo,
+ /// l_ptr(g->StructFunctionCallInfoData));
- v_argnull0 = l_funcnull(b, v_fcinfo, 0);
- v_argnull1 = l_funcnull(b, v_fcinfo, 1);
+ v_argnull0 = l_funcnull(b, v_fcinfo, 0, g);
+ v_argnull1 = l_funcnull(b, v_fcinfo, 1, g);
v_anyargisnull =
LLVMBuildOr(b,
LLVMBuildICmp(b,
LLVMIntEQ,
v_argnull0,
- l_sbool_const(1),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false),
""),
LLVMBuildICmp(b, LLVMIntEQ,
v_argnull1,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
"");
LLVMBuildCondBr(b, v_anyargisnull, b_null, b_compare);
@@ -1831,7 +1943,7 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_compare);
/* call function */
- v_retval = BuildV1Call(context, b, mod, fcinfo,
+ v_retval = BuildV1CallLLVM(context, b, mod, fcinfo, v_fcinfo,
&v_fcinfo_isnull);
LLVMBuildStore(b, v_retval, v_resvaluep);
@@ -1840,7 +1952,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildICmp(b,
LLVMIntEQ,
v_fcinfo_isnull,
- l_sbool_const(0),
+ LLVMConstInt(g->TypeStorageBool, (int)(0), false),
""),
b_compare_result,
b_null);
@@ -1853,7 +1965,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildICmp(b,
LLVMIntEQ,
v_retval,
- l_sizet_const(0), ""),
+ LLVMConstInt(g->TypeSizeT, 0, false), ""),
opblocks[opno + 1],
opblocks[op->d.rowcompare_step.jumpdone]);
@@ -1862,7 +1974,7 @@ llvm_compile_expr(ExprState *state)
* result.
*/
LLVMPositionBuilderAtEnd(b, b_null);
- LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_resnullp);
LLVMBuildBr(b, opblocks[op->d.rowcompare_step.jumpnull]);
break;
@@ -1883,7 +1995,7 @@ llvm_compile_expr(ExprState *state)
*/
v_cmpresult =
LLVMBuildTrunc(b,
- l_load(b, TypeSizeT, v_resvaluep, ""),
+ l_load(b, g->TypeSizeT, v_resvaluep, ""),
LLVMInt32TypeInContext(lc), "");
switch (cmptype)
@@ -1912,9 +2024,9 @@ llvm_compile_expr(ExprState *state)
v_cmpresult,
l_int32_const(lc, 0),
"");
- v_result = LLVMBuildZExt(b, v_result, TypeSizeT, "");
+ v_result = LLVMBuildZExt(b, v_result, g->TypeSizeT, "");
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
LLVMBuildStore(b, v_result, v_resvaluep);
LLVMBuildBr(b, opblocks[opno + 1]);
@@ -1922,26 +2034,26 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_MINMAX:
- build_EvalXFunc(b, mod, "ExecEvalMinMax",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalMinMax",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_FIELDSELECT:
- build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalFieldSelect",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_FIELDSTORE_DEFORM:
- build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalFieldStoreDeForm",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_FIELDSTORE_FORM:
- build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalFieldStoreForm",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -1952,13 +2064,13 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_casenullp,
v_casenull;
- v_casevaluep = l_ptr_const(op->d.casetest.value,
- l_ptr(TypeSizeT));
- v_casenullp = l_ptr_const(op->d.casetest.isnull,
- l_ptr(TypeStorageBool));
+ v_casevaluep = l_ptr_const_step(d.casetest.value,
+ l_ptr(g->TypeSizeT));
+ v_casenullp = l_ptr_const_step(d.casetest.isnull,
+ l_ptr(g->TypeStorageBool));
- v_casevalue = l_load(b, TypeSizeT, v_casevaluep, "");
- v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
+ v_casevalue = l_load(b, g->TypeSizeT, v_casevaluep, "");
+ v_casenull = l_load(b, g->TypeStorageBool, v_casenullp, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp);
@@ -1973,13 +2085,13 @@ llvm_compile_expr(ExprState *state)
v_casevalue =
l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_DOMAINDATUM,
"");
v_casenull =
l_load_struct_gep(b,
- StructExprContext,
+ g->StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_DOMAINNULL,
"");
@@ -1991,14 +2103,14 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_DOMAIN_NOTNULL:
- build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalConstraintNotNull",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_DOMAIN_CHECK:
- build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalConstraintCheck",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -2006,10 +2118,10 @@ llvm_compile_expr(ExprState *state)
{
LLVMValueRef v_initvalue;
- v_initvalue = l_sizet_const(op->d.hashdatum_initvalue.init_value);
+ v_initvalue = LLVMConstInt(g->TypeSizeT, op->d.hashdatum_initvalue.init_value, false);
LLVMBuildStore(b, v_initvalue, v_resvaluep);
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
}
@@ -2044,25 +2156,31 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_tmp2;
LLVMValueRef tmp;
- tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
- l_ptr(TypeSizeT));
+ ///tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
+ /// l_ptr(TypeSizeT));
+ tmp = l_ptr_const_step(d.hashdatum.iresult, l_ptr(g->StructNullableDatum));
+ tmp = l_struct_gep(b, g->StructNullableDatum, tmp,
+ FIELDNO_NULLABLE_DATUM_DATUM,
+ "");
+
+ ///l_ptr(TypeSizeT));
/*
* Fetch the previously hashed value from where the
* previous hash operation stored it.
*/
- v_prevhash = l_load(b, TypeSizeT, tmp, "prevhash");
+ v_prevhash = l_load(b, g->TypeSizeT, tmp, "prevhash");
/*
* Rotate bits left by 1 bit. Be careful not to
* overflow uint32 when working with size_t.
*/
- v_tmp1 = LLVMBuildShl(b, v_prevhash, l_sizet_const(1),
+ v_tmp1 = LLVMBuildShl(b, v_prevhash, LLVMConstInt(g->TypeSizeT, 1, false),
"");
v_tmp1 = LLVMBuildAnd(b, v_tmp1,
- l_sizet_const(0xffffffff), "");
+ LLVMConstInt(g->TypeSizeT, 0xffffffff, false), "");
v_tmp2 = LLVMBuildLShr(b, v_prevhash,
- l_sizet_const(31), "");
+ LLVMConstInt(g->TypeSizeT, 31, false), "");
v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2,
"rotatedhash");
}
@@ -2079,8 +2197,10 @@ llvm_compile_expr(ExprState *state)
if (fcinfo->nargs != 1)
elog(ERROR, "incorrect number of function arguments");
- v_fcinfo = l_ptr_const(fcinfo,
- l_ptr(StructFunctionCallInfoData));
+ v_fcinfo = ///l_ptr_const(fcinfo,
+ /// l_ptr(g->StructFunctionCallInfoData));
+ l_load_member_value_by_offset(b, lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep, d.hashdatum.fcinfo_data));
b_checkargnull = l_bb_before_v(b_ifnotnull,
"b.%d.isnull.0", opno);
@@ -2104,8 +2224,8 @@ llvm_compile_expr(ExprState *state)
* In strict node, NULL inputs result in NULL. Save
* the NULL result and goto jumpdone.
*/
- LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(1), false), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
LLVMBuildBr(b, opblocks[op->d.hashdatum.jumpdone]);
}
else
@@ -2117,7 +2237,7 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_ifnullblock);
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
if (opcode == EEOP_HASHDATUM_NEXT32)
{
@@ -2137,7 +2257,7 @@ llvm_compile_expr(ExprState *state)
* Store a zero Datum when the Datum to hash is
* NULL
*/
- LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeSizeT, 0, false), v_resvaluep);
}
LLVMBuildBr(b, opblocks[opno + 1]);
@@ -2146,12 +2266,12 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_checkargnull);
/* emit code to check if the input parameter is NULL */
- v_argisnull = l_funcnull(b, v_fcinfo, 0);
+ v_argisnull = l_funcnull(b, v_fcinfo, 0, g);
LLVMBuildCondBr(b,
LLVMBuildICmp(b,
LLVMIntEQ,
v_argisnull,
- l_sbool_const(1),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false),
""),
b_ifnullblock,
b_ifnotnull);
@@ -2169,31 +2289,34 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_tmp2;
LLVMValueRef tmp;
- tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
- l_ptr(TypeSizeT));
-
+ ///tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
+ /// l_ptr(TypeSizeT));
+ tmp = l_ptr_const_step(d.hashdatum.iresult, l_ptr(g->StructNullableDatum));
+ tmp = l_struct_gep(b, g->StructNullableDatum, tmp,
+ FIELDNO_NULLABLE_DATUM_DATUM,
+ "");
/*
* Fetch the previously hashed value from where the
* previous hash operation stored it.
*/
- v_prevhash = l_load(b, TypeSizeT, tmp, "prevhash");
+ v_prevhash = l_load(b, g->TypeSizeT, tmp, "prevhash");
/*
* Rotate bits left by 1 bit. Be careful not to
* overflow uint32 when working with size_t.
*/
- v_tmp1 = LLVMBuildShl(b, v_prevhash, l_sizet_const(1),
+ v_tmp1 = LLVMBuildShl(b, v_prevhash, LLVMConstInt(g->TypeSizeT, 1, false),
"");
v_tmp1 = LLVMBuildAnd(b, v_tmp1,
- l_sizet_const(0xffffffff), "");
+ LLVMConstInt(g->TypeSizeT, 0xffffffff, false), "");
v_tmp2 = LLVMBuildLShr(b, v_prevhash,
- l_sizet_const(31), "");
+ LLVMConstInt(g->TypeSizeT, 31, false), "");
v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2,
"rotatedhash");
}
/* call the hash function */
- v_retval = BuildV1Call(context, b, mod, fcinfo,
+ v_retval = BuildV1CallLLVM(context, b, mod, fcinfo, v_fcinfo,
&v_fcinfo_isnull);
/*
@@ -2206,45 +2329,45 @@ llvm_compile_expr(ExprState *state)
"xorhash");
LLVMBuildStore(b, v_retval, v_resvaluep);
- LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_resnullp);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
}
case EEOP_CONVERT_ROWTYPE:
- build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalConvertRowtype",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_SCALARARRAYOP:
- build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalScalarArrayOp",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_HASHED_SCALARARRAYOP:
- build_EvalXFunc(b, mod, "ExecEvalHashedScalarArrayOp",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalHashedScalarArrayOp",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_XMLEXPR:
- build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalXmlExpr",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_JSON_CONSTRUCTOR:
- build_EvalXFunc(b, mod, "ExecEvalJsonConstructor",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalJsonConstructor",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_IS_JSON:
- build_EvalXFunc(b, mod, "ExecEvalJsonIsPredicate",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalJsonIsPredicate",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -2257,8 +2380,8 @@ llvm_compile_expr(ExprState *state)
* Call ExecEvalJsonExprPath(). It returns the address of
* the step to perform next.
*/
- v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExprPath",
- v_state, op, v_econtext);
+ v_ret = build_EvalXFunc(b, context, "ExecEvalJsonExprPath",
+ v_state, v_op, v_econtext);
/*
* Build a switch to map the return value (v_ret above),
@@ -2343,15 +2466,15 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_JSONEXPR_COERCION:
- build_EvalXFunc(b, mod, "ExecEvalJsonCoercion",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalJsonCoercion",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_JSONEXPR_COERCION_FINISH:
- build_EvalXFunc(b, mod, "ExecEvalJsonCoercionFinish",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalJsonCoercionFinish",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -2365,8 +2488,8 @@ llvm_compile_expr(ExprState *state)
v_aggno = l_int32_const(lc, op->d.aggref.aggno);
/* load agg value / null */
- value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_aggno, "aggvalue");
- isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
+ value = l_load_gep1(b, g->TypeSizeT, v_aggvalues, v_aggno, "aggvalue");
+ isnull = l_load_gep1(b, g->TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
/* and store result */
LLVMBuildStore(b, value, v_resvaluep);
@@ -2377,8 +2500,8 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_GROUPING_FUNC:
- build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
- v_state, op);
+ build_EvalXFunc(b, context, "ExecEvalGroupingFunc",
+ v_state, v_op);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -2395,14 +2518,17 @@ llvm_compile_expr(ExprState *state)
* up in ExecInitWindowAgg() after initializing the
* expression). So load it from memory each time round.
*/
- v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
- l_ptr(LLVMInt32TypeInContext(lc)));
+ v_wfuncnop = ///l_ptr_const(&wfunc->wfuncno,
+ /// l_ptr(LLVMInt32TypeInContext(lc)));
+ l_ptr_const_step(d.window_func.wfstate, l_ptr(g->StructWindowFuncExprState));
+ v_wfuncnop = l_struct_member_ptr_by_offset(b, lc, v_wfuncnop, offsetof(WindowFuncExprState, wfuncno) );
+
v_wfuncno = l_load(b, LLVMInt32TypeInContext(lc), v_wfuncnop, "v_wfuncno");
/* load window func value / null */
- value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_wfuncno,
+ value = l_load_gep1(b, g->TypeSizeT, v_aggvalues, v_wfuncno,
"windowvalue");
- isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_wfuncno,
+ isnull = l_load_gep1(b, g->TypeStorageBool, v_aggnulls, v_wfuncno,
"windownull");
LLVMBuildStore(b, value, v_resvaluep);
@@ -2413,14 +2539,14 @@ llvm_compile_expr(ExprState *state)
}
case EEOP_MERGE_SUPPORT_FUNC:
- build_EvalXFunc(b, mod, "ExecEvalMergeSupportFunc",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalMergeSupportFunc",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_SUBPLAN:
- build_EvalXFunc(b, mod, "ExecEvalSubPlan",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalSubPlan",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -2434,41 +2560,53 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_fcinfo_isnull;
LLVMValueRef v_tmpcontext;
LLVMValueRef v_oldcontext;
+ LLVMValueRef v_fcinfo;
if (opcode == EEOP_AGG_STRICT_DESERIALIZE)
{
- LLVMValueRef v_fcinfo;
LLVMValueRef v_argnull0;
LLVMBasicBlockRef b_deserialize;
b_deserialize = l_bb_before_v(opblocks[opno + 1],
"op.%d.deserialize", opno);
- v_fcinfo = l_ptr_const(fcinfo,
- l_ptr(StructFunctionCallInfoData));
- v_argnull0 = l_funcnull(b, v_fcinfo, 0);
+ v_fcinfo = ///l_ptr_const(fcinfo,
+ /// l_ptr(g->StructFunctionCallInfoData));
+ l_load_member_value_by_offset(b, lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep, d.agg_deserialize.fcinfo_data));
+ v_argnull0 = l_funcnull(b, v_fcinfo, 0, g);
LLVMBuildCondBr(b,
LLVMBuildICmp(b,
LLVMIntEQ,
v_argnull0,
- l_sbool_const(1),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false),
""),
opblocks[op->d.agg_deserialize.jumpnull],
b_deserialize);
LLVMPositionBuilderAtEnd(b, b_deserialize);
}
+ else
+ {
+ v_fcinfo = l_load_member_value_by_offset(b, lc, v_op,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(ExprEvalStep, d.agg_deserialize.fcinfo_data));
+ }
aggstate = castNode(AggState, state->parent);
fcinfo = op->d.agg_deserialize.fcinfo_data;
- v_tmpcontext =
- l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
- l_ptr(StructMemoryContextData));
- v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
- v_retval = BuildV1Call(context, b, mod, fcinfo,
+ ///v_tmpcontext =
+ ///l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
+ /// l_ptr(g->StructMemoryContextData));
+ /// l_load_struct_gep(b, StructExprState, v_state, FIELDNO_EXPRSTATE_PARENT,"");
+ v_tmpcontext = l_load_struct_gep(b, g->StructExprState, v_state, FIELDNO_EXPRSTATE_PARENT,"");
+ v_tmpcontext = l_load_struct_gep(b, g->StructAggState, v_tmpcontext, FIELDNO_AGGSTATE_TMPCONTEXT,"");
+ v_tmpcontext = l_load_struct_gep(b, g->StructExprContext, v_tmpcontext, FIELDNO_EXPRCONTEXT_PERTUPLEMEMORY,"");
+
+ v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext, g);
+ v_retval = BuildV1CallLLVM(context, b, mod, fcinfo, v_fcinfo,
&v_fcinfo_isnull);
- l_mcxt_switch(mod, b, v_oldcontext);
+ l_mcxt_switch(mod, b, v_oldcontext, g);
LLVMBuildStore(b, v_retval, v_resvaluep);
LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
@@ -2492,8 +2630,10 @@ llvm_compile_expr(ExprState *state)
Assert(nargs > 0);
jumpnull = op->d.agg_strict_input_check.jumpnull;
- v_argsp = l_ptr_const(args, l_ptr(StructNullableDatum));
- v_nullsp = l_ptr_const(nulls, l_ptr(TypeStorageBool));
+ v_argsp = ///l_ptr_const(args, l_ptr(g->StructNullableDatum));
+ l_ptr_const_step(d.agg_strict_input_check.args, l_ptr(g->StructNullableDatum));
+ v_nullsp = ///l_ptr_const(nulls, l_ptr(g->TypeStorageBool));
+ l_ptr_const_step(d.agg_strict_input_check.nulls, l_ptr(g->TypeStorageBool));
/* create blocks for checking args */
b_checknulls = palloc(sizeof(LLVMBasicBlockRef *) * nargs);
@@ -2522,14 +2662,14 @@ llvm_compile_expr(ExprState *state)
b_argnotnull = b_checknulls[argno + 1];
if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
- v_argisnull = l_load_gep1(b, TypeStorageBool, v_nullsp, v_argno, "");
+ v_argisnull = l_load_gep1(b, g->TypeStorageBool, v_nullsp, v_argno, "");
else
{
LLVMValueRef v_argn;
- v_argn = l_gep(b, StructNullableDatum, v_argsp, &v_argno, 1, "");
+ v_argn = l_gep(b, g->StructNullableDatum, v_argsp, &v_argno, 1, "");
v_argisnull =
- l_load_struct_gep(b, StructNullableDatum, v_argn,
+ l_load_struct_gep(b, g->StructNullableDatum, v_argn,
FIELDNO_NULLABLE_DATUM_ISNULL,
"");
}
@@ -2538,7 +2678,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildICmp(b,
LLVMIntEQ,
v_argisnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
opblocks[jumpnull],
b_argnotnull);
}
@@ -2561,23 +2701,23 @@ llvm_compile_expr(ExprState *state)
* [op->d.agg_plain_pergroup_nullcheck.setoff];
*/
v_aggstatep = LLVMBuildBitCast(b, v_parent,
- l_ptr(StructAggState), "");
+ l_ptr(g->StructAggState), "");
v_allpergroupsp = l_load_struct_gep(b,
- StructAggState,
+ g->StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups");
v_setoff = l_int32_const(lc, op->d.agg_plain_pergroup_nullcheck.setoff);
- v_pergroup_allaggs = l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
+ v_pergroup_allaggs = l_load_gep1(b, l_ptr(g->StructAggStatePerGroupData),
v_allpergroupsp, v_setoff, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ,
- LLVMBuildPtrToInt(b, v_pergroup_allaggs, TypeSizeT, ""),
- l_sizet_const(0), ""),
+ LLVMBuildPtrToInt(b, v_pergroup_allaggs, g->TypeSizeT, ""),
+ LLVMConstInt(g->TypeSizeT, 0, false), ""),
opblocks[jumpnull],
opblocks[opno + 1]);
break;
@@ -2626,17 +2766,18 @@ llvm_compile_expr(ExprState *state)
fcinfo = pertrans->transfn_fcinfo;
v_aggstatep =
- LLVMBuildBitCast(b, v_parent, l_ptr(StructAggState), "");
- v_pertransp = l_ptr_const(pertrans,
- l_ptr(StructAggStatePerTransData));
-
+ LLVMBuildBitCast(b, v_parent, l_ptr(g->StructAggState), "");
+ v_pertransp = ///l_ptr_const(pertrans,
+ /// l_ptr(g->StructAggStatePerTransData));
+ l_ptr_const_step(d.agg_trans.pertrans,
+ l_ptr(g->StructAggStatePerTransData));
/*
* pergroup = &aggstate->all_pergroups
* [op->d.agg_trans.setoff] [op->d.agg_trans.transno];
*/
v_allpergroupsp =
l_load_struct_gep(b,
- StructAggState,
+ g->StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups");
@@ -2644,8 +2785,8 @@ llvm_compile_expr(ExprState *state)
v_transno = l_int32_const(lc, op->d.agg_trans.transno);
v_pergroupp =
l_gep(b,
- StructAggStatePerGroupData,
- l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
+ g->StructAggStatePerGroupData,
+ l_load_gep1(b, l_ptr(g->StructAggStatePerGroupData),
v_allpergroupsp, v_setoff, ""),
&v_transno, 1, "");
@@ -2659,7 +2800,7 @@ llvm_compile_expr(ExprState *state)
v_notransvalue =
l_load_struct_gep(b,
- StructAggStatePerGroupData,
+ g->StructAggStatePerGroupData,
v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE,
"notransvalue");
@@ -2671,7 +2812,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_notransvalue,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
b_init,
b_no_init);
@@ -2681,8 +2822,8 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_init);
- v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
- l_ptr(StructExprContext));
+ v_aggcontext = l_ptr_const_step(d.agg_trans.aggcontext,
+ l_ptr(g->StructExprContext));
params[0] = v_aggstatep;
params[1] = v_pertransp;
@@ -2690,8 +2831,8 @@ llvm_compile_expr(ExprState *state)
params[3] = v_aggcontext;
l_call(b,
- llvm_pg_var_func_type("ExecAggInitGroup"),
- llvm_pg_func(mod, "ExecAggInitGroup"),
+ llvm_pg_var_func_type(context, "ExecAggInitGroup"),
+ llvm_pg_func(context, "ExecAggInitGroup"),
params, lengthof(params),
"");
@@ -2713,14 +2854,14 @@ llvm_compile_expr(ExprState *state)
"op.%d.strictpass", opno);
v_transnull =
l_load_struct_gep(b,
- StructAggStatePerGroupData,
+ g->StructAggStatePerGroupData,
v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
"transnull");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_transnull,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
opblocks[opno + 1],
b_strictpass);
@@ -2728,26 +2869,32 @@ llvm_compile_expr(ExprState *state)
}
- v_fcinfo = l_ptr_const(fcinfo,
- l_ptr(StructFunctionCallInfoData));
- v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
- l_ptr(StructExprContext));
+ v_fcinfo = ///l_ptr_const(fcinfo,
+ /// l_ptr(g->StructFunctionCallInfoData));
+ l_load_member_value_by_offset(b, lc, v_op,
+ l_ptr(g->StructAggStatePerTransData), offsetof(ExprEvalStep, d.agg_trans.pertrans));
+ v_fcinfo = ///l_ptr_const(fcinfo,
+ /// l_ptr(g->StructFunctionCallInfoData));
+ l_load_member_value_by_offset(b, lc, v_fcinfo,
+ l_ptr(g->StructFunctionCallInfoData), offsetof(AggStatePerTransData, transfn_fcinfo));
+ v_aggcontext = l_ptr_const_step(d.agg_trans.aggcontext,
+ l_ptr(g->StructExprContext));
v_current_setp =
l_struct_gep(b,
- StructAggState,
+ g->StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_CURRENT_SET,
"aggstate.current_set");
v_curaggcontext =
l_struct_gep(b,
- StructAggState,
+ g->StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_CURAGGCONTEXT,
"aggstate.curaggcontext");
v_current_pertransp =
l_struct_gep(b,
- StructAggState,
+ g->StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_CURPERTRANS,
"aggstate.curpertrans");
@@ -2759,36 +2906,40 @@ llvm_compile_expr(ExprState *state)
LLVMBuildStore(b, v_pertransp, v_current_pertransp);
/* invoke transition function in per-tuple context */
- v_tmpcontext =
- l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
- l_ptr(StructMemoryContextData));
- v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
+ ///v_tmpcontext =
+ /// l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
+ /// l_ptr(g->StructMemoryContextData));
+ v_tmpcontext = l_load_struct_gep(b, g->StructExprState, v_state, FIELDNO_EXPRSTATE_PARENT,"");
+ v_tmpcontext = l_load_struct_gep(b, g->StructAggState, v_tmpcontext, FIELDNO_AGGSTATE_TMPCONTEXT,"");
+ v_tmpcontext = l_load_struct_gep(b, g->StructExprContext, v_tmpcontext, FIELDNO_EXPRCONTEXT_PERTUPLEMEMORY,"");
+
+ v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext, g);
/* store transvalue in fcinfo->args[0] */
v_transvaluep =
l_struct_gep(b,
- StructAggStatePerGroupData,
+ g->StructAggStatePerGroupData,
v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE,
"transvalue");
v_transnullp =
l_struct_gep(b,
- StructAggStatePerGroupData,
+ g->StructAggStatePerGroupData,
v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
"transnullp");
LLVMBuildStore(b,
l_load(b,
- TypeSizeT,
+ g->TypeSizeT,
v_transvaluep,
"transvalue"),
- l_funcvaluep(b, v_fcinfo, 0));
+ l_funcvaluep(b, v_fcinfo, 0, g));
LLVMBuildStore(b,
- l_load(b, TypeStorageBool, v_transnullp, "transnull"),
- l_funcnullp(b, v_fcinfo, 0));
+ l_load(b, g->TypeStorageBool, v_transnullp, "transnull"),
+ l_funcnullp(b, v_fcinfo, 0, g));
/* and invoke transition function */
- v_retval = BuildV1Call(context, b, mod, fcinfo,
+ v_retval = BuildV1CallLLVM(context, b, mod, fcinfo, v_fcinfo,
&v_fcinfo_isnull);
/*
@@ -2817,8 +2968,8 @@ llvm_compile_expr(ExprState *state)
b_nocall = l_bb_before_v(opblocks[opno + 1],
"op.%d.transnocall", opno);
- v_transvalue = l_load(b, TypeSizeT, v_transvaluep, "");
- v_transnull = l_load(b, TypeStorageBool, v_transnullp, "");
+ v_transvalue = l_load(b, g->TypeSizeT, v_transvaluep, "");
+ v_transnull = l_load(b, g->TypeStorageBool, v_transnullp, "");
/*
* DatumGetPointer(newVal) !=
@@ -2837,12 +2988,12 @@ llvm_compile_expr(ExprState *state)
params[1] = v_pertransp;
params[2] = v_retval;
params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull,
- TypeParamBool, "");
+ g->TypeParamBool, "");
params[4] = v_transvalue;
params[5] = LLVMBuildTrunc(b, v_transnull,
- TypeParamBool, "");
+ g->TypeParamBool, "");
- v_fn = llvm_pg_func(mod, "ExecAggCopyTransValue");
+ v_fn = llvm_pg_func(context, "ExecAggCopyTransValue");
v_newval =
l_call(b,
LLVMGetFunctionType(v_fn),
@@ -2854,7 +3005,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildStore(b, v_newval, v_transvaluep);
LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
- l_mcxt_switch(mod, b, v_oldcontext);
+ l_mcxt_switch(mod, b, v_oldcontext, g);
LLVMBuildBr(b, opblocks[opno + 1]);
/* returned datum passed datum, no need to reparent */
@@ -2865,7 +3016,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildStore(b, v_retval, v_transvaluep);
LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
- l_mcxt_switch(mod, b, v_oldcontext);
+ l_mcxt_switch(mod, b, v_oldcontext, g);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -2877,19 +3028,21 @@ llvm_compile_expr(ExprState *state)
AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
- LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctSingle");
+ LLVMValueRef v_fn = llvm_pg_func(context, "ExecEvalPreOrderedDistinctSingle");
LLVMValueRef v_args[2];
LLVMValueRef v_ret;
- v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState));
- v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData));
+ ///v_args[0] = l_ptr_const(aggstate, l_ptr(g->StructAggState));
+ v_args[0] = v_parent;
+ /// v_args[1] = l_ptr_const(pertrans, l_ptr(g->StructAggStatePerTransData));
+ v_args[1] = l_ptr_const_step(d.agg_presorted_distinctcheck.pertrans, l_ptr(g->StructAggStatePerTransData));
v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, "");
- v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
+ v_ret = LLVMBuildZExt(b, v_ret, g->TypeStorageBool, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_ret,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
opblocks[opno + 1],
opblocks[jumpdistinct]);
break;
@@ -2901,33 +3054,35 @@ llvm_compile_expr(ExprState *state)
AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
- LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctMulti");
+ LLVMValueRef v_fn = llvm_pg_func(context, "ExecEvalPreOrderedDistinctMulti");
LLVMValueRef v_args[2];
LLVMValueRef v_ret;
- v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState));
- v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData));
+ ///v_args[0] = l_ptr_const(aggstate, l_ptr(g->StructAggState));
+ v_args[0] = v_parent;
+ ///v_args[1] = l_ptr_const(pertrans, l_ptr(g->StructAggStatePerTransData));
+ v_args[1] = l_ptr_const_step(d.agg_presorted_distinctcheck.pertrans, l_ptr(g->StructAggStatePerTransData));
v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, "");
- v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
+ v_ret = LLVMBuildZExt(b, v_ret, g->TypeStorageBool, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_ret,
- l_sbool_const(1), ""),
+ LLVMConstInt(g->TypeStorageBool, (int)(1), false), ""),
opblocks[opno + 1],
opblocks[jumpdistinct]);
break;
}
case EEOP_AGG_ORDERED_TRANS_DATUM:
- build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalAggOrderedTransDatum",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
case EEOP_AGG_ORDERED_TRANS_TUPLE:
- build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
- v_state, op, v_econtext);
+ build_EvalXFunc(b, context, "ExecEvalAggOrderedTransTuple",
+ v_state, v_op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]);
break;
@@ -2955,7 +3110,12 @@ llvm_compile_expr(ExprState *state)
state->evalfunc = ExecRunCompiledExpr;
state->evalfunc_private = cstate;
}
-
+ {
+ char *error = NULL;
+ ///LLVMDumpModule(context->module);
+ LLVMVerifyModule(context->module, LLVMAbortProcessAction, &error);
+ LLVMDisposeMessage(error);
+ }
llvm_leave_fatal_on_oom();
INSTR_TIME_SET_CURRENT(endtime);
@@ -2992,7 +3152,7 @@ ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull)
return func(state, econtext, isNull);
}
-
+#ifdef DELETE_IT
static LLVMValueRef
BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
LLVMModuleRef mod, FunctionCallInfo fcinfo,
@@ -3008,18 +3168,18 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
v_fn = llvm_function_reference(context, b, mod, fcinfo);
- v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
+ v_fcinfo = l_ptr_const(fcinfo, l_ptr(g->StructFunctionCallInfoData));
v_fcinfo_isnullp = l_struct_gep(b,
- StructFunctionCallInfoData,
+ g->StructFunctionCallInfoData,
v_fcinfo,
FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
"v_fcinfo_isnull");
- LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp);
+ LLVMBuildStore(b, LLVMConstInt(g->TypeStorageBool, (int)(0), false), v_fcinfo_isnullp);
v_retval = l_call(b, LLVMGetFunctionType(AttributeTemplate), v_fn, &v_fcinfo, 1, "funccall");
if (v_fcinfo_isnull)
- *v_fcinfo_isnull = l_load(b, TypeStorageBool, v_fcinfo_isnullp, "");
+ *v_fcinfo_isnull = l_load(b, g->TypeStorageBool, v_fcinfo_isnullp, "");
/*
* Add lifetime-end annotation, signaling that writes to memory don't have
@@ -3040,7 +3200,57 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
return v_retval;
}
+#endif
+static LLVMValueRef
+BuildV1CallLLVM(LLVMJitContext *context, LLVMBuilderRef b,
+ LLVMModuleRef mod, FunctionCallInfo fcinfo2,
+ LLVMValueRef v_fcinfo, LLVMValueRef *v_fcinfo_isnull)
+{
+ LLVMContextRef lc;
+ LLVMValueRef v_fn;
+ LLVMValueRef v_fcinfo_isnullp;
+ LLVMValueRef v_retval;
+
+ lc = LLVMGetModuleContext(mod);
+ v_fn = llvm_function_reference(context, b, mod, fcinfo2, v_fcinfo);
+
+ ///v_fcinfo = l_ptr_const(fcinfo, l_ptr(g->StructFunctionCallInfoData));
+ v_fcinfo_isnullp = l_struct_gep(b,
+ context->jit_types->StructFunctionCallInfoData,
+ v_fcinfo,
+ FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
+ "v_fcinfo_isnull");
+ LLVMBuildStore(b, LLVMConstInt(context->jit_types->TypeStorageBool, (int)(0), false), v_fcinfo_isnullp);
+
+ v_retval = l_call(b, LLVMGetFunctionType(context->jit_types->AttributeTemplate), v_fn, &v_fcinfo, 1, "funccall");
+
+ if (v_fcinfo_isnull)
+ *v_fcinfo_isnull = l_load(b, context->jit_types->TypeStorageBool, v_fcinfo_isnullp, "");
+
+ /*
+ * Add lifetime-end annotation, signaling that writes to memory don't have
+ * to be retained (important for inlining potential).
+ */
+ {
+ LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
+ LLVMValueRef params[2];
+ /* TODO check fcinfo2->nargs is const or is changed from call to call */
+ params[0] = l_int64_const(lc, sizeof(NullableDatum) * fcinfo2->nargs);
+ params[1] = ///l_ptr_const(fcinfo->args, l_ptr(LLVMInt8TypeInContext(lc)));
+ l_load_member_value_by_offset(b, lc , v_fcinfo, l_ptr(LLVMInt8TypeInContext(lc)), offsetof(FunctionCallInfoBaseData, args) );
+ l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
+
+ params[0] = l_int64_const(lc, sizeof(fcinfo2->isnull));
+ params[1] = /// l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8TypeInContext(lc)));
+ l_struct_member_ptr_by_offset(b, lc, v_fcinfo, offsetof(FunctionCallInfoBaseData, isnull));
+ l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
+ }
+
+ return v_retval;
+}
+
+#ifdef DELETE_IT
/*
* Implement an expression step by calling the function funcname.
*/
@@ -3049,7 +3259,40 @@ build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
LLVMValueRef v_state, ExprEvalStep *op,
int nargs, LLVMValueRef *v_args)
{
- LLVMValueRef v_fn = llvm_pg_func(mod, funcname);
+ LLVMValueRef v_fn = llvm_pg_func(context, funcname);
+ LLVMValueRef *params;
+ int argno = 0;
+ LLVMValueRef v_ret;
+
+ /* cheap pre-check as llvm just asserts out */
+ if (LLVMCountParams(v_fn) != (nargs + 2))
+ elog(ERROR, "parameter mismatch: %s expects %d passed %d",
+ funcname, LLVMCountParams(v_fn), nargs + 2);
+
+ params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
+
+ params[argno++] = v_state;
+ params[argno++] = l_ptr_const(op, l_ptr(g->StructExprEvalStep));
+
+ for (int i = 0; i < nargs; i++)
+ params[argno++] = v_args[i];
+
+ v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, params, argno, "");
+
+ pfree(params);
+
+ return v_ret;
+}
+#endif
+/*
+ * Implement an expression step by calling the function funcname.
+ */
+static LLVMValueRef
+build_EvalXFuncIntLLVM(LLVMBuilderRef b, LLVMJitContext *context, const char *funcname,
+ LLVMValueRef v_state, LLVMValueRef v_op,
+ int nargs, LLVMValueRef *v_args)
+{
+ LLVMValueRef v_fn = llvm_pg_func(context, funcname);
LLVMValueRef *params;
int argno = 0;
LLVMValueRef v_ret;
@@ -3062,7 +3305,7 @@ build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
params[argno++] = v_state;
- params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
+ params[argno++] = v_op;
for (int i = 0; i < nargs; i++)
params[argno++] = v_args[i];
diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c
index dbe0282e98f..f39ddfc30a6 100644
--- a/src/backend/jit/llvm/llvmjit_types.c
+++ b/src/backend/jit/llvm/llvmjit_types.c
@@ -69,6 +69,7 @@ MinimalTupleTableSlot StructMinimalTupleTableSlot;
TupleDescData StructTupleDescData;
PlanState StructPlanState;
MinimalTupleData StructMinimalTupleData;
+WindowFuncExprState StructWindowFuncExprState;
/*
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 45915767825..9bb8ae0e076 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -61,6 +61,9 @@
#define COPY_LOCATION_FIELD(fldname) \
(newnode->fldname = from->fldname)
+/* Copy a saved jit context */
+#define COPY_JITCONTEXT_FIELD(fldname) \
+ (newnode->fldname = from->fldname)
#include "copyfuncs.funcs.c"
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index f2598a1b69a..6cd16db0a0d 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -84,6 +84,12 @@
#define COMPARE_COERCIONFORM_FIELD(fldname) \
((void) 0)
+/* Compare a saved jit context */
+#define COMPARE_JITCONTEXT_FIELD(fldname) \
+ do { \
+ if (a->fldname != b->fldname) \
+ return false; \
+ } while (0)
#include "equalfuncs.funcs.c"
diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index 1a657f7e0ae..d2c284af857 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -865,6 +865,14 @@ _equal${n}(const $n *a, const $n *b)
print $cff "\tCOPY_SCALAR_FIELD($f);\n" unless $copy_ignore;
print $eff "\tCOMPARE_SCALAR_FIELD($f);\n" unless $equal_ignore;
}
+ elsif ($t eq 'struct CachedJitContext*')
+ {
+ # Fields of these types are required to be a pointer to a
+ # static struct. So we don't copy the struct itself,
+ # just reference the original one.
+ print $cff "\tCOPY_SCALAR_FIELD($f);\n" unless $copy_ignore;
+ print $eff "\tCOMPARE_SCALAR_FIELD($f);\n" unless $equal_ignore;
+ }
else
{
die
@@ -1214,6 +1222,11 @@ _read${n}(void)
}
! unless $no_read;
}
+ elsif ($t eq 'struct CachedJitContext*')
+ {
+ print $off "\tWRITE_JITCONTEXT_FIELD($f);\n";
+ print $rff "\tREAD_JITCONTEXT_FIELD($f);\n" unless $no_read;
+ }
else
{
die
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index bb9bdd67192..9c772a00197 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -93,6 +93,10 @@ static void outDouble(StringInfo str, double d);
#define WRITE_LOCATION_FIELD(fldname) \
appendStringInfo(str, " :" CppAsString(fldname) " %d", write_location_fields ? node->fldname : -1)
+/* Write a parse jit context field (actually same as INT case) */
+#define WRITE_JITCONTEXT_FIELD(fldname) \
+ appendStringInfo(str, " :" CppAsString(fldname) " %d", 0)
+
/* Write a Node field */
#define WRITE_NODE_FIELD(fldname) \
(appendStringInfoString(str, " :" CppAsString(fldname) " "), \
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 64d3a09f765..b4bb27353a5 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -131,6 +131,12 @@
local_node->fldname = -1 /* set field to "unknown" */
#endif
+/* Read a parse jit context field*/
+#define READ_JITCONTEXT_FIELD(fldname) \
+ token = pg_strtok(&length); /* skip :fldname */ \
+ token = pg_strtok(&length); /* get field value */ \
+ local_node->fldname = (struct CachedJitContext*)atoi(token)
+
/* Read a Node field */
#define READ_NODE_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index 55db8f53705..f2016ed79d3 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -72,6 +72,7 @@
#include "utils/rls.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
+#include "jit/jit.h"
/*
@@ -1015,6 +1016,10 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
is_transient = true;
if (plannedstmt->dependsOnRole)
plan->dependsOnRole = true;
+ if (!plansource->is_oneshot && !plannedstmt->jit_context)
+ {
+ plannedstmt->jit_context = CACHED_JITCONTEXT_EMPTY;
+ }
}
if (is_transient)
{
@@ -1305,7 +1310,21 @@ ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
/* One-shot plans do not own their context, so we can't free them */
if (!plan->is_oneshot)
+ {
+ /* release cached jit contexts */
+ ListCell *lc;
+ foreach(lc, plan->stmt_list)
+ {
+ PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc);
+
+ if (plannedstmt->jit_context &&
+ plannedstmt->jit_context != CACHED_JITCONTEXT_EMPTY)
+ {
+ jit_release_context(plannedstmt->jit_context); /* todo fix to correct pointer to jit context (.jit)*/
+ }
+ }
MemoryContextDelete(plan->context);
+ }
}
}
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index ce7534d4d23..0fe8349e9b8 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -1983,6 +1983,18 @@ struct config_bool ConfigureNamesBool[] =
NULL, NULL, NULL
},
+ {
+ {"jit_cached", PGC_USERSET, QUERY_TUNING_OTHER,
+ gettext_noop("Allow JIT compilation to store in a plan cache."),
+ NULL,
+ GUC_EXPLAIN
+ },
+ &jit_cached,
+ false,
+ NULL, NULL, NULL
+ },
+
+
{
{"jit_debugging_support", PGC_SU_BACKEND, DEVELOPER_OPTIONS,
gettext_noop("Register JIT-compiled functions with debugger."),
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 51bd35dcb07..092d3f850fb 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -301,7 +301,9 @@ typedef struct ExprEvalStep
intptr_t opcode;
/* where to store the result of this step */
+#define FIELDNO_EXPREVALSTEP_RESVALUE 1
Datum *resvalue;
+#define FIELDNO_EXPREVALSTEP_RESNULL 2
bool *resnull;
/*
diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h
index 33cb36c5d2e..ca8dc047c7f 100644
--- a/src/include/jit/jit.h
+++ b/src/include/jit/jit.h
@@ -81,6 +81,7 @@ struct JitProviderCallbacks
/* GUCs */
extern PGDLLIMPORT bool jit_enabled;
+extern PGDLLIMPORT bool jit_cached;
extern PGDLLIMPORT char *jit_provider;
extern PGDLLIMPORT bool jit_debugging_support;
extern PGDLLIMPORT bool jit_dump_bitcode;
diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h
index 5038cf33e3f..b4489786a03 100644
--- a/src/include/jit/llvmjit.h
+++ b/src/include/jit/llvmjit.h
@@ -40,6 +40,38 @@ extern "C"
#include "jit/jit.h"
#include "nodes/pg_list.h"
+/* type and struct definitions */
+typedef struct LLVMJitTypes
+{
+ LLVMTypeRef TypeParamBool;
+ LLVMTypeRef TypePGFunction;
+ LLVMTypeRef TypeSizeT;
+ LLVMTypeRef TypeStorageBool;
+
+ LLVMTypeRef StructNullableDatum;
+ LLVMTypeRef StructTupleDescData;
+ LLVMTypeRef StructHeapTupleData;
+ LLVMTypeRef StructHeapTupleHeaderData;
+ LLVMTypeRef StructMinimalTupleData;
+ LLVMTypeRef StructTupleTableSlot;
+ LLVMTypeRef StructHeapTupleTableSlot;
+ LLVMTypeRef StructMinimalTupleTableSlot;
+ LLVMTypeRef StructMemoryContextData;
+ LLVMTypeRef StructFunctionCallInfoData;
+ LLVMTypeRef StructExprContext;
+ LLVMTypeRef StructExprEvalStep;
+ LLVMTypeRef StructExprState;
+ LLVMTypeRef StructAggState;
+ LLVMTypeRef StructAggStatePerTransData;
+ LLVMTypeRef StructAggStatePerGroupData;
+ LLVMTypeRef StructPlanState;
+ LLVMTypeRef StructWindowFuncExprState;
+
+ LLVMValueRef AttributeTemplate;
+ LLVMValueRef ExecEvalBoolSubroutineTemplate;
+ LLVMValueRef ExecEvalSubroutineTemplate;
+} LLVMJitTypes;
+
typedef struct LLVMJitContext
{
JitContext base;
@@ -60,44 +92,34 @@ typedef struct LLVMJitContext
/* current, "open for write", module */
LLVMModuleRef module;
+ /* types module in llvm_context or NULL */
+ LLVMModuleRef llvm_types_module;
+
+ /* types defined in types module */
+ LLVMJitTypes *jit_types;
+
/* is there any pending code that needs to be emitted */
bool compiled;
/* # of objects emitted, used to generate non-conflicting names */
- int counter;
+ int counter_expr;
+
+ /* max # of objects emitted, used to start counting from 0 */
+ int max_counter_expr;
+
+ /* # of objects emitted, used to generate non-conflicting names */
+ int counter_deform;
/* list of handles for code emitted via Orc */
List *handles;
} LLVMJitContext;
-/* type and struct definitions */
-extern PGDLLIMPORT LLVMTypeRef TypeParamBool;
-extern PGDLLIMPORT LLVMTypeRef TypePGFunction;
-extern PGDLLIMPORT LLVMTypeRef TypeSizeT;
-extern PGDLLIMPORT LLVMTypeRef TypeStorageBool;
-
-extern PGDLLIMPORT LLVMTypeRef StructNullableDatum;
-extern PGDLLIMPORT LLVMTypeRef StructTupleDescData;
-extern PGDLLIMPORT LLVMTypeRef StructHeapTupleData;
-extern PGDLLIMPORT LLVMTypeRef StructHeapTupleHeaderData;
-extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleData;
-extern PGDLLIMPORT LLVMTypeRef StructTupleTableSlot;
-extern PGDLLIMPORT LLVMTypeRef StructHeapTupleTableSlot;
-extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleTableSlot;
-extern PGDLLIMPORT LLVMTypeRef StructMemoryContextData;
-extern PGDLLIMPORT LLVMTypeRef StructFunctionCallInfoData;
-extern PGDLLIMPORT LLVMTypeRef StructExprContext;
-extern PGDLLIMPORT LLVMTypeRef StructExprEvalStep;
-extern PGDLLIMPORT LLVMTypeRef StructExprState;
-extern PGDLLIMPORT LLVMTypeRef StructAggState;
-extern PGDLLIMPORT LLVMTypeRef StructAggStatePerTransData;
-extern PGDLLIMPORT LLVMTypeRef StructAggStatePerGroupData;
-extern PGDLLIMPORT LLVMTypeRef StructPlanState;
-
-extern PGDLLIMPORT LLVMValueRef AttributeTemplate;
-extern PGDLLIMPORT LLVMValueRef ExecEvalBoolSubroutineTemplate;
-extern PGDLLIMPORT LLVMValueRef ExecEvalSubroutineTemplate;
+struct CachedJitContext
+{
+ LLVMJitContext jit;
+};
+extern PGDLLIMPORT LLVMJitTypes llvm_jit_types_struct;
extern void llvm_enter_fatal_on_oom(void);
extern void llvm_leave_fatal_on_oom(void);
@@ -106,18 +128,21 @@ extern void llvm_reset_after_error(void);
extern void llvm_assert_in_fatal_section(void);
extern LLVMJitContext *llvm_create_context(int jitFlags);
+extern LLVMJitContext *llvm_create_cached_context(int jitFlags);
extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context);
-extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename);
+extern char *llvm_expand_funcname_expr(LLVMJitContext *context, const char *basename);
+extern char *llvm_expand_funcname_deform(LLVMJitContext *context, const char *basename);
extern void *llvm_get_function(LLVMJitContext *context, const char *funcname);
extern void llvm_split_symbol_name(const char *name, char **modname, char **funcname);
-extern LLVMTypeRef llvm_pg_var_type(const char *varname);
-extern LLVMTypeRef llvm_pg_var_func_type(const char *varname);
-extern LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname);
+extern LLVMTypeRef llvm_pg_var_type(LLVMModuleRef llvm_types_module, const char *varname);
+extern LLVMTypeRef llvm_pg_var_func_type(LLVMJitContext *context, const char *varname);
+extern LLVMValueRef llvm_pg_func(LLVMJitContext *context /*LLVMModuleRef mod*/, const char *funcname);
extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,
LLVMBuilderRef builder,
LLVMModuleRef mod,
- FunctionCallInfo fcinfo);
+ FunctionCallInfo fcinfo,
+ LLVMValueRef v_fcinfo);
extern void llvm_inline_reset_caches(void);
extern void llvm_inline(LLVMModuleRef mod);
diff --git a/src/include/jit/llvmjit_emit.h b/src/include/jit/llvmjit_emit.h
index df5a9fc8500..6f8d0e83649 100644
--- a/src/include/jit/llvmjit_emit.h
+++ b/src/include/jit/llvmjit_emit.h
@@ -25,7 +25,7 @@
* Emit a non-LLVM pointer as an LLVM constant.
*/
static inline LLVMValueRef
-l_ptr_const(void *ptr, LLVMTypeRef type)
+l_ptr_const(void *ptr, LLVMTypeRef type, LLVMTypeRef TypeSizeT)
{
LLVMValueRef c = LLVMConstInt(TypeSizeT, (uintptr_t) ptr, false);
@@ -76,7 +76,7 @@ l_int64_const(LLVMContextRef lc, int64 i)
{
return LLVMConstInt(LLVMInt64TypeInContext(lc), i, false);
}
-
+#ifdef DELETE_IT
/*
* Emit constant integer.
*/
@@ -95,6 +95,7 @@ l_sbool_const(bool i)
return LLVMConstInt(TypeStorageBool, (int) i, false);
}
+
/*
* Emit constant boolean, as used for parameters (e.g. function parameters).
*/
@@ -103,6 +104,7 @@ l_pbool_const(bool i)
{
return LLVMConstInt(TypeParamBool, (int) i, false);
}
+#endif
static inline LLVMValueRef
l_struct_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, int32 idx, const char *name)
@@ -149,6 +151,44 @@ l_load_gep1(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef idx, c
return l_load(b, t, l_gep(b, t, v, &idx, 1, ""), name);
}
+#ifndef DELETE_IT
+/*
+ * Load value of a structure using offset of member in structure.
+ * b - builder
+ * v - value of sturcture
+ * dest - the type of the structure member
+ * offset - the offset of the structure member in the structure v
+ */
+static inline LLVMValueRef
+l_load_member_value_by_offset(LLVMBuilderRef b, LLVMContextRef lc, LLVMValueRef v, LLVMTypeRef dest, int offset)
+{
+#ifdef _DELETE_IT
+ LLVMValueRef castbase = LLVMBuildPtrToInt(b, v, LLVMInt64TypeInContext(llvm_context), "base_pointer");
+ LLVMValueRef castchar1offset = LLVMBuildAdd(b, castbase, l_int64_const(llvm_context, offset), "member_pointer_int");
+ LLVMValueRef castchar2 = LLVMBuildIntToPtr(b, castchar1offset, l_ptr(dest), "member_pointer");
+ return l_load(b, dest, castchar2, "member_value");
+#endif
+ LLVMValueRef offsets = l_int32_const(lc, offset);
+ LLVMValueRef member_address = l_gep(b,(LLVMInt8TypeInContext(lc)), v, &offsets, 1, "member_address");
+ return l_load(b, dest, member_address, "member_value");
+}
+
+#define l_ptr_const_step(m,t) l_load_member_value_by_offset(b,lc, v_op, t, offsetof(ExprEvalStep ,m))
+
+static inline LLVMValueRef
+l_struct_member_ptr_by_offset(LLVMBuilderRef b, LLVMContextRef lc, LLVMValueRef v, /* LLVMTypeRef dest, */ int offset)
+{
+#ifdef _DELETE_IT
+ LLVMValueRef castbase = LLVMBuildPtrToInt(b, v, LLVMInt64TypeInContext(llvm_context), "base_pointer");
+ LLVMValueRef castchar1offset = LLVMBuildAdd(b, castbase, l_int64_const(llvm_context, offset), "member_pointer_int");
+ LLVMValueRef castchar2 = LLVMBuildIntToPtr(b, castchar1offset, l_ptr(dest), "member_pointer");
+ return l_load(b, dest, castchar2, "member_value");
+#endif
+ LLVMValueRef offsets = l_int32_const(lc, offset);
+ LLVMValueRef member_address = l_gep(b,(LLVMInt8TypeInContext(lc)), v, &offsets, 1, "member_address");
+ return member_address;
+}
+#endif
/* separate, because pg_attribute_printf(2, 3) can't appear in definition */
static inline LLVMBasicBlockRef l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...) pg_attribute_printf(2, 3);
@@ -232,15 +272,15 @@ l_callsite_alwaysinline(LLVMValueRef f)
* Emit code to switch memory context.
*/
static inline LLVMValueRef
-l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc)
+l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc, LLVMJitTypes *g)
{
const char *cmc = "CurrentMemoryContext";
LLVMValueRef cur;
LLVMValueRef ret;
if (!(cur = LLVMGetNamedGlobal(mod, cmc)))
- cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc);
- ret = l_load(b, l_ptr(StructMemoryContextData), cur, cmc);
+ cur = LLVMAddGlobal(mod, l_ptr(g->StructMemoryContextData), cmc);
+ ret = l_load(b, l_ptr(g->StructMemoryContextData), cur, cmc);
LLVMBuildStore(b, nc, cur);
return ret;
@@ -250,23 +290,23 @@ l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc)
* Return pointer to the argno'th argument nullness.
*/
static inline LLVMValueRef
-l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
+l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno, LLVMJitTypes *g)
{
LLVMValueRef v_args;
LLVMValueRef v_argn;
v_args = l_struct_gep(b,
- StructFunctionCallInfoData,
+ g->StructFunctionCallInfoData,
v_fcinfo,
FIELDNO_FUNCTIONCALLINFODATA_ARGS,
"");
v_argn = l_struct_gep(b,
- LLVMArrayType(StructNullableDatum, 0),
+ LLVMArrayType(g->StructNullableDatum, 0),
v_args,
argno,
"");
return l_struct_gep(b,
- StructNullableDatum,
+ g->StructNullableDatum,
v_argn,
FIELDNO_NULLABLE_DATUM_ISNULL,
"");
@@ -276,23 +316,23 @@ l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
* Return pointer to the argno'th argument datum.
*/
static inline LLVMValueRef
-l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
+l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno, LLVMJitTypes *g)
{
LLVMValueRef v_args;
LLVMValueRef v_argn;
v_args = l_struct_gep(b,
- StructFunctionCallInfoData,
+ g->StructFunctionCallInfoData,
v_fcinfo,
FIELDNO_FUNCTIONCALLINFODATA_ARGS,
"");
v_argn = l_struct_gep(b,
- LLVMArrayType(StructNullableDatum, 0),
+ LLVMArrayType(g->StructNullableDatum, 0),
v_args,
argno,
"");
return l_struct_gep(b,
- StructNullableDatum,
+ g->StructNullableDatum,
v_argn,
FIELDNO_NULLABLE_DATUM_DATUM,
"");
@@ -302,18 +342,18 @@ l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
* Return argno'th argument nullness.
*/
static inline LLVMValueRef
-l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
+l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno, LLVMJitTypes *g)
{
- return l_load(b, TypeStorageBool, l_funcnullp(b, v_fcinfo, argno), "");
+ return l_load(b, g->TypeStorageBool, l_funcnullp(b, v_fcinfo, argno, g), "");
}
/*
* Return argno'th argument datum.
*/
static inline LLVMValueRef
-l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
+l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno, LLVMJitTypes *g)
{
- return l_load(b, TypeSizeT, l_funcvaluep(b, v_fcinfo, argno), "");
+ return l_load(b, g->TypeSizeT, l_funcvaluep(b, v_fcinfo, argno, g), "");
}
#endif /* USE_LLVM */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index e2d1dc1e067..0267781b25d 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -108,6 +108,7 @@ typedef struct ExprState
/*
* Instructions to compute expression's return value.
*/
+#define FIELDNO_EXPRSTATE_STEPS 5
struct ExprEvalStep *steps;
/*
@@ -272,6 +273,7 @@ typedef struct ExprContext
/* Memory contexts for expression evaluation --- see notes above */
MemoryContext ecxt_per_query_memory;
+#define FIELDNO_EXPRCONTEXT_PERTUPLEMEMORY 5
MemoryContext ecxt_per_tuple_memory;
/* Values to substitute for Param nodes in expression */
@@ -2534,6 +2536,7 @@ typedef struct AggState
AggStatePerTrans pertrans; /* per-Trans state information */
ExprContext *hashcontext; /* econtexts for long-lived data (hashtable) */
ExprContext **aggcontexts; /* econtexts for long-lived data (per GS) */
+#define FIELDNO_AGGSTATE_TMPCONTEXT 13
ExprContext *tmpcontext; /* econtext for input expressions */
#define FIELDNO_AGGSTATE_CURAGGCONTEXT 14
ExprContext *curaggcontext; /* currently active aggcontext */
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 2a2cf816cb6..a5c0a310191 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -22,7 +22,8 @@
#include "nodes/lockoptions.h"
#include "nodes/primnodes.h"
-
+struct CachedJitContext;
+#define CACHED_JITCONTEXT_EMPTY ((struct CachedJitContext*)(-1))
/* ----------------------------------------------------------------
* node definitions
* ----------------------------------------------------------------
@@ -104,6 +105,7 @@ typedef struct PlannedStmt
/* statement location in source string (copied from Query) */
ParseLoc stmt_location; /* start location, or -1 if unknown */
ParseLoc stmt_len; /* length in bytes; 0 means "rest of string" */
+ struct CachedJitContext *jit_context; /* context of save jit-module */
} PlannedStmt;
/* macro for fetching the Plan associated with a SubPlan node */
--
2.39.5 (Apple Git-154)
jit_cached_bench.pngimage/png; name=jit_cached_bench.pngDownload
�PNG
IHDR � S ���� pHYs � �%��z IDATx���{\Tu�?��(��Y.�U��$� "&�X(iF����Ws�U7����(�7���l��V31���oY (yY�@�`B�����eQn2r~�p��9s�33����3���|���y��r��0!�B1����B!�b�(�$�B!�B�$!�B�
$ !�BH�P I!�B��IB!��-HB!��n��@����X�b
%�|��P�TX�~=���-�:B!����&��'O"&&_~�%jjjD����b��=��s'���5k�X���B!}�M���G^^���$����{��e���/#++��-$�B��l2� ���#�����GZZ�����(�;w�B�#�B�X��r��]xzz���c��?����W���vvv\������ !�t������g�fbU}6�;v,,X GGG,Y��=�n����c�ry�|�I�m���m��B�A����n!Vg�C�R���QRR x���������vdggC�Tj��B!�gl2������a�������(6UUU8|�0�}�] �������R(
���+��{��[M!������vjj�hzXX.\� pww��s����gggK6�B!�_��I)
��W��J� �B!�<l�GRJ@@���@!��o��IB!�b9HB!��n�@�B!�t��B!�[(�$�B!�B�$!�B�
$ !�BH�P I!�B��IB!��-HB!��n�@�B!�t��B!�[(�$�B!�B�$!�B�
$ !�BH�P I!�B�e���]��_GRR����������={p��Y����'c��l!!�BH�f�����'�e�444`����y������0 ���C-�DB!��>�&����#//O<��d���:��9!!!l!�BH�a�s$CBB0r�H�y����g��������GAA��ZG!��?�d��1��[///��5|����PZZ��'##�h����[���B!6��FR6$88�����������NNN(//���%����#::Z�fB����A�h�C�R���QRR����c������y�+�JxyyY����4��wk~B!D�Mm���!##w��ETT����b>|w����������b���hhh�����w�^���Y���4������ �A��L�m�U�F!��&6H����������� �E�a��Ehnn��!C,�<b�tH�c��n�;� ���B�E����B�������(�$F����D�m<S5������[����B��l�GRJ@@���@l�������9�����KW������g*�PB�w�T I�I�=�� R����� �B�g���6!&q���7;�ml��������B!}�H���mK��������B���4Z�a;,��x����9�� ��GP )7v����>��=�&�8�^�B�
$�&(`��q���� ��K)v!��$�b�(��4�Q@i9�wk�5��[z%��h/���-�������-" !��A�m��
���a����Bnbw�1t9k��>