From ee19a77f46082b2eefd9ece7ca2222475f720169 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Mon, 20 Jan 2025 22:07:17 -0800 Subject: [PATCH] llvmPackages.bolt: add experimental bolt hook --- lib/systems/default.nix | 2 ++ pkgs/build-support/cc-wrapper/default.nix | 8 ++++++++ .../compilers/llvm/common/bolt/default.nix | 5 +++++ .../compilers/llvm/common/bolt/setup-hook.sh | 16 ++++++++++++++++ pkgs/stdenv/cross/default.nix | 3 +++ pkgs/top-level/release-attrpaths-superset.nix | 1 + pkgs/top-level/release.nix | 1 + pkgs/top-level/stage.nix | 14 ++++++++++++++ 8 files changed, 50 insertions(+) create mode 100644 pkgs/development/compilers/llvm/common/bolt/setup-hook.sh diff --git a/lib/systems/default.nix b/lib/systems/default.nix index ec0106a13dacf6..7dff3fd8c67d1c 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -93,6 +93,8 @@ let # Derived meta-data useLLVM = final.isFreeBSD || final.isOpenBSD; + useBolt = false; + libc = /**/ if final.isDarwin then "libSystem" else if final.isMinGW then "msvcrt" diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 8558a9f3d8d26e..3b24742d9a4fe7 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -728,6 +728,14 @@ stdenvNoCC.mkDerivation { substituteAll ${./add-clang-cc-cflags-before.sh} $out/nix-support/add-local-cc-cflags-before.sh '' + ### + ### Bolt support + ### Binaries need to be linked with relocations. + ### + + optionalString targetPlatform.useBolt '' + echo " --emit-relocs" >> $out/nix-support/cc-ldflags + '' + ## ## Extra custom steps ## diff --git a/pkgs/development/compilers/llvm/common/bolt/default.nix b/pkgs/development/compilers/llvm/common/bolt/default.nix index 9bc078df0e4449..a2054fbacdf5f3 100644 --- a/pkgs/development/compilers/llvm/common/bolt/default.nix +++ b/pkgs/development/compilers/llvm/common/bolt/default.nix @@ -71,6 +71,9 @@ stdenv.mkDerivation (finalAttrs: { postInstall = '' mkdir -p $dev/lib mv $out/lib/libLLVMBOLT*.a $dev/lib + + mkdir -p $out/nix-support + cp $setupHook $out/nix-support/setup-hook ''; outputs = [ @@ -78,6 +81,8 @@ stdenv.mkDerivation (finalAttrs: { "dev" ]; + setupHook = ./setup-hook.sh; + meta = llvm_meta // { homepage = "https://github.com/llvm/llvm-project/tree/main/bolt"; description = "LLVM post-link optimizer."; diff --git a/pkgs/development/compilers/llvm/common/bolt/setup-hook.sh b/pkgs/development/compilers/llvm/common/bolt/setup-hook.sh new file mode 100644 index 00000000000000..acee9c84a54d21 --- /dev/null +++ b/pkgs/development/compilers/llvm/common/bolt/setup-hook.sh @@ -0,0 +1,16 @@ +# shellcheck shell=bash + +function boltFixupPhase { + if [ -d "$prefix/bin" ]; then + for e in $(find "$prefix/bin" -executable -type f); do + if $(file "$e" | cut -f2 -d ':' | grep -q ELF); then + llvm-bolt "$e" -o $(dirname "$e")/.bolt-$(basename "$e") "${boltFlags[@]-}" + mv $(dirname "$e")/.bolt-$(basename "$e") "$e" + fi + done + fi +} + +if [ -z "${dontUseBolt-}" ]; then + appendToVar preFixupPhases boltFixupPhase +fi diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index 69ea14be5c83d0..eace479b806a81 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -69,6 +69,9 @@ lib.init bootStages extraNativeBuildInputs = old.extraNativeBuildInputs ++ lib.optionals (hostPlatform.isLinux && !buildPlatform.isLinux) [ buildPackages.patchelf ] + ++ lib.optionals hostPlatform.useBolt [ + buildPackages.llvmPackages.bolt + ] ++ lib.optional ( let f = diff --git a/pkgs/top-level/release-attrpaths-superset.nix b/pkgs/top-level/release-attrpaths-superset.nix index c306a64be585e5..e4ee9c6511b76c 100644 --- a/pkgs/top-level/release-attrpaths-superset.nix +++ b/pkgs/top-level/release-attrpaths-superset.nix @@ -51,6 +51,7 @@ let # cross packagesets pkgsLLVM = true; pkgsLLVMLibc = true; + pkgsBolt = true; pkgsMusl = true; pkgsStatic = true; pkgsCross = true; diff --git a/pkgs/top-level/release.nix b/pkgs/top-level/release.nix index 97e64f73c510db..a5c0a1b70cfc9a 100644 --- a/pkgs/top-level/release.nix +++ b/pkgs/top-level/release.nix @@ -345,6 +345,7 @@ let agdaPackages = packagePlatforms pkgs.agdaPackages; pkgsLLVM.stdenv = [ "x86_64-linux" "aarch64-linux" ]; + pkgsBolt.stdenv = [ "x86_64-linux" "aarch64-linux" ]; pkgsLLVMLibc.stdenv = [ "x86_64-linux" "aarch64-linux" ]; pkgsArocc.stdenv = [ "x86_64-linux" "aarch64-linux" ]; pkgsZig.stdenv = [ "x86_64-linux" "aarch64-linux" ]; diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 64bc2308f6da77..f1ee4df1b297d6 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -211,6 +211,20 @@ let }; }; + pkgsBolt = nixpkgsFun { + overlays = [ + (self': super': { + pkgsBolt = super'; + }) + ] ++ overlays; + # Bootstrap a cross stdenv and apply the Bolt post-link optimizer. + # This is currently not possible when compiling natively, + # so we don't need to check hostPlatform != buildPlatform. + crossSystem = stdenv.hostPlatform // { + useBolt = true; + }; + }; + pkgsLLVMLibc = nixpkgsFun { overlays = [ (self': super': { pkgsLLVMLibc = super';