Skip to content

Commit 28da5b8

Browse files
committed
[DEV-5385] Build CPython using BOLT
Using the patch adapted from python/cpython#95908
1 parent 12237a4 commit 28da5b8

File tree

4 files changed

+123
-3
lines changed

4 files changed

+123
-3
lines changed

Dockerfile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ RUN apt-get update && \
4848

4949
# matches our production except -march=haswell, we have to downgrade -march because of GHA
5050
ENV OPT="-pipe -fno-semantic-interposition -march=haswell -mabm -maes -mno-pku -mno-sgx --param l1-cache-line-size=64 --param l1-cache-size=32 --param l2-cache-size=33792"
51-
# Bolt: -Wl,--emit-relocs -fno-reorder-blocks-and-partition
51+
ADD patches/cpython_configure_ac.patch patches/cpython_makefile.patch patches/cpython_rules.patch /
5252

5353
# runtime environment
5454
RUN echo 'deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted' >>/etc/apt/sources.list && \
@@ -61,18 +61,27 @@ RUN echo 'deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted' >>/et
6161
python3-distutils html2text libjs-sphinxdoc && \
6262
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
6363
locale-gen && \
64+
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy main" >>/etc/apt/sources.list.d/llvm.list && \
65+
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
66+
apt-get update && \
67+
apt-get install -y bolt llvm && \
68+
export LLVM_SYMBOLIZER_PATH=/usr/lib/llvm/bin/llvm-symbolizer && \
6469
add-apt-repository -s ppa:deadsnakes/ppa && \
6570
mkdir /cpython && \
6671
cd /cpython && \
6772
apt-get source python$PYTHON_VERSION && \
6873
apt-get -s build-dep python$PYTHON_VERSION | grep "Inst " | cut -d" " -f2 | sort | tr '\n' ' ' >build_bloat && \
6974
DEBIAN_FRONTEND="noninteractive" TZ="Europe/Madrid" apt-get build-dep -y python$PYTHON_VERSION && \
70-
rm /etc/apt/sources.list.d/deadsnakes* && \
75+
rm /etc/apt/sources.list.d/deadsnakes* /etc/apt/sources.list.d/llvm.list && \
7176
cd python$PYTHON_VERSION* && \
7277
sed -i 's/__main__/__skip__/g' Tools/scripts/run_tests.py && \
7378
dch --bin-nmu -Dunstable "Optimized build" && \
7479
echo 11 >debian/compat && \
7580
sed -i 's/debhelper (>= 9)/debhelper (>= 11)/g' debian/control.in && \
81+
patch configure.ac </cpython_configure_ac.patch && \
82+
patch Makefile.pre.in </cpython_makefile.patch && \
83+
patch debian/rules </cpython_rules.patch && \
84+
rm /cpython_configure_ac.patch /cpython_makefile.patch /cpython_rules.patch && \
7685
DEB_CFLAGS_SET="$OPT" DEB_LDFLAGS_SET="$OPT" dpkg-buildpackage -uc -b -j$(getconf _NPROCESSORS_ONLN) && \
7786
cd .. && \
7887
apt-get source python3 && \
@@ -101,7 +110,7 @@ RUN echo 'deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted' >>/et
101110
python$PYTHON_VERSION-venv* \
102111
python$PYTHON_VERSION-full* && \
103112
echo "========" && ls && \
104-
apt-get purge -y dpkg-dev devscripts software-properties-common html2text $(cat build_bloat) && \
113+
apt-get purge -y dpkg-dev devscripts software-properties-common html2text bolt llvm $(cat build_bloat) && \
105114
apt-get autoremove -y && \
106115
dpkg -i *python3.11*.deb && \
107116
dpkg -i python3-minimal*.deb libpython3-stdlib*.deb && \

