Skip to content

Commit 60cd583

Browse files
committed
meson: Add LLVM bitcode emission
This needs a bit more love before being ready...
1 parent ddc5eaf commit 60cd583

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ if not llvmopt.disabled()
699699

700700
ccache = find_program('ccache', native: true, required: false)
701701
clang = find_program(llvm_binpath / 'clang', required: true)
702+
llvm_lto = find_program(llvm_binpath / 'llvm-lto', required: true)
703+
irlink = find_program('src/tools/irlink', native: true)
702704
endif
703705
else
704706
llvm = not_found_dep

src/backend/jit/llvm/meson.build

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ else
5555
llvm_irgen_command = clang
5656
endif
5757

58+
llvm_irlink_kw = {
59+
'command': [
60+
irlink,
61+
'--name', 'postgres',
62+
'--lto', llvm_lto,
63+
'--outdir', '@OUTPUT0@',
64+
'--privdir', '@PRIVATE_DIR@',
65+
'@INPUT@',
66+
],
67+
'install': true,
68+
'install_dir': dir_lib_pkg,
69+
}
70+
5871

5972
# XXX: Need to determine proper version of the function cflags for clang
6073
bitcode_cflags = ['-fno-strict-aliasing', '-fwrapv']
@@ -81,3 +94,11 @@ llvmjit_types = custom_target('llvmjit_types.bc',
8194
depfile: '@BASENAME@.c.bc.d',
8295
)
8396
backend_targets += llvmjit_types
97+
98+
# Figure out -I's needed to build all postgres code, including all its
99+
# dependencies
100+
pkg_config = find_program(['pkg-config', 'pkgconf'], required: true)
101+
r = run_command(pkg_config,
102+
['--cflags-only-I', meson.build_root() / 'meson-uninstalled/postgresql-extension-uninstalled.pc'],
103+
check: true)
104+
bitcode_cflags += r.stdout().split()

src/backend/meson.build

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,49 @@ subdir('replication/libpqwalreceiver')
299299
subdir('replication/pgoutput')
300300
subdir('snowball')
301301
subdir('utils/mb/conversion_procs')
302+
303+
304+
305+
###############################################################
306+
# emit LLVM bitcode of backend code for JIT inlining
307+
###############################################################
308+
309+
if llvm.found()
310+
311+
# custom_target() insists on targeting files into the current
312+
# directory. But we have files with the same name in different
313+
# subdirectories. generators() don't have that problem, but their results
314+
# are not installable. The irlink command copies the files for us.
315+
#
316+
# FIXME: this needs to be in a central place
317+
#
318+
# generators don't accept CustomTargetIndex as input or 'depends', nor do
319+
# they like targets with more than one output. However, a custom target
320+
# accepts them as input without a problem. So we have the below transitive
321+
# target :(
322+
323+
transitive_depend_target = custom_target('stamp',
324+
input: generated_headers + generated_backend_headers + generated_backend_sources,
325+
output: 'stamp',
326+
command: [touch, '@OUTPUT@'],
327+
install: false)
328+
329+
llvm_gen = generator(llvm_irgen_command,
330+
arguments: llvm_irgen_args + bitcode_cflags,
331+
depends: transitive_depend_target,
332+
depfile: '@BASENAME@.c.bc.d',
333+
output: '@PLAINNAME@.bc',
334+
)
335+
336+
bc_backend_sources = llvm_gen.process(backend_sources,
337+
preserve_path_from: meson.current_source_dir())
338+
339+
postgres_llvm = custom_target('bitcode',
340+
output: ['bitcode'],
341+
input: bc_backend_sources,
342+
kwargs: llvm_irlink_kw,
343+
)
344+
345+
backend_targets += postgres_llvm
346+
347+
endif

src/tools/irlink

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import shutil
5+
import subprocess
6+
import sys
7+
import argparse
8+
9+
parser = argparse.ArgumentParser(
10+
description='generate PostgreSQL JIT IR module')
11+
12+
parser.add_argument('--name', type=str, required=True)
13+
parser.add_argument('--lto', type=str, required=True)
14+
parser.add_argument('--privdir', type=str, required=True)
15+
parser.add_argument('--outdir', type=str, required=True)
16+
parser.add_argument('INPUT', type=str, nargs='+')
17+
18+
args = parser.parse_args()
19+
20+
outdir = os.path.realpath(args.outdir)
21+
privdir = os.path.realpath(args.privdir)
22+
23+
index = '{0}/{1}.index.bc'.format(outdir, args.name)
24+
destdir = '{0}/{1}'.format(outdir, args.name)
25+
26+
# Remove old contents if exist
27+
if os.path.exists(destdir):
28+
shutil.rmtree(destdir)
29+
30+
shutil.copytree(privdir, destdir)
31+
32+
# Change working directory for irlink to link correctly
33+
os.chdir(args.outdir)
34+
35+
file_names = []
36+
for input in args.INPUT:
37+
file_names += [args.name + input.replace(args.privdir, '')]
38+
39+
command = [args.lto, '-thinlto', '-thinlto-action=thinlink',
40+
'-o', index] + file_names
41+
res = subprocess.run(command)
42+
43+
exit(res.returncode)

0 commit comments

Comments
 (0)