Quick adaption of JIT tuple deforming to the fast default patch.
Instead using memset to set tts_isnull, call the new slot_getmissingattrs(). Also fix a bug (= instead of >=) in the code generation. Normally = is correct, but when repeatedly deforming fields not in a tuple (e.g. deform up to natts + 1 and then natts + 2) >= is needed. Discussion: https://postgr.es/m/20180328010053.i2qvsuuusst4lgmc@alap3.anarazel.de
This commit is contained in:
parent
b4013b8e4a
commit
f4f5845b31
@ -112,9 +112,13 @@ getmissingattr(TupleDesc tupleDesc,
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in missing values for a TupleTableSlot
|
||||
* Fill in missing values for a TupleTableSlot.
|
||||
*
|
||||
* This is only exposed because it's needed for JIT compiled tuple
|
||||
* deforming. That exception aside, there should be no callers outside of this
|
||||
* file.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, int lastAttNum)
|
||||
{
|
||||
AttrMissing *attrmiss = NULL;
|
||||
|
@ -76,6 +76,7 @@ LLVMValueRef AttributeTemplate;
|
||||
LLVMValueRef FuncStrlen;
|
||||
LLVMValueRef FuncVarsizeAny;
|
||||
LLVMValueRef FuncSlotGetsomeattrs;
|
||||
LLVMValueRef FuncSlotGetmissingattrs;
|
||||
LLVMValueRef FuncHeapGetsysattr;
|
||||
LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
|
||||
LLVMValueRef FuncExecEvalArrayRefSubscript;
|
||||
@ -798,6 +799,7 @@ llvm_create_types(void)
|
||||
FuncStrlen = LLVMGetNamedFunction(mod, "strlen");
|
||||
FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any");
|
||||
FuncSlotGetsomeattrs = LLVMGetNamedFunction(mod, "slot_getsomeattrs");
|
||||
FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs");
|
||||
FuncHeapGetsysattr = LLVMGetNamedFunction(mod, "heap_getsysattr");
|
||||
FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");
|
||||
FuncExecEvalArrayRefSubscript = LLVMGetNamedFunction(mod, "ExecEvalArrayRefSubscript");
|
||||
|
@ -21,14 +21,12 @@
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
#include "access/htup_details.h"
|
||||
#include "access/tupdesc_details.h"
|
||||
#include "executor/tuptable.h"
|
||||
#include "jit/llvmjit.h"
|
||||
#include "jit/llvmjit_emit.h"
|
||||
|
||||
|
||||
static LLVMValueRef get_memset(LLVMModuleRef mod);
|
||||
|
||||
|
||||
/*
|
||||
* Create a function that deforms a tuple of type desc up to natts columns.
|
||||
*/
|
||||
@ -100,10 +98,23 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
|
||||
*/
|
||||
for (attnum = 0; attnum < desc->natts; attnum++)
|
||||
{
|
||||
if (TupleDescAttr(desc, attnum)->attnotnull)
|
||||
{
|
||||
Form_pg_attribute att = TupleDescAttr(desc, attnum);
|
||||
|
||||
/*
|
||||
* If the column is possibly missing, we can't rely on its (or
|
||||
* subsequent) NOT NULL constraints to indicate minimum attributes in
|
||||
* the tuple, so stop here.
|
||||
*/
|
||||
if (att->atthasmissing)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Column is NOT NULL and there've been no preceding missing columns,
|
||||
* it's guaranteed that all columns up to here exist at least in the
|
||||
* NULL bitmap.
|
||||
*/
|
||||
if (att->attnotnull)
|
||||
guaranteed_column_number = attnum;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the signature and function */
|
||||
@ -242,9 +253,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
|
||||
|
||||
/*
|
||||
* Check if's guaranteed the all the desired attributes are available in
|
||||
* tuple. If so, we can start deforming. If not, need to make sure
|
||||
* tts_values/isnull is set appropriately for columns not available in the
|
||||
* tuple.
|
||||
* tuple. If so, we can start deforming. If not, need to make sure to
|
||||
* fetch the missing columns.
|
||||
*/
|
||||
if ((natts - 1) <= guaranteed_column_number)
|
||||
{
|
||||
@ -255,9 +265,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVMValueRef v_set;
|
||||
LLVMValueRef v_startset;
|
||||
LLVMValueRef v_params[5];
|
||||
LLVMValueRef v_params[3];
|
||||
|
||||
/* branch if not all columns available */
|
||||
LLVMBuildCondBr(b,
|
||||
@ -271,19 +279,10 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
|
||||
/* if not, memset tts_isnull of relevant cols to true */
|
||||
LLVMPositionBuilderAtEnd(b, b_adjust_unavail_cols);
|
||||
|
||||
v_set = LLVMBuildSub(b,
|
||||
l_int16_const(attnum),
|
||||
v_maxatt, "");
|
||||
|
||||
v_startset = LLVMBuildGEP(b, v_tts_nulls, &v_maxatt, 1, "");
|
||||
|
||||
v_params[0] = v_startset;
|
||||
v_params[1] = l_int8_const(1);
|
||||
v_params[2] = LLVMBuildZExt(b, v_set, LLVMInt32Type(), "");
|
||||
v_params[3] = l_int32_const(1);
|
||||
v_params[4] = LLVMConstInt(LLVMInt1Type(), 0, false);
|
||||
|
||||
LLVMBuildCall(b, get_memset(mod),
|
||||
v_params[0] = v_slot;
|
||||
v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), "");
|
||||
v_params[2] = l_int32_const(natts);
|
||||
LLVMBuildCall(b, llvm_get_decl(mod, FuncSlotGetmissingattrs),
|
||||
v_params, lengthof(v_params), "");
|
||||
LLVMBuildBr(b, b_find_start);
|
||||
}
|
||||
@ -358,7 +357,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
|
||||
{
|
||||
LLVMValueRef v_islast;
|
||||
|
||||
v_islast = LLVMBuildICmp(b, LLVMIntEQ,
|
||||
v_islast = LLVMBuildICmp(b, LLVMIntUGE,
|
||||
l_attno,
|
||||
v_maxatt,
|
||||
"heap_natts");
|
||||
@ -366,7 +365,11 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
|
||||
}
|
||||
LLVMPositionBuilderAtEnd(b, attstartblocks[attnum]);
|
||||
|
||||
/* check for nulls if necessary */
|
||||
/*
|
||||
* Check for nulls if necessary. No need to take missing attributes
|
||||
* into account, because in case they're present the heaptuple's natts
|
||||
* would have indicated that a slot_getmissingattrs() is needed.
|
||||
*/
|
||||
if (!att->attnotnull)
|
||||
{
|
||||
LLVMBasicBlockRef b_ifnotnull;
|
||||
@ -699,31 +702,3 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts)
|
||||
|
||||
return v_deform_fn;
|
||||
}
|
||||
|
||||
static LLVMValueRef
|
||||
get_memset(LLVMModuleRef mod)
|
||||
{
|
||||
LLVMTypeRef sig;
|
||||
LLVMValueRef v_fn;
|
||||
LLVMTypeRef param_types[5];
|
||||
const char *nm = "llvm.memset.p0i8.i32";
|
||||
|
||||
v_fn = LLVMGetNamedFunction(mod, nm);
|
||||
if (v_fn)
|
||||
return v_fn;
|
||||
|
||||
param_types[0] = LLVMPointerType(LLVMInt8Type(), 0); /* addr */
|
||||
param_types[1] = LLVMInt8Type(); /* val */
|
||||
param_types[2] = LLVMInt32Type(); /* len */
|
||||
param_types[3] = LLVMInt32Type(); /* align */
|
||||
param_types[4] = LLVMInt1Type(); /* volatile */
|
||||
|
||||
sig = LLVMFunctionType(LLVMVoidType(), param_types, lengthof(param_types), 0);
|
||||
v_fn = LLVMAddFunction(mod, nm, sig);
|
||||
|
||||
LLVMSetFunctionCallConv(v_fn, LLVMCCallConv);
|
||||
|
||||
Assert(LLVMGetIntrinsicID(v_fn));
|
||||
|
||||
return v_fn;
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ void *referenced_functions[] =
|
||||
strlen,
|
||||
varsize_any,
|
||||
slot_getsomeattrs,
|
||||
slot_getmissingattrs,
|
||||
heap_getsysattr,
|
||||
MakeExpandedObjectReadOnlyInternal,
|
||||
ExecEvalArrayRefSubscript,
|
||||
|
@ -179,5 +179,6 @@ extern void slot_getsomeattrs(TupleTableSlot *slot, int attnum);
|
||||
extern bool slot_attisnull(TupleTableSlot *slot, int attnum);
|
||||
extern bool slot_getsysattr(TupleTableSlot *slot, int attnum,
|
||||
Datum *value, bool *isnull);
|
||||
extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, int lastAttNum);
|
||||
|
||||
#endif /* TUPTABLE_H */
|
||||
|
@ -78,6 +78,7 @@ extern LLVMValueRef AttributeTemplate;
|
||||
extern LLVMValueRef FuncStrlen;
|
||||
extern LLVMValueRef FuncVarsizeAny;
|
||||
extern LLVMValueRef FuncSlotGetsomeattrs;
|
||||
extern LLVMValueRef FuncSlotGetmissingattrs;
|
||||
extern LLVMValueRef FuncHeapGetsysattr;
|
||||
extern LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
|
||||
extern LLVMValueRef FuncExecEvalArrayRefSubscript;
|
||||
|
Loading…
x
Reference in New Issue
Block a user