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  
        #include "commands/trigger.h"
  #include "executor/execdebug.h"
  #include "foreign/fdwapi.h"
 +#include "jit/jit.h"
  #include "mb/pg_wchar.h"
  #include "miscadmin.h"
  #include "optimizer/clauses.h"
      estate->es_top_eflags = eflags;
     estate->es_instrument = queryDesc->instrument_options;
  
 +   if (queryDesc->plannedstmt)
 +       estate->es_jit_flags = queryDesc->plannedstmt->jitFlags;
 +
     /*
      * Set up an AFTER-trigger statement context, unless told not to, or
      * unless it's EXPLAIN-only mode (when ExecutorFinish won't be called).
      UnregisterSnapshot(estate->es_snapshot);
     UnregisterSnapshot(estate->es_crosscheck_snapshot);
  
 +   /* release JIT context, if allocated */
 +   if (estate->es_jit)
 +       jit_release_context(estate->es_jit);
 +
     /*
      * Must switch out of context before destroying it
      */
             int64       tuples_needed;  /* tuple bound, see ExecSetTupleBound */
     dsa_pointer param_exec;
     int         eflags;
 +   int         jit_flags;
  } FixedParallelExecutorState;
  
  /*
      fpes->tuples_needed = tuples_needed;
     fpes->param_exec = InvalidDsaPointer;
     fpes->eflags = estate->es_top_eflags;
 +   fpes->jit_flags = estate->es_jit_flags;
     shm_toc_insert(pcxt->toc, PARALLEL_KEY_EXECUTOR_FIXED, fpes);
  
     /* Store query string */
      area = dsa_attach_in_place(area_space, seg);
  
     /* Start up the executor */
 +   queryDesc->plannedstmt->jitFlags = fpes->jit_flags;
     ExecutorStart(queryDesc, fpes->eflags);
  
     /* Special executor initialization steps for parallel workers */
          
     estate->es_use_parallel_mode = false;
  
 +   estate->es_jit_flags = 0;
 +   estate->es_jit = NULL;
 +
     /*
      * Return the executor state structure
      */
          bool       jit_debugging_support = false;
  bool       jit_dump_bitcode = false;
  bool       jit_profiling_support = false;
 +double     jit_above_cost = 100000;
 +double     jit_optimize_above_cost = 500000;
  
  static JitProviderCallbacks provider;
  static bool provider_successfully_loaded = false;
             COPY_SCALAR_FIELD(transientPlan);
     COPY_SCALAR_FIELD(dependsOnRole);
     COPY_SCALAR_FIELD(parallelModeNeeded);
 +   COPY_SCALAR_FIELD(jitFlags);
     COPY_NODE_FIELD(planTree);
     COPY_NODE_FIELD(rtable);
     COPY_NODE_FIELD(resultRelations);
             WRITE_BOOL_FIELD(transientPlan);
     WRITE_BOOL_FIELD(dependsOnRole);
     WRITE_BOOL_FIELD(parallelModeNeeded);
 +   WRITE_BOOL_FIELD(jitFlags);
     WRITE_NODE_FIELD(planTree);
     WRITE_NODE_FIELD(rtable);
     WRITE_NODE_FIELD(resultRelations);
             READ_BOOL_FIELD(transientPlan);
     READ_BOOL_FIELD(dependsOnRole);
     READ_BOOL_FIELD(parallelModeNeeded);
 +   READ_BOOL_FIELD(jitFlags);
     READ_NODE_FIELD(planTree);
     READ_NODE_FIELD(rtable);
     READ_NODE_FIELD(resultRelations);
          #include "executor/nodeAgg.h"
  #include "foreign/fdwapi.h"
  #include "miscadmin.h"
 +#include "jit/jit.h"
  #include "lib/bipartite_match.h"
  #include "lib/knapsack.h"
  #include "nodes/makefuncs.h"
      result->stmt_location = parse->stmt_location;
     result->stmt_len = parse->stmt_len;
  
 +   result->jitFlags = PGJIT_NONE;
 +   if (jit_enabled && jit_above_cost >= 0 &&
 +       top_plan->total_cost > jit_above_cost)
 +   {
 +       result->jitFlags |= PGJIT_PERFORM;
 +
 +       /*
 +        * Decide how much effort should be put into generating better code.
 +        */
 +       if (jit_optimize_above_cost >= 0 &&
 +           top_plan->total_cost > jit_optimize_above_cost)
 +           result->jitFlags |= PGJIT_OPT3;
 +   }
 +
     return result;
  }
  
                 NULL, NULL, NULL
     },
  
 +   {
 +       {"jit_above_cost", PGC_USERSET, QUERY_TUNING_COST,
 +           gettext_noop("Perform JIT compilation if query is more expensive."),
 +           gettext_noop("-1 disables JIT compilation.")
 +       },
 +       &jit_above_cost,
 +       100000, -1, DBL_MAX,
 +       NULL, NULL, NULL
 +   },
 +
 +   {
 +       {"jit_optimize_above_cost", PGC_USERSET, QUERY_TUNING_COST,
 +           gettext_noop("Optimize JITed functions if query is more expensive."),
 +           gettext_noop("-1 disables optimization.")
 +       },
 +       &jit_optimize_above_cost,
 +       500000, -1, DBL_MAX,
 +       NULL, NULL, NULL
 +   },
 +
     {
         {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER,
             gettext_noop("Sets the planner's estimate of the fraction of "
          #cpu_operator_cost = 0.0025        # same scale as above
  #parallel_tuple_cost = 0.1     # same scale as above
  #parallel_setup_cost = 1000.0  # same scale as above
 +
 +#jit_above_cost = 100000       # perform JIT compilation if available
 +                   # and query more expensive, -1 disables
 +#jit_optimize_above_cost = 500000  # optimize JITed functions if query is
 +                   # more expensive, -1 disables
 +
  #min_parallel_table_scan_size = 8MB
  #min_parallel_index_scan_size = 512kB
  #effective_cache_size = 4GB
          extern bool jit_debugging_support;
  extern bool jit_dump_bitcode;
  extern bool jit_profiling_support;
 +extern double jit_above_cost;
 +extern double jit_optimize_above_cost;
  
  
  extern void jit_reset_after_error(void);
          
     /* The per-query shared memory area to use for parallel execution. */
     struct dsa_area *es_query_dsa;
 +
 +   /*
 +    * JIT information. es_jit_flags indicates whether JIT should be performed
 +    * and with which options.  es_jit is created on-demand when JITing is
 +    * performed.
 +    */
 +   int         es_jit_flags;
 +   struct JitContext *es_jit;
  } EState;
  
  
          
     bool        parallelModeNeeded; /* parallel mode required to execute? */
  
 +   int         jitFlags;       /* which forms of JIT should be performed */
 +
     struct Plan *planTree;      /* tree of Plan nodes */
  
     List       *rtable;         /* list of RangeTblEntry nodes */