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/20170901064131.tazjxwus3k2w3ybh@alap3.anarazel.de
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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy