From a43ae0d098da2b0a5d77b6ecbc578f6d14b22d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 4 Sep 2021 10:38:41 +0200 Subject: [PATCH] pgo: replace meson-pgo.sh with several script primitives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All scripts are in the ‘pgo’ directory: * options: command line options for generate-alt-random-writes.py, sourced by other scripts. * pgo.sh: top-level script, generates a meson build directory, selects a PGO method, generates the profiling data, re-configures the meson build directory and does the final build. This script is intended to be used by end-users, and shows _how_ to integrate the script primitives. Build servers will most likely *not* want to use this script as-is. * partial.sh: generates alt-random-write data and runs “foot{,client} --version”, and then feeds the alt-random data to the PGO helper binary. Does not require a running Wayland session. Touches $blddir/pgo-ok on success. * full-inner.sh: runs “footclient --version”, and then a complex “foot” command that first generates alt-random-write data, and then “cat’s” it. Requires a running Wayland session, *but*, this script is usually not called directly (see below). Touches $blddir/pgo-ok onsucces.. * full-current-session.sh: runs full-inner.sh. That is, it runs foot in the currently running Wayland session. Note that this will pop up a foot window. * full-headless-sway.sh: generates a custom Sway configuration that exec’s foot-headless-sway-inner.sh (see below), and then executes a headless Sway. In other words, this script does a *full* PGO build, but *without* requiring a running Wayland session. Requires Sway >= 1.6.2. * full-headless-sway.sh: runs full-inner.sh + “swaymsg exit”. To do a custom PGO build, without using pgo.sh, you’d need to: CFLAGS=”$CFLAGS -O3” meson --buildtype=release -Db_lto=true meson configure -Db_pgo=generate ninja ninja test (only needed if tllist+fcft are built as subprojects) Run *one* of: - partial.sh - full-current-session.sh - full-headless-sway.sh meson configure -D b_pgo=use ninja --- meson-pgo.sh | 154 -------------------------------- pgo/full-current-session.sh | 8 ++ pgo/full-headless-sway-inner.sh | 9 ++ pgo/full-headless-sway.sh | 24 +++++ pgo/full-inner.sh | 31 +++++++ pgo/options | 1 + pgo/partial.sh | 28 ++++++ pgo/pgo.sh | 101 +++++++++++++++++++++ 8 files changed, 202 insertions(+), 154 deletions(-) delete mode 100755 meson-pgo.sh create mode 100755 pgo/full-current-session.sh create mode 100755 pgo/full-headless-sway-inner.sh create mode 100755 pgo/full-headless-sway.sh create mode 100755 pgo/full-inner.sh create mode 100644 pgo/options create mode 100755 pgo/partial.sh create mode 100755 pgo/pgo.sh diff --git a/meson-pgo.sh b/meson-pgo.sh deleted file mode 100755 index cbd355f1..00000000 --- a/meson-pgo.sh +++ /dev/null @@ -1,154 +0,0 @@ -#!/bin/sh - -# Requirements: -# -# * all: build directory must not exist; it is created by the script -# * all: LC_CTYPE must be set to an UTF-8 locale -# * full*: must have at least one font installed -# * full-headless-sway: Sway 1.6.2 must be installed - - -set -e - -usage_and_die() { - echo "Usage: ${0} none|partial|full|full-headless-sway|[auto] " - exit 1 -} - -[ ${#} -ge 3 ] || usage_and_die - -mode=${1} -source_dir=$(realpath "${2}") -build_dir=$(realpath "${3}") -shift 3 - -# meson will complain if source dir is invalid - -if [ -d "${build_dir}" ]; then - echo "${build_dir}: build directory already exists" - exit 1 -fi - -compiler=other -do_pgo=no - -CFLAGS="${CFLAGS} -O3" - -case $(${CC-cc} --version) in - *GCC*) - compiler=gcc - do_pgo=yes - ;; - - *clang*) - compiler=clang - - if command -v llvm-profdata > /dev/null; then - do_pgo=yes - CFLAGS="${CFLAGS} -Wno-ignored-optimization-argument" - fi - ;; -esac - -case ${mode} in - partial|full|full-headless-sway) - ;; - - none) - do_pgo=no - ;; - - auto) - if command -v sway > /dev/null; then - mode=full-headless-sway - elif [ -n "${WAYLAND_DISPLAY+x}" ]; then - mode=full - else - mode=partial - fi - ;; - - *) - usage_and_die - ;; -esac - -# echo "source: ${source_dir}" -# echo "build: ${build_dir}" -# echo "compiler: ${compiler}" -# echo "mode: ${mode}" - -export CFLAGS -meson "${@}" "${build_dir}" - -if [ ${do_pgo} = yes ]; then - find . -name "*.gcda" -delete - meson configure "${build_dir}" -Db_pgo=generate - ninja -C "${build_dir}" - - # If fcft/tllist are subprojects, we need to ensure their tests - # have been executed, or we’ll get “profile count data file not - # found” errors. - ninja -C "${build_dir}" test - - script_options="--scroll --scroll-region --colors-regular --colors-bright --colors-256 --colors-rgb --attr-bold --attr-italic --attr-underline --sixel" - - tmp_file=$(mktemp) - pwd=$(pwd) - - cleanup() { - rm -f "${tmp_file}" - cd "${pwd}" - } - trap cleanup EXIT INT HUP TERM - - cd "${build_dir}" - case ${mode} in - full) - ./footclient --version - ./foot \ - --config=/dev/null \ - --term=xterm \ - sh -c "${source_dir}/scripts/generate-alt-random-writes.py ${script_options} ${tmp_file} && cat ${tmp_file}" - ;; - - full-headless-sway) - ./footclient --version - - runtime_dir=$(mktemp -d) - sway_conf=$(mktemp) - - echo "exec ${build_dir}/foot -o tweak.render-timer=log --config=/dev/null --term=xterm sh -c \"${source_dir}/scripts/generate-alt-random-writes.py ${script_options} ${tmp_file} && cat ${tmp_file}\" && swaymsg exit" > "${sway_conf}" - export XDG_RUNTIME_DIR=${runtime_dir} - export WLR_BACKENDS=headless - - sway -c "${sway_conf}" - - rm "${sway_conf}" - rm -rf "${runtime_dir}" - ;; - - partial) - ./footclient --version - ./foot --version - "${source_dir}"/scripts/generate-alt-random-writes.py \ - --rows=67 \ - --cols=135 \ - ${script_options} \ - "${tmp_file}" - ./pgo "${tmp_file}" - ;; - esac - - cd "${pwd}" - rm "${tmp_file}" - - if [ ${compiler} = clang ]; then - llvm-profdata \ - merge \ - "${build_dir}"/default_*.profraw \ - --output="${build_dir}"/default.profdata - fi - - meson configure "${build_dir}" -Db_pgo=use -fi diff --git a/pgo/full-current-session.sh b/pgo/full-current-session.sh new file mode 100755 index 00000000..3f62a6b5 --- /dev/null +++ b/pgo/full-current-session.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -eu + +srcdir=$(realpath "${1}") +blddir=$(realpath "${2}") + +"${srcdir}"/pgo/full-inner.sh "${srcdir}" "${blddir}" diff --git a/pgo/full-headless-sway-inner.sh b/pgo/full-headless-sway-inner.sh new file mode 100755 index 00000000..5bf20390 --- /dev/null +++ b/pgo/full-headless-sway-inner.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -u + +srcdir=$(realpath "${1}") +blddir=$(realpath "${2}") + +"${srcdir}"/pgo/full-inner.sh "${srcdir}" "${blddir}" +swaymsg exit diff --git a/pgo/full-headless-sway.sh b/pgo/full-headless-sway.sh new file mode 100755 index 00000000..ef34c560 --- /dev/null +++ b/pgo/full-headless-sway.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +set -eu + +srcdir=$(realpath "${1}") +blddir=$(realpath "${2}") + +runtime_dir=$(mktemp -d) +sway_conf=$(mktemp) + +cleanup() { + rm -f "${sway_conf}" + rm -rf "${runtime_dir}" +} +trap cleanup EXIT INT HUP TERM + +# Generate a custom config that executes our generate-pgo-data script +> "${sway_conf}" echo "exec '${srcdir}'/pgo/full-headless-sway-inner.sh '${srcdir}' '${blddir}'" + +# Run Sway. full-headless-sway-inner.sh ends with a ‘swaymsg exit’ +XDG_RUNTIME_DIR="${runtime_dir}" WLR_BACKENDS=headless sway -c "${sway_conf}" + +# Sway’s exit code doesn’t reflect our script’s exit code +[ -f "${blddir}"/pgo-ok ] || exit 1 diff --git a/pgo/full-inner.sh b/pgo/full-inner.sh new file mode 100755 index 00000000..14a3528c --- /dev/null +++ b/pgo/full-inner.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +set -eu + +srcdir=$(realpath "${1}") +blddir=$(realpath "${2}") + +. "${srcdir}"/pgo/options + +pgo_data=$(mktemp) +trap "rm -f ${pgo_data}" EXIT INT HUP TERM + +rm -f "${blddir}"/pgo-ok + +# To ensure profiling data is generated in the build directory +cd "${blddir}" + +LC_CTYPE=en_US.UTF-8 "${blddir}"/footclient --version +LC_CTYPE=en_US.UTF-8 "${blddir}"/foot \ + -o tweak.render-timer=log \ + --config=/dev/null \ + --term=xterm \ + sh -c " + set -eu + + '${srcdir}/scripts/generate-alt-random-writes.py' \ + ${script_options} \"${pgo_data}\" + + cat \"${pgo_data}\" + " +touch "${blddir}"/pgo-ok diff --git a/pgo/options b/pgo/options new file mode 100644 index 00000000..3fb821e9 --- /dev/null +++ b/pgo/options @@ -0,0 +1 @@ +script_options="--scroll --scroll-region --colors-regular --colors-bright --colors-256 --colors-rgb --attr-bold --attr-italic --attr-underline --sixel" diff --git a/pgo/partial.sh b/pgo/partial.sh new file mode 100755 index 00000000..9cb8bd59 --- /dev/null +++ b/pgo/partial.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +set -eu + +srcdir=$(realpath "${1}") +blddir=$(realpath "${2}") + +. "${srcdir}"/pgo/options + +pgo_data=$(mktemp) +trap "rm -f ${pgo_data}" EXIT INT HUP TERM + +rm -f "${blddir}"/pgo-ok + +"${srcdir}"/scripts/generate-alt-random-writes.py \ + --rows=67 \ + --cols=135 \ + ${script_options} \ + "${pgo_data}" + +# To ensure profiling data is generated in the build directory +cd "${blddir}" + +"${blddir}"/footclient --version +"${blddir}"/foot --version +"${blddir}"/pgo "${pgo_data}" + +touch "${blddir}"/pgo-ok diff --git a/pgo/pgo.sh b/pgo/pgo.sh new file mode 100755 index 00000000..fbd7fbe2 --- /dev/null +++ b/pgo/pgo.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +set -eu + +usage_and_die() { + echo "Usage: ${0} none|partial|full-current-session|full-headless-sway|[auto] [meson options]" + exit 1 +} + +[ ${#} -ge 3 ] || usage_and_die + +mode=${1} +srcdir=$(realpath "${2}") +blddir=$(realpath "${3}") +shift 3 + +if [ -e "${blddir}" ]; then + echo "error: ${blddir}: build directory already exists" + exit 1 +fi + +compiler=other +do_pgo=no + +CFLAGS="${CFLAGS-} -O3" + +case $(${CC-cc} --version) in + *GCC*) + compiler=gcc + do_pgo=yes + ;; + + *clang*) + compiler=clang + + if command -v llvm-profdata > /dev/null; then + do_pgo=yes + CFLAGS="${CFLAGS} -Wno-ignored-optimization-argument" + fi + ;; +esac + +case ${mode} in + partial|full-current-session|full-headless-sway) + ;; + + none) + do_pgo=no + ;; + + auto) + # TODO: once Sway 1.6.2 has been released, prefer + # full-headless-sway + + if [ -n "${WAYLAND_DISPLAY+x}" ]; then + mode=full-current-session + elif command -v sway > /dev/null; then + mode=full-headless-sway + else + mode=partial + fi + ;; + + *) + usage_and_die + ;; +esac + +# echo "source: ${srcdir}" +# echo "build: ${blddir}" +# echo "compiler: ${compiler}" +# echo "mode: ${mode}" +# echo "CFLAGS: ${CFLAGS}" + +export CFLAGS +meson "${@}" "${blddir}" "${srcdir}" --buildtype=release -Db_lto=true + +if [ ${do_pgo} = yes ]; then + find . -name "*.gcda" -delete + meson configure "${blddir}" -Db_pgo=generate + ninja -C "${blddir}" + + # If fcft/tllist are subprojects, we need to ensure their tests + # have been executed, or we’ll get “profile count data file not + # found” errors. + ninja -C "${blddir}" test + + # Run mode-dependent script to generate profiling data + "${srcdir}"/pgo/${mode}.sh "${srcdir}" "${blddir}" + + if [ ${compiler} = clang ]; then + llvm-profdata \ + merge \ + "${blddir}"/default_*.profraw \ + --output="${blddir}"/default.profdata + fi + + meson configure "${blddir}" -Db_pgo=use +fi + +ninja -C "${blddir}"