]> granicus.if.org Git - postgresql/commitdiff
Quick adaption of JIT tuple deforming to the fast default patch.
authorAndres Freund <andres@anarazel.de>
Wed, 28 Mar 2018 04:03:10 +0000 (21:03 -0700)
committerAndres Freund <andres@anarazel.de>
Wed, 28 Mar 2018 04:03:10 +0000 (21:03 -0700)
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

src/backend/access/common/heaptuple.c
src/backend/jit/llvm/llvmjit.c
src/backend/jit/llvm/llvmjit_deform.c
src/backend/jit/llvm/llvmjit_types.c
src/include/executor/tuptable.h
src/include/jit/llvmjit.h

index b6ad7356718376a5da2e5e1ed5b6510c9bf4e340..960bbe42037e2b035a4923ce1f68c572c36a6c2f 100644 (file)
@@ -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;
index bbb2360232fd35192ed245fc9a98d698d674e4ac..5a33e52e1dce15326ca11bfd3c92df59231be22e 100644 (file)
@@ -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");
index 0762ab678628035029f0af5b3e6f191987508b9c..795f67114e65c784ba329ef757f4854a3ec59915 100644 (file)
 #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;
-}
index 0e06160c2aa6e8839af2f530c6c44c98c813c200..42304d06401a625f5b6f9f43891887c798a79267 100644 (file)
@@ -98,6 +98,7 @@ void     *referenced_functions[] =
        strlen,
        varsize_any,
        slot_getsomeattrs,
+       slot_getmissingattrs,
        heap_getsysattr,
        MakeExpandedObjectReadOnlyInternal,
        ExecEvalArrayRefSubscript,
index 3c1cf67d8f94d8323f5c66e803d78d75f8395961..b71ec8e0698194f644f77b1c41d4202ebad3ab8a 100644 (file)
@@ -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 */
index 9443a568d859e6cb5d3a8f1496146ec0aa50654d..f6aed64d8d5e4e8c6b38c057a740237d5b21576e 100644 (file)
@@ -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;