Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2931a33

Browse files
nbyavuzCommitfest Bot
authored and
Commitfest Bot
committed
meson: Add architecture for LLVM bitcode emission
This commit adds suport for bitcode emission for both normal and generated source files (processed by bison, flex, etc). These bitcode files are installed into $pkglibdir/bitcode/ directory if the LLVM is found. New variable `bitcode_modules` is introduced to generate bitcode files. All required information is gathered in this variable. Then, this variable is processed by the main meson LLVM bitcode emission scripts: src/backend/jit/llvm/bitcode/meson.build -> src/tools/irlink. An example of a possible structure of bitcode_modules is: ``` bitcode_modules = [ { 'name': '...', 'target': ..., 'srcfiles': [ '...', '...', ], 'additional_flags': [ '-I...', '-I...', ], 'gen_srcfiles': [ { 'srcfiles': [ <custom_target for ...>, <custom_target for ...>, ], 'additional_flags': [ '-I...', '-I...', ] } ] } ] ``` Author: Andres Freund <andres@anarazel.de> Author: Nazir Bilal Yavuz <byavuz81@gmail.com> Author: Diego Fronza <diego.fronza@percona.com> Reviewed-by: Diego Fronza <diego.fronza@percona.com> Discussion: https://postgr.es/m/206b001d-1884-4081-bd02-bed5c92f02ba%40eisentraut.org
1 parent 05a5ede commit 2931a33

File tree

5 files changed

+141
-11
lines changed

5 files changed

+141
-11
lines changed

meson.build

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,8 @@ if add_languages('cpp', required: llvmopt, native: false)
815815
# Some distros put LLVM and clang in different paths, so fallback to
816816
# find via PATH, too.
817817
clang = find_program(llvm_binpath / 'clang', 'clang', required: true)
818+
llvm_lto = find_program(llvm_binpath / 'llvm-lto', required: true)
819+
irlink = find_program('src/tools/irlink', native: true)
818820
endif
819821
elif llvmopt.auto()
820822
message('llvm requires a C++ compiler')
@@ -3044,6 +3046,11 @@ test_deps = []
30443046
tests = []
30453047
meson_extension_tests = []
30463048

3049+
# List of object files + source files to generated LLVM IR for inlining.
3050+
# Each element is a hash of:
3051+
# {'target': target, 'srcfiles': ..., 'additional_flags': ...}.
3052+
bitcode_modules = []
3053+
30473054

30483055
# Default options for targets
30493056

@@ -3366,6 +3373,11 @@ subdir('src/interfaces/ecpg/test')
33663373

33673374
subdir('doc/src/sgml')
33683375

3376+
# generate bitcode for JIT inlining after giving contrib modules etc a chance
3377+
# to add themselves to bitcode_modules[]
3378+
subdir('src/backend/jit/llvm/bitcode', if_found: llvm)
3379+
3380+
33693381
generated_sources_ac += {'': ['GNUmakefile']}
33703382

33713383
# After processing src/test, add test_install_libs to the testprep_targets
@@ -4001,6 +4013,15 @@ if meson.version().version_compare('>=0.57')
40014013
section: 'Programs',
40024014
)
40034015

