Re: WIP: expression evaluation improvements

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Robert Haas <robertmhaas@gmail.com>
Cc: "pgsql-hackers@postgresql.org" <pgsql-hackers@postgresql.org>
Date: 2021-11-05T23:01:57Z
Lists: pgsql-hackers
Hi,

On 2021-11-05 14:13:38 -0400, Robert Haas wrote:
> On Fri, Nov 5, 2021 at 1:20 PM Andres Freund <andres@anarazel.de> wrote:
> > Yes. Optimally we'd do JIT caching across connections as well. One of the
> > biggest issues with the costs of JITing is actually parallel query, where
> > we'll often recreate the same JIT code again and again. For that you really
> > can't have much in the way of pointers...
> 
> Well that much is clear, and parallel query also needs relative
> pointers in some places for other reasons, which reminds me to ask you
> whether these new relative pointers can't reuse "utils/relptr.h"
> instead of inventing another way of do it. And if not maybe we should
> try to first change relptr.h and the one existing client
> (freepage.c/h) to something better and then use that in both places,
> because if we're going to be stuck with relative pointers are all over
> the place it would at least be nice not to have too many different
> kinds.

Hm. Yea, that's a fair point. Right now the "allocno" bit would be a
problem. Perhaps we can get around that somehow. We could search for
allocations by the offset, I guess.


> > > It's a pretty annoying problem, really. Somehow it's hard to shake the
> > > feeling that there ought to be a better approach than relative
> > > pointers.
> >
> > Yes. I don't like it much either :(. Basically native code has the same issue,
> > and also largely ended up with making most things relative (see x86-64 which
> > does most addressing relative to the instruction pointer, and binaries
> > pre-relocation, where the addresses aren't resolved yed).
> 
> Yes, but the good thing about those cases is that they're handled by
> the toolchain. What's irritating about this case is that we're using a
> just-in-time compiler, and yet somehow it feels like the job that
> ought to be done by the compiler is having to be done by our code, and
> the result is a lot of extra notation. I don't know what the
> alternative is -- if you don't tell the compiler which things it's
> supposed to assume are constant and which things might vary from
> execution to execution, it can't know. But it feels a little weird
> that there isn't some better way to give it that information.

Yes, I feel like there must be something better too. But in the end, I think
we want something like this for the non-JIT path too, so that we can avoid the
expensive re-creation of expression for every query execution. Which does make
referencing at least the mutable data only by offset fairly attractive, imo.

Greetings,

Andres Freund



Commits

  1. Add special case fast-paths for strict functions

  2. Replace EEOP_DONE with special steps for return/no return

  3. jit: Reference expression step functions via llvmjit_types.

  4. jit: Remove redundancies in expression evaluation code generation.

  5. expression eval: Don't redundantly keep track of AggState.

  6. jit: Reference functions by name in IOCOERCE steps.

  7. expression eval, jit: Minor code cleanups.