From cb02d0d1d7fa63f19a4cd6464a6af48b59ebfb95 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Wed, 24 Aug 2022 19:58:45 -0700 Subject: [PATCH v12 14/15] meson: Add LLVM bitcode emission This needs a bit more love before being ready... --- src/backend/jit/llvm/meson.build | 21 +++++++++++++++ src/backend/meson.build | 46 ++++++++++++++++++++++++++++++++ meson.build | 2 ++ src/tools/irlink | 39 +++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 src/tools/irlink diff --git a/src/backend/jit/llvm/meson.build b/src/backend/jit/llvm/meson.build index de2e624ab58..ede51503377 100644 --- a/src/backend/jit/llvm/meson.build +++ b/src/backend/jit/llvm/meson.build @@ -48,6 +48,19 @@ else llvm_irgen_command = clang endif +llvm_irlink_kw = { + 'command': [ + irlink, + '--name', 'postgres', + '--lto', llvm_lto, + '--outdir', '@OUTPUT0@', + '--privdir', '@PRIVATE_DIR@', + '@INPUT@', + ], + 'install': true, + 'install_dir': dir_lib_pkg, +} + # XXX: Need to determine proper version of the function cflags for clang bitcode_cflags = ['-fno-strict-aliasing', '-fwrapv'] @@ -71,3 +84,11 @@ llvmjit_types = custom_target('llvmjit_types.bc', depfile: '@BASENAME@.c.bc.d', ) backend_targets += llvmjit_types + +# Figure out -I's needed to build all postgres code, including all its +# dependencies +pkg_config = find_program(['pkg-config', 'pkgconf'], required: true) +r = run_command(pkg_config, + ['--cflags-only-I', meson.build_root() / 'meson-uninstalled/postgresql-extension-uninstalled.pc'], + check: true) +bitcode_cflags += r.stdout().split() diff --git a/src/backend/meson.build b/src/backend/meson.build index 537afe413c9..3a2fc51bda3 100644 --- a/src/backend/meson.build +++ b/src/backend/meson.build @@ -281,3 +281,49 @@ subdir('replication/libpqwalreceiver') subdir('replication/pgoutput') subdir('snowball') subdir('utils/mb/conversion_procs') + + + +############################################################### +# emit LLVM bitcode of backend code for JIT inlining +############################################################### + +if llvm.found() + + # custom_target() insists on targetting files into the current + # directory. But we have files with the same name in different + # subdirectories. generators() don't have that problem, but their results + # are not installable. The irlink command copies the files for us. + # + # FIXME: this needs to be in a central place + # + # generators don't accept CustomTargetIndex as input or 'depends', nor do + # they like targets with more than one output. However, a custom target + # accepts them as input without a problem. So we have the below transitive + # target :( + + transitive_depend_target = custom_target('stamp', + input: generated_headers + generated_backend_headers + generated_backend_sources, + output: 'stamp', + command: [touch, '@OUTPUT@'], + install: false) + + llvm_gen = generator(llvm_irgen_command, + arguments: llvm_irgen_args + bitcode_cflags, + depends: transitive_depend_target, + depfile: '@BASENAME@.c.bc.d', + output: '@PLAINNAME@.bc', + ) + + bc_backend_sources = llvm_gen.process(backend_sources, + preserve_path_from: meson.current_source_dir()) + + postgres_llvm = custom_target('bitcode', + output: ['bitcode'], + input: bc_backend_sources, + kwargs: llvm_irlink_kw, + ) + + backend_targets += postgres_llvm + +endif diff --git a/meson.build b/meson.build index e64054b1c56..b9eaad73628 100644 --- a/meson.build +++ b/meson.build @@ -638,6 +638,8 @@ if not llvmopt.disabled() ccache = find_program('ccache', native: true, required: false) clang = find_program(llvm_binpath / 'clang', required: true) + llvm_lto = find_program(llvm_binpath / 'llvm-lto', required: true) + irlink = find_program('src/tools/irlink', native: true) endif else llvm = not_found_dep diff --git a/src/tools/irlink b/src/tools/irlink new file mode 100644 index 00000000000..7d3f49da427 --- /dev/null +++ b/src/tools/irlink @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +import os +import shutil +import subprocess +import sys +import argparse + +parser = argparse.ArgumentParser(description='generate PostgreSQL JIT IR module') + +parser.add_argument('--name', type=str, required=True) +parser.add_argument('--lto', type=str, required=True) +parser.add_argument('--privdir', type=str, required=True) +parser.add_argument('--outdir', type=str, required=True) +parser.add_argument('INPUT', type=str, nargs='+') + +args = parser.parse_args() + +outdir = os.path.realpath(args.outdir) +privdir = os.path.realpath(args.privdir) + +#index = os.path.realpath(args.index) +index = '{0}/{1}.index.bc'.format(outdir, args.name) +destdir = '{0}/{1}'.format(outdir, args.name) + +# Remove old contents if exist +if os.path.exists(destdir): + shutil.rmtree(destdir) + +shutil.copytree(privdir, destdir) + +# Change working directory for irlink to link correctly +os.chdir(args.outdir) + +file_names = [args.name + input.replace(args.privdir, '') for input in args.INPUT] +command = [args.lto, '-thinlto', '-thinlto-action=thinlink', '-o', index] + file_names +res = subprocess.run(command) + +exit(res.returncode) -- 2.37.0.3.g30cc8d0f14