4016+
if llvm.found()
4017+
summary(
4018+
{
4019+
'clang': clang,
4020+
},
4021+
section: 'Programs',
4022+
)
4023+
endif
4024+
40044025
summary(
40054026
{
40064027
'bonjour': bonjour,
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright (c) 2022-2024, PostgreSQL Global Development Group
2+
#
3+
# emit LLVM bitcode for JIT inlining
4+
5+
assert(llvm.found())
6+
7+
foreach bitcode_module : bitcode_modules
8+
bitcode_targets = []
9+
bitcode_obj = bitcode_module['target']
10+
bitcode_cflags_local = bitcode_cflags + bitcode_module.get('additional_flags', [])
11+
bitcode_name = bitcode_module.get('name', bitcode_obj.name())
12+
13+
foreach srcfile : bitcode_module['srcfiles']
14+
if meson.version().version_compare('>=0.59')
15+
srcfilename = fs.parent(srcfile) / fs.name(srcfile)
16+
else
17+
srcfilename = '@0@'.format(srcfile)
18+
endif
19+
20+
targetname = '@0@_@1@.bc'.format(
21+
bitcode_name,
22+
srcfilename.underscorify(),
23+
)
24+
bitcode_targets += custom_target(
25+
targetname,
26+
depends: [bitcode_obj],
27+
input: [srcfile],
28+
output: targetname,
29+
command: [llvm_irgen_command, bitcode_cflags_local],
30+
install: true,
31+
install_dir: dir_bitcode,
32+
)
33+
endforeach
34+
35+
# Process generated sources, which may include custom compilation flags.
36+
foreach gen_sources: bitcode_module.get('gen_sources', [])
37+
bitcode_cflags_gen_local = bitcode_cflags_local + gen_sources.get('additional_flags', [])
38+
39+
foreach srcfile: gen_sources['srcfiles']
40+
# Generated sources are stored in some folder under meson.build_root()/**,
41+
# remove the build prefix from the string.
42+
srcfilename = srcfile.full_path().split(meson.build_root() + '/')[1]
43+
44+
targetname = '@0@_@1@.bc'.format(
45+
bitcode_name,
46+
srcfilename.underscorify(),
47+
)
48+
bitcode_targets += custom_target(
49+
targetname,
50+
depends: [bitcode_obj],
51+
input: [srcfile],
52+
output: targetname,
53+
command: [llvm_irgen_command, bitcode_cflags_gen_local],
54+
install: true,
55+
install_dir: dir_bitcode,
56+
)
57+
endforeach
58+
endforeach
59+
60+
index_name = '@0@.index.bc'.format(bitcode_name)
61+
bitcode_index = custom_target('@0@'.format(bitcode_name),
62+
output: index_name,
63+
input: bitcode_targets,
64+
command: [irlink, '--lto', llvm_lto, '--outdir', '@OUTDIR@', '--index', index_name, '@INPUT@'],
65+
install: true,
66+
install_dir: dir_bitcode,
67+
)
68+
backend_targets += bitcode_index
69+
endforeach

src/backend/jit/llvm/meson.build

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,22 @@ backend_targets += llvmjit
4242

4343
# Define a few bits and pieces used here and elsewhere to generate bitcode
4444

45-
llvm_irgen_args = [
46-
'-c', '-o', '@OUTPUT@', '@INPUT@',
45+
llvm_irgen_command = []
46+
if ccache.found()
47+
llvm_irgen_command += ccache
48+
endif
49+
50+
llvm_irgen_command += [
51+
clang,
52+
'-c', '-o', '@OUTPUT0@', '@INPUT0@',
4753
'-flto=thin', '-emit-llvm',
48-
'-MD', '-MQ', '@OUTPUT@', '-MF', '@DEPFILE@',
4954
'-O2',
5055
'-Wno-ignored-attributes',
5156
'-Wno-empty-body',
57+
'-Wno-unknown-warning-option',
58+
'-Wno-compound-token-split-by-macro',
5259
]
53-
54-
if ccache.found()
55-
llvm_irgen_command = ccache
56-
llvm_irgen_args = [clang.path()] + llvm_irgen_args
57-
else
58-
llvm_irgen_command = clang
59-
endif
60+
llvm_irgen_dep_args = ['-MD', '-MQ', '@OUTPUT0@', '-MF', '@DEPFILE@']
6061

6162

6263
# XXX: Need to determine proper version of the function cflags for clang
@@ -73,7 +74,7 @@ bitcode_cflags += '-I@SOURCE_ROOT@/src/include'
7374
# Note this is intentionally not installed to bitcodedir, as it's not for
7475
# inlining
7576
llvmjit_types = custom_target('llvmjit_types.bc',
76-
command: [llvm_irgen_command] + llvm_irgen_args + bitcode_cflags,
77+
command: llvm_irgen_command + llvm_irgen_dep_args + bitcode_cflags,
7778
input: 'llvmjit_types.c',
7879
output: 'llvmjit_types.bc',
7980
depends: [postgres],
@@ -82,3 +83,11 @@ llvmjit_types = custom_target('llvmjit_types.bc',
8283
depfile: '@BASENAME@.c.bc.d',
8384
)
8485
backend_targets += llvmjit_types
86+
87+
# Figure out -I's needed to build all postgres code, including all its
88+
# dependencies
89+
pkg_config = find_program(['pkg-config', 'pkgconf'], required: true)
90+
r = run_command(pkg_config,
91+
['--cflags-only-I', meson.build_root() / 'meson-uninstalled/postgresql-extension-uninstalled.pc'],
92+
check: true)
93+
bitcode_cflags += r.stdout().split()

src/backend/meson.build

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ postgres = executable('postgres',
140140

141141
backend_targets += postgres
142142

143+
bitcode_modules += {
144+
'name': 'postgres',
145+
'target': postgres_lib,
146+
'srcfiles': backend_sources,
147+
}
148+
143149
pg_mod_c_args = cflags_mod
144150
pg_mod_cpp_args = cxxflags_mod
145151
pg_mod_link_args = ldflags_sl + ldflags_mod

src/tools/irlink

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import os
5+
import shutil
6+
import subprocess
7+
import sys
8+
9+
parser = argparse.ArgumentParser(
10+
description='generate PostgreSQL JIT IR module')
11+
12+
parser.add_argument('--index', type=str, required=True)
13+
parser.add_argument('--lto', type=str, required=True)
14+
parser.add_argument('--outdir', type=str, required=True)
15+
parser.add_argument('INPUT', type=str, nargs='+')
16+
17+
args = parser.parse_args()
18+
19+
file_names = [os.path.basename(f) for f in args.INPUT]
20+
command = [args.lto,
21+
'-thinlto', '-thinlto-action=thinlink',
22+
'-o', args.index] + file_names
23+
res = subprocess.run(command, cwd=args.outdir)
24+
25+
exit(res.returncode)

0 commit comments

Comments
 (0)