patches/cpython_configure_ac.patch

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
--- configure.ac 2022-11-16 11:37:19.773231374 +0100
2+
+++ configure.ac.bolt 2022-11-16 11:37:11.161182410 +0100
3+
@@ -1751,7 +1751,16 @@
4+
# non-suffixed name in their versioned llvm directory.
5+
6+
llvm_bin_dir=''
7+
-llvm_path="${PATH}"
8+
+
9+
+AC_ARG_WITH(llvm,
10+
+ AS_HELP_STRING([--with-llvm=PATH],
11+
+ [specify the directory where LLVM binaries are installed]),
12+
+[
13+
+ llvm_path=${withval}
14+
+],[
15+
+ llvm_path="${PATH}"
16+
+])
17+
+
18+
if test "${CC}" = "clang"
19+
then
20+
clang_bin=`which clang`
21+
@@ -1889,6 +1898,59 @@
22+
LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS"
23+
fi
24+
25+
+# Enable bolt flags
26+
+Py_BOLT='false'
27+
+AC_MSG_CHECKING(for --enable-bolt)
28+
+AC_ARG_ENABLE(bolt, AS_HELP_STRING(
29+
+ [--enable-bolt],
30+
+ [enable usage of the llvm-bolt post-link optimizer (default is no)]),
31+
+[
32+
+if test "$enableval" != no
33+
+then
34+
+ Py_BOLT='true'
35+
+ AC_MSG_RESULT(yes);
36+
+else
37+
+ Py_BOLT='false'
38+
+ AC_MSG_RESULT(no);
39+
+fi],
40+
+[AC_MSG_RESULT(no)])
41+
+
42+
+AC_SUBST(PREBOLT_RULE)
43+
+if test "$Py_BOLT" = 'true' ; then
44+
+ PREBOLT_RULE="${DEF_MAKE_ALL_RULE}"
45+
+ DEF_MAKE_ALL_RULE="bolt-opt"
46+
+ DEF_MAKE_RULE="build_all"
47+
+
48+
+ # These flags are required for bolt to work:
49+
+ CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition"
50+
+ LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs"
51+
+
52+
+ # These flags are required to get good performance from bolt:
53+
+ CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie"
54+
+ # We want to add these no-pie flags to linking executables but not shared libraries:
55+
+ LINKCC="$LINKCC -fno-pie -no-pie"
56+
+ # Designate the DWARF version into 4 since the LLVM-BOLT does not support DWARF5 yet.
57+
+ CFLAGS="$CFLAGS -gdwarf-4"
58+
+ LDFLAGS="$LDFLAGS -gdwarf-4"
59+
+ AC_SUBST(LLVM_BOLT)
60+
+ AC_PATH_TOOL(LLVM_BOLT, llvm-bolt, '', ${llvm_path})
61+
+ if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}"
62+
+ then
63+
+ AC_MSG_RESULT("Found llvm-bolt")
64+
+ else
65+
+ AC_MSG_ERROR([llvm-bolt is required for a --enable-bolt build but could not be found.])
66+
+ fi
67+
+
68+
+ AC_SUBST(MERGE_FDATA)
69+
+ AC_PATH_TOOL(MERGE_FDATA, merge-fdata, '', ${llvm_path})
70+
+ if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}"
71+
+ then
72+
+ AC_MSG_RESULT("Found merge-fdata")
73+
+ else
74+
+ AC_MSG_ERROR([merge-fdata is required for a --enable-bolt build but could not be found.])
75+
+ fi
76+
+fi
77+
+
78+
# Enable PGO flags.
79+
AC_SUBST(PGO_PROF_GEN_FLAG)
80+
AC_SUBST(PGO_PROF_USE_FLAG)

patches/cpython_makefile.patch

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--- Makefile.pre.in 2022-11-09 19:45:00.000000000 +0100
2+
+++ Makefile.pre.in.bolt 2022-11-16 12:06:59.565683052 +0100
3+
@@ -659,6 +659,16 @@
4+
-rm -f profile-clean-stamp
5+
$(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST)"
6+
7+
+bolt-opt: @PREBOLT_RULE@
8+
+ rm -f *.fdata
9+
+ @LLVM_BOLT@ ./$(BUILDPYTHON) -instrument -instrumentation-file-append-pid -instrumentation-file=$(abspath $(BUILDPYTHON).bolt) -o $(BUILDPYTHON).bolt_inst
10+
+ ./$(BUILDPYTHON).bolt_inst $(PROFILE_TASK) || true
11+
+ @MERGE_FDATA@ $(BUILDPYTHON).*.fdata > $(BUILDPYTHON).fdata
12+
+ @LLVM_BOLT@ ./$(BUILDPYTHON) -o $(BUILDPYTHON).bolt -data=$(BUILDPYTHON).fdata -update-debug-sections -reorder-blocks=ext-tsp -reorder-functions=hfsort+ -split-functions -icf=1 -inline-all -split-eh -reorder-functions-use-hot-size -peepholes=all -jump-tables=aggressive -inline-ap -indirect-call-promotion=all -dyno-stats -use-gnu-stack -frame-opt=hot
13+
+ rm -f *.fdata
14+
+ rm -f $(BUILDPYTHON).bolt_inst
15+
+ mv $(BUILDPYTHON).bolt $(BUILDPYTHON)
16+
+
17+
# Compile and run with gcov
18+
.PHONY=coverage coverage-lcov coverage-report
19+
coverage:

patches/cpython_rules.patch

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--- rules 2022-11-16 12:34:58.128078268 +0100
2+
+++ rules.bolt 2022-11-16 12:37:40.129579671 +0100
3+
@@ -394,7 +394,8 @@
4+
CPPFLAGS="$(DPKG_CPPFLAGS)" LDFLAGS="$(DPKG_LDFLAGS) $(LTO_CFLAGS)" \
5+
$(config_site) \
6+
../configure \
7+
- $(common_configure_args)
8+
+ $(common_configure_args) \
9+
+ --with-llvm=/usr/lib/llvm/bin --enable-bolt
10+
11+
$(call __post_configure,$(buildd_static))
12+
touch $@

0 commit comments

Comments
 (0)