Skip to content

Commit 32af96b

Browse files
committed
JIT tuple deforming in LLVM JIT provider.
Performing JIT compilation for deforming gains performance benefits over unJITed deforming from compile-time knowledge of the tuple descriptor. Fixed column widths, NOT NULLness, etc can be taken advantage of. Right now the JITed deforming is only used when deforming tuples as part of expression evaluation (and obviously only if the descriptor is known). It's likely to be beneficial in other cases, too. By default tuple deforming is JITed whenever an expression is JIT compiled. There's a separate boolean GUC controlling it, but that's expected to be primarily useful for development and benchmarking. Docs will follow in a later commit containing docs for the whole JIT feature. Author: Andres Freund Discussion: https://postgr.es/m/20170901064131.tazjxwus3k2w3ybh@alap3.anarazel.de
1 parent 64f8589 commit 32af96b

File tree

17 files changed

+827
-3
lines changed

17 files changed

+827
-3
lines changed

src/backend/access/common/heaptuple.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,3 +1556,13 @@ minimal_tuple_from_heap_tuple(HeapTuple htup)
15561556
result->t_len = len;
15571557
return result;
15581558
}
1559+
1560+
/*
1561+
* This mainly exists so JIT can inline the definition, but it's also
1562+
* sometimes useful in debugging sessions.
1563+
*/
1564+
size_t
1565+
varsize_any(void *p)
1566+
{
1567+
return VARSIZE_ANY(p);
1568+
}

src/backend/executor/execExpr.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,18 +2287,21 @@ ExecPushExprSlots(ExprState *state, LastAttnumInfo *info)
22872287
{
22882288
scratch.opcode = EEOP_INNER_FETCHSOME;
22892289
scratch.d.fetch.last_var = info->last_inner;
2290+
scratch.d.fetch.known_desc = NULL;
22902291
ExprEvalPushStep(state, &scratch);
22912292
}
22922293
if (info->last_outer > 0)
22932294
{
22942295
scratch.opcode = EEOP_OUTER_FETCHSOME;
22952296
scratch.d.fetch.last_var = info->last_outer;
2297+
scratch.d.fetch.known_desc = NULL;
22962298
ExprEvalPushStep(state, &scratch);
22972299
}
22982300
if (info->last_scan > 0)
22992301
{
23002302
scratch.opcode = EEOP_SCAN_FETCHSOME;
23012303
scratch.d.fetch.last_var = info->last_scan;
2304+
scratch.d.fetch.known_desc = NULL;
23022305
ExprEvalPushStep(state, &scratch);
23032306
}
23042307
}
@@ -3250,10 +3253,12 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
32503253
/* push deform steps */
32513254
scratch.opcode = EEOP_INNER_FETCHSOME;
32523255
scratch.d.fetch.last_var = maxatt;
3256+
scratch.d.fetch.known_desc = ldesc;
32533257
ExprEvalPushStep(state, &scratch);
32543258

32553259
scratch.opcode = EEOP_OUTER_FETCHSOME;
32563260
scratch.d.fetch.last_var = maxatt;
3261+
scratch.d.fetch.known_desc = rdesc;
32573262
ExprEvalPushStep(state, &scratch);
32583263

32593264
/*

src/backend/executor/execTuples.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,7 @@ ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
896896
{
897897
scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable,
898898
tupledesc);
899+
scanstate->ps.scandesc = tupledesc;
899900
}
900901

901902
/* ----------------

src/backend/executor/nodeForeignscan.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,11 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
186186
}
187187
else
188188
{
189-
ExecInitScanTupleSlot(estate, &scanstate->ss, RelationGetDescr(currentRelation));
189+
TupleDesc scan_tupdesc;
190+
191+
/* don't trust FDWs to return tuples fulfilling NOT NULL constraints */
192+
scan_tupdesc = CreateTupleDescCopy(RelationGetDescr(currentRelation));
193+
ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc);
190194
/* Node's targetlist will contain Vars with varno = scanrelid */
191195
tlistvarno = scanrelid;
192196
}

src/backend/jit/jit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ bool jit_debugging_support = false;
3838
bool jit_dump_bitcode = false;
3939
bool jit_expressions = true;
4040
bool jit_profiling_support = false;
41+
bool jit_tuple_deforming = true;
4142
double jit_above_cost = 100000;
4243
double jit_optimize_above_cost = 500000;
4344

src/backend/jit/llvm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ OBJS=$(WIN32RES)
3939
# Infrastructure
4040
OBJS += llvmjit.o llvmjit_error.o llvmjit_wrap.o
4141
# Code generation
42-
OBJS += llvmjit_expr.o
42+
OBJS += llvmjit_expr.o llvmjit_deform.o
4343

4444
all: all-shared-lib llvmjit_types.bc
4545

src/backend/jit/llvm/llvmjit.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ LLVMTypeRef StructAggStatePerTransData;
7474

7575
LLVMValueRef AttributeTemplate;
7676
LLVMValueRef FuncStrlen;
77+
LLVMValueRef FuncVarsizeAny;
7778
LLVMValueRef FuncSlotGetsomeattrs;
7879
LLVMValueRef FuncHeapGetsysattr;
7980
LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
@@ -784,6 +785,7 @@ llvm_create_types(void)
784785

785786
AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate");
786787
FuncStrlen = LLVMGetNamedFunction(mod, "strlen");
788+
FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any");
787789
FuncSlotGetsomeattrs = LLVMGetNamedFunction(mod, "slot_getsomeattrs");
788790
FuncHeapGetsysattr = LLVMGetNamedFunction(mod, "heap_getsysattr");
789791
FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");

0 commit comments

Comments
 (0)