Re: JIT compiling with LLVM v11

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
Cc: pgsql-hackers@postgresql.org, Pierre Ducroquet <p.psql@pinaraf.info>
Date: 2018-03-03T19:39:55Z
Lists: pgsql-hackers
Hi,

On 2018-03-03 09:37:35 -0500, Peter Eisentraut wrote:
> On 3/2/18 19:29, Andres Freund wrote:
> >> Using my standard set of CC=gcc-7 and CXX=g++-7, the build fails with
> >>
> >> g++-7: error: unrecognized command line option '-stdlib=libc++'
> 
> > It's actually already filtered, I just added -std*, because of selecting
> > the c++ standard, I guess I need to filter more aggressively.  This is
> > fairly fairly annoying.
> 
> I see you already filter llvm-config --cflags by picking only -I and -D.
>  Why not do the same for --cxxflags?  Any other options that we need
> like -f* should be discovered using the normal
> does-the-compiler-support-this-option tests.

Well, some -f obtions are ABI / behaviour influencing.  You can't, to my
knowledge, mix/match code build with -fno-rtti with code built with it
(influences symbol names).  LLVM builds without rtti by default, but a
lot of distros enable it...

I narrowed the filter to -std= (from -std), which should take care of
the -stdlib bit. I also dropped -fno-exceptions being copied since that
should not conflict.


> >> It seems that it was intended that way anyway, since llvmjit.h contains
> >> its own provisions for extern C.
> > 
> > Hrmpf, yea, I broke that the third time now.  I'm actually inclined to
> > add an appropriate #ifdef ... #error so it's not repeated, what do you
> > think?
> 
> Not sure.  Why not just move the line and not move it again? ;-)

Heh, done ;). Let's see how long it takes...


> > Does putting an
> > override COMPILER = $(CXX) $(CFLAGS)
> > 
> > into src/backend/jit/llvm/Makefile work?  It does force the use of CXX
> > for all important platforms if I see it correctly. Verified that it
> > works on linux.
> 
> Your latest HEAD builds out of the box for me now using the system compiler.

Cool.


> >> configure didn't find any of the LLVMOrc* symbols it was looking for.
> >> Is that a problem?  They seem to be for some debugging support.
> > 
> > That's not a problem, except that the symbols won't be registered with
> > the debugger, which is a bit annoying for backtraces. I tried to have
> > configure throw errors in cases llvm is too old or such.
> 
> Where does one get those then?  I have LLVM 5.0.1.  Is there something
> even newer?

I've submitted them upstream, but they're not yet released.


> > Hm, I'll switch them on in the development branch. Independent of the
> > final decision that's definitely the right thing for now.  The "full
> > capability" of the patchset is used if you turn on these three GUCs:
> > 
> > -c jit_expressions=1
> > -c jit_tuple_deforming=1
> > -c jit_perform_inlining=1
> 
> The last one doesn't seem to exist anymore.

Yup, as discussed in the earlier reply to you, I decided it's not
particularly useful to have.  As also threatened in that reply, I've
switched the defaults so you shouldn't have to change them anymore.


> If I turn on either of the first two, then make installcheck fails.  See
> attached diff.

Hm, so there's definitely something going on here that I don't yet
understand. I've pushed something that I've a slight hunch about
(dropping the dots from the symbol names, some tooling doesn't seem to
like that).

I'd to rebase to fix a few issues, but I've left the changes made since
the last push as separate commits.

Could you run something like:
regression[18425][1]=# set jit_above_cost = 0;
SET
regression[18425][1]=# set client_min_messages=debug2;
SET
regression[18425][1]=# SELECT pg_jit_available();
DEBUG:  00000: probing availability of llvm for JIT at /home/andres/build/postgres/dev-assert/install/lib/llvmjit.so
LOCATION:  provider_init, jit.c:83
DEBUG:  00000: successfully loaded LLVM in current session
LOCATION:  provider_init, jit.c:107
DEBUG:  00000: time to opt: 0.001s
LOCATION:  llvm_compile_module, llvmjit.c:435
DEBUG:  00000: time to emit: 0.014s
LOCATION:  llvm_compile_module, llvmjit.c:481
┌──────────────────┐
│ pg_jit_available │
├──────────────────┤
│ t                │
└──────────────────┘
(1 row)

regression[18425][1]=# select now();
DEBUG:  00000: time to opt: 0.001s
LOCATION:  llvm_compile_module, llvmjit.c:435
DEBUG:  00000: time to emit: 0.008s
LOCATION:  llvm_compile_module, llvmjit.c:481
┌───────────────────────────────┐
│              now              │
├───────────────────────────────┤
│ 2018-03-03 11:33:13.776947-08 │
└───────────────────────────────┘
(1 row)

regression[18425][1]=# SET jit_dump_bitcode = 1;
SET
regression[18425][1]=# select now();
DEBUG:  00000: time to opt: 0.002s
LOCATION:  llvm_compile_module, llvmjit.c:435
DEBUG:  00000: time to emit: 0.018s
LOCATION:  llvm_compile_module, llvmjit.c:481
┌───────────────────────────────┐
│              now              │
├───────────────────────────────┤
│ 2018-03-03 11:33:23.508875-08 │
└───────────────────────────────┘
(1 row)


The last command should have dumped something into your data directory,
even if it failed like your regression test output showed. Could attach
the two files something like
ls -lstr /srv/dev/pgdev-dev/*.b
would show if /srv/dev/pgdev-dev/ is your test directory?


If my random hunch or this doesn't bear fruit, I'm going to have to get
access to an OSX machine somehow :(


Independent of this, I'm working to make the code pgindent
compliant. Given the typical coding patterns when emitting IR (nested
function calls) that's painful because pgindent insists on indenting
everything a lot.  I've started adding a few small wrapper functions to
make that bearable...

Greetings,

Andres Freund


Commits

  1. Improve JIT docs.

  2. Add documentation for the JIT feature.

  3. Add EXPLAIN support for JIT.

  4. Add inlining support to LLVM JIT provider.

  5. JIT tuple deforming in LLVM JIT provider.

  6. Add FIELDNO_* macro designating offset into structs required for JIT.

  7. Add expression compilation support to LLVM JIT provider.

  8. Expand list of synchronized types and functions in LLVM JIT provider.

  9. Add helpers for emitting LLVM IR.

  10. Basic planner and executor integration for JIT.

  11. Debugging and profiling support for LLVM JIT provider.

  12. Support for optimizing and emitting code in LLVM JIT provider.

  13. Add file containing extensions of the LLVM C API.

  14. Basic JIT provider and error handling infrastructure.

  15. Add configure infrastructure (--with-llvm) to enable LLVM support.

  16. Add C++ support to configure.

  17. Add PGAC_PROG_VARCC_VARFLAGS_OPT autoconf macro.

  18. Fix VM buffer pin management in heap_lock_updated_tuple_rec().

  19. Allow tupleslots to have a fixed tupledesc, use in executor nodes.

  20. Expression evaluation based aggregate transition invocation.

  21. Perform slot validity checks in a separate pass over expression.

  22. Rely on executor utils to build targetlist for DML RETURNING.

  23. Refer to OS X as "macOS", except for the port name which is still "darwin".