Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cc415a5

Browse files
committed
Basic planner and executor integration for JIT.
This adds simple cost based plan time decision about whether JIT should be performed. jit_above_cost, jit_optimize_above_cost are compared with the total cost of a plan, and if the cost is above them JIT is performed / optimization is performed respectively. For that PlannedStmt and EState have a jitFlags (es_jit_flags) field that stores information about what JIT operations should be performed. EState now also has a new es_jit field, which can store a JitContext. When there are no errors the context is released in standard_ExecutorEnd(). It is likely that the default values for jit_[optimize_]above_cost will need to be adapted further, but in my test these values seem to work reasonably. Author: Andres Freund, with feedback by Peter Eisentraut Discussion: https://postgr.es/m/[email protected]
1 parent 7ec0d80 commit cc415a5

File tree

13 files changed

+72
-0
lines changed

13 files changed

+72
-0
lines changed

src/backend/executor/execMain.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "commands/trigger.h"
4949
#include "executor/execdebug.h"
5050
#include "foreign/fdwapi.h"
51+
#include "jit/jit.h"
5152
#include "mb/pg_wchar.h"
5253
#include "miscadmin.h"
5354
#include "optimizer/clauses.h"
@@ -249,6 +250,9 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
249250
estate->es_top_eflags = eflags;
250251
estate->es_instrument = queryDesc->instrument_options;
251252

253+
if (queryDesc->plannedstmt)
254+
estate->es_jit_flags = queryDesc->plannedstmt->jitFlags;
255+
252256
/*
253257
* Set up an AFTER-trigger statement context, unless told not to, or
254258
* unless it's EXPLAIN-only mode (when ExecutorFinish won't be called).
@@ -496,6 +500,10 @@ standard_ExecutorEnd(QueryDesc *queryDesc)
496500
UnregisterSnapshot(estate->es_snapshot);
497501
UnregisterSnapshot(estate->es_crosscheck_snapshot);
498502

503+
/* release JIT context, if allocated */
504+
if (estate->es_jit)
505+
jit_release_context(estate->es_jit);
506+
499507
/*
500508
* Must switch out of context before destroying it
501509
*/

src/backend/executor/execParallel.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ typedef struct FixedParallelExecutorState
7373
int64 tuples_needed; /* tuple bound, see ExecSetTupleBound */
7474
dsa_pointer param_exec;
7575
int eflags;
76+
int jit_flags;
7677
} FixedParallelExecutorState;
7778

7879
/*
@@ -680,6 +681,7 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate,
680681
fpes->tuples_needed = tuples_needed;
681682
fpes->param_exec = InvalidDsaPointer;
682683
fpes->eflags = estate->es_top_eflags;
684+
fpes->jit_flags = estate->es_jit_flags;
683685
shm_toc_insert(pcxt->toc, PARALLEL_KEY_EXECUTOR_FIXED, fpes);
684686

685687
/* Store query string */
@@ -1287,6 +1289,7 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc)
12871289
area = dsa_attach_in_place(area_space, seg);
12881290

12891291
/* Start up the executor */
1292+
queryDesc->plannedstmt->jitFlags = fpes->jit_flags;
12901293
ExecutorStart(queryDesc, fpes->eflags);
12911294

12921295
/* Special executor initialization steps for parallel workers */

src/backend/executor/execUtils.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ CreateExecutorState(void)
158158

159159
estate->es_use_parallel_mode = false;
160160

161+
estate->es_jit_flags = 0;
162+
estate->es_jit = NULL;
163+
161164
/*
162165
* Return the executor state structure
163166
*/

src/backend/jit/jit.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ char *jit_provider = "llvmjit";
3636
bool jit_debugging_support = false;
3737
bool jit_dump_bitcode = false;
3838
bool jit_profiling_support = false;
39+
double jit_above_cost = 100000;
40+
double jit_optimize_above_cost = 500000;
3941

4042
static JitProviderCallbacks provider;
4143
static bool provider_successfully_loaded = false;

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ _copyPlannedStmt(const PlannedStmt *from)
8787
COPY_SCALAR_FIELD(transientPlan);
8888
COPY_SCALAR_FIELD(dependsOnRole);
8989
COPY_SCALAR_FIELD(parallelModeNeeded);
90+
COPY_SCALAR_FIELD(jitFlags);
9091
COPY_NODE_FIELD(planTree);
9192
COPY_NODE_FIELD(rtable);
9293
COPY_NODE_FIELD(resultRelations);

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
272272
WRITE_BOOL_FIELD(transientPlan);
273273
WRITE_BOOL_FIELD(dependsOnRole);
274274
WRITE_BOOL_FIELD(parallelModeNeeded);
275+
WRITE_BOOL_FIELD(jitFlags);
275276
WRITE_NODE_FIELD(planTree);
276277
WRITE_NODE_FIELD(rtable);
277278
WRITE_NODE_FIELD(resultRelations);

src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,7 @@ _readPlannedStmt(void)
14751475
READ_BOOL_FIELD(transientPlan);
14761476
READ_BOOL_FIELD(dependsOnRole);
14771477
READ_BOOL_FIELD(parallelModeNeeded);
1478+
READ_BOOL_FIELD(jitFlags);
14781479
READ_NODE_FIELD(planTree);
14791480
READ_NODE_FIELD(rtable);
14801481
READ_NODE_FIELD(resultRelations);

src/backend/optimizer/plan/planner.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "executor/nodeAgg.h"
3030
#include "foreign/fdwapi.h"
3131
#include "miscadmin.h"
32+
#include "jit/jit.h"
3233
#include "lib/bipartite_match.h"
3334
#include "lib/knapsack.h"
3435
#include "nodes/makefuncs.h"
@@ -531,6 +532,20 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
531532
result->stmt_location = parse->stmt_location;
532533
result->stmt_len = parse->stmt_len;
533534

535+
result->jitFlags = PGJIT_NONE;
536+
if (jit_enabled && jit_above_cost >= 0 &&
537+
top_plan->total_cost > jit_above_cost)
538+
{
539+
result->jitFlags |= PGJIT_PERFORM;
540+
541+
/*
542+
* Decide how much effort should be put into generating better code.
543+
*/
544+
if (jit_optimize_above_cost >= 0 &&
545+
top_plan->total_cost > jit_optimize_above_cost)
546+
result->jitFlags |= PGJIT_OPT3;
547+
}
548+
534549
return result;
535550
}
536551

src/backend/utils/misc/guc.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,6 +3075,26 @@ static struct config_real ConfigureNamesReal[] =
30753075
NULL, NULL, NULL
30763076
},
30773077

3078+
{
3079+
{"jit_above_cost", PGC_USERSET, QUERY_TUNING_COST,
3080+
gettext_noop("Perform JIT compilation if query is more expensive."),
3081+
gettext_noop("-1 disables JIT compilation.")
3082+
},
3083+
&jit_above_cost,
3084+
100000, -1, DBL_MAX,
3085+
NULL, NULL, NULL
3086+
},
3087+
3088+
{
3089+
{"jit_optimize_above_cost", PGC_USERSET, QUERY_TUNING_COST,
3090+
gettext_noop("Optimize JITed functions if query is more expensive."),
3091+
gettext_noop("-1 disables optimization.")
3092+
},
3093+
&jit_optimize_above_cost,
3094+
500000, -1, DBL_MAX,
3095+
NULL, NULL, NULL
3096+
},
3097+
30783098
{
30793099
{"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER,
30803100
gettext_noop("Sets the planner's estimate of the fraction of "

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,12 @@
318318
#cpu_operator_cost = 0.0025 # same scale as above
319319
#parallel_tuple_cost = 0.1 # same scale as above
320320
#parallel_setup_cost = 1000.0 # same scale as above
321+
322+
#jit_above_cost = 100000 # perform JIT compilation if available
323+
# and query more expensive, -1 disables
324+
#jit_optimize_above_cost = 500000 # optimize JITed functions if query is
325+
# more expensive, -1 disables
326+
321327
#min_parallel_table_scan_size = 8MB
322328
#min_parallel_index_scan_size = 512kB
323329
#effective_cache_size = 4GB

src/include/jit/jit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ extern char *jit_provider;
6161
extern bool jit_debugging_support;
6262
extern bool jit_dump_bitcode;
6363
extern bool jit_profiling_support;
64+
extern double jit_above_cost;
65+
extern double jit_optimize_above_cost;
6466

6567

6668
extern void jit_reset_after_error(void);

src/include/nodes/execnodes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@ typedef struct EState
528528

529529
/* The per-query shared memory area to use for parallel execution. */
530530
struct dsa_area *es_query_dsa;
531+
532+
/*
533+
* JIT information. es_jit_flags indicates whether JIT should be performed
534+
* and with which options. es_jit is created on-demand when JITing is
535+
* performed.
536+
*/
537+
int es_jit_flags;
538+
struct JitContext *es_jit;
531539
} EState;
532540

533541

src/include/nodes/plannodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ typedef struct PlannedStmt
5858

5959
bool parallelModeNeeded; /* parallel mode required to execute? */
6060

61+
int jitFlags; /* which forms of JIT should be performed */
62+
6163
struct Plan *planTree; /* tree of Plan nodes */
6264

6365
List *rtable; /* list of RangeTblEntry nodes */

0 commit comments

Comments
 (0)