From 1bda5b199d3bf976e9367ea3c51d854f6e8bcbde Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 3 Sep 2025 03:42:44 +0100 Subject: [PATCH 1/2] =?UTF-8?q?haskell.compiler.ghc{924,963,984}Binary:=20?= =?UTF-8?q?remove=20LLVM=E2=80=90related=20dead=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These binary packages are available for a fixed set of platforms, all of which support the native code generator. Therefore, the `llvmPackages` argument was never used. We leave an assertion around, just in case. --- pkgs/development/compilers/ghc/9.2.4-binary.nix | 10 +++------- pkgs/development/compilers/ghc/9.6.3-binary.nix | 10 +++------- pkgs/development/compilers/ghc/9.8.4-binary.nix | 10 +++------- pkgs/top-level/haskell-packages.nix | 12 +++--------- 4 files changed, 12 insertions(+), 30 deletions(-) diff --git a/pkgs/development/compilers/ghc/9.2.4-binary.nix b/pkgs/development/compilers/ghc/9.2.4-binary.nix index 77986b76d64b..d867b7926684 100644 --- a/pkgs/development/compilers/ghc/9.2.4-binary.nix +++ b/pkgs/development/compilers/ghc/9.2.4-binary.nix @@ -10,7 +10,6 @@ libiconv, numactl, libffi, - llvmPackages, coreutils, targetPackages, @@ -193,8 +192,6 @@ let ) binDistUsed.archSpecificLibraries )).nixPackage; - useLLVM = !(import ./common-have-ncg.nix { inherit lib stdenv version; }); - libPath = lib.makeLibraryPath ( # Add arch-specific libraries. map ({ nixPackage, ... }: nixPackage) binDistUsed.archSpecificLibraries @@ -207,9 +204,6 @@ let targetPackages.stdenv.cc.bintools coreutils # for cat ] - ++ lib.optionals useLLVM [ - (lib.getBin llvmPackages.llvm) - ] # On darwin, we need unwrapped bintools as well (for otool) ++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [ targetPackages.stdenv.cc.bintools.bintools @@ -217,6 +211,8 @@ let in +assert import ./common-have-ncg.nix { inherit lib stdenv version; }; + stdenv.mkDerivation { inherit version; pname = "ghc-binary${binDistUsed.variantSuffix}"; @@ -470,7 +466,7 @@ stdenv.mkDerivation { targetPrefix = ""; enableShared = true; - inherit llvmPackages; + llvmPackages = null; # Our Cabal compiler name haskellCompilerName = "ghc-${version}"; diff --git a/pkgs/development/compilers/ghc/9.6.3-binary.nix b/pkgs/development/compilers/ghc/9.6.3-binary.nix index 72367c6b3d80..1557cb48a3df 100644 --- a/pkgs/development/compilers/ghc/9.6.3-binary.nix +++ b/pkgs/development/compilers/ghc/9.6.3-binary.nix @@ -10,7 +10,6 @@ libiconv, numactl, libffi, - llvmPackages, coreutils, targetPackages, @@ -192,8 +191,6 @@ let ) binDistUsed.archSpecificLibraries )).nixPackage; - useLLVM = !(import ./common-have-ncg.nix { inherit lib stdenv version; }); - libPath = lib.makeLibraryPath ( # Add arch-specific libraries. map ({ nixPackage, ... }: nixPackage) binDistUsed.archSpecificLibraries @@ -206,9 +203,6 @@ let targetPackages.stdenv.cc.bintools coreutils # for cat ] - ++ lib.optionals useLLVM [ - (lib.getBin llvmPackages.llvm) - ] # On darwin, we need unwrapped bintools as well (for otool) ++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [ targetPackages.stdenv.cc.bintools.bintools @@ -216,6 +210,8 @@ let in +assert import ./common-have-ncg.nix { inherit lib stdenv version; }; + stdenv.mkDerivation { inherit version; pname = "ghc-binary${binDistUsed.variantSuffix}"; @@ -449,7 +445,7 @@ stdenv.mkDerivation { targetPrefix = ""; enableShared = true; - inherit llvmPackages; + llvmPackages = null; # Our Cabal compiler name haskellCompilerName = "ghc-${version}"; diff --git a/pkgs/development/compilers/ghc/9.8.4-binary.nix b/pkgs/development/compilers/ghc/9.8.4-binary.nix index e8e1e5e4397a..b691715f8795 100644 --- a/pkgs/development/compilers/ghc/9.8.4-binary.nix +++ b/pkgs/development/compilers/ghc/9.8.4-binary.nix @@ -9,7 +9,6 @@ libiconv, numactl, libffi, - llvmPackages, coreutils, targetPackages, @@ -206,8 +205,6 @@ let ) binDistUsed.archSpecificLibraries )).nixPackage; - useLLVM = !(import ./common-have-ncg.nix { inherit lib stdenv version; }); - libPath = lib.makeLibraryPath ( # Add arch-specific libraries. map ({ nixPackage, ... }: nixPackage) binDistUsed.archSpecificLibraries @@ -220,9 +217,6 @@ let targetPackages.stdenv.cc.bintools coreutils # for cat ] - ++ lib.optionals useLLVM [ - (lib.getBin llvmPackages.llvm) - ] # On darwin, we need unwrapped bintools as well (for otool) ++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [ targetPackages.stdenv.cc.bintools.bintools @@ -230,6 +224,8 @@ let in +assert import ./common-have-ncg.nix { inherit lib stdenv version; }; + stdenv.mkDerivation { inherit version; pname = "ghc-binary${binDistUsed.variantSuffix}"; @@ -464,7 +460,7 @@ stdenv.mkDerivation { targetPrefix = ""; enableShared = true; - inherit llvmPackages; + llvmPackages = null; # Our Cabal compiler name haskellCompilerName = "ghc-${version}"; diff --git a/pkgs/top-level/haskell-packages.nix b/pkgs/top-level/haskell-packages.nix index c6920778ef86..ab8358c19a00 100644 --- a/pkgs/top-level/haskell-packages.nix +++ b/pkgs/top-level/haskell-packages.nix @@ -74,17 +74,11 @@ in llvmPackages = pkgs.llvmPackages_12; }; - ghc924Binary = callPackage ../development/compilers/ghc/9.2.4-binary.nix { - llvmPackages = pkgs.llvmPackages_12; - }; + ghc924Binary = callPackage ../development/compilers/ghc/9.2.4-binary.nix { }; - ghc963Binary = callPackage ../development/compilers/ghc/9.6.3-binary.nix { - llvmPackages = pkgs.llvmPackages_15; - }; + ghc963Binary = callPackage ../development/compilers/ghc/9.6.3-binary.nix { }; - ghc984Binary = callPackage ../development/compilers/ghc/9.8.4-binary.nix { - llvmPackages = pkgs.llvmPackages_15; - }; + ghc984Binary = callPackage ../development/compilers/ghc/9.8.4-binary.nix { }; ghc948 = callPackage ../development/compilers/ghc/9.4.8.nix { bootPkgs = From fb5a523d141f6406cd4d81962b1240a57fe71591 Mon Sep 17 00:00:00 2001 From: Emily Date: Sun, 10 Aug 2025 14:08:21 +0100 Subject: [PATCH 2/2] haskell.compiler.ghc902Binary: bump LLVM by wrapping `opt(1)` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement a wrapper script to translate the `opt(1)` arguments passed by the GHC 9.0.2 binary distribution to the equivalent arguments for the new LLVM pass manager passed by GHC ≥ 9.10 and our soon‐to‐be‐patched compilers. This ensures that the bootstrap of GHC 9.4 continues to work on AArch64. On an earlier version of this change, I built `haskell.compiler.ghc948` on both `aarch64-linux` and `aarch64-darwin`, and `haskell.compiler.ghc924` on `aarch64-linux` only (it is already broken on Darwin). I confirmed that we get functionally identical store outputs before and after this change, modulo self‐references: $ cp -a result-before/ before $ cp -a result-after/ after $ chmod -R +w before after $ LANG=C find before -type f -exec \ remove-references-to \ -t $(readlink result-before) \ -t $(readlink result-before-doc) \ '{}' ';' $ LANG=C find after -type f -exec \ remove-references-to \ -t $(readlink result-after) \ -t $(readlink result-after-doc) \ '{}' ';' # Darwin only: normalize build user UIDs in the archive files… $ LANG=C find before -name '*.a' -exec \ sed -i 's/ 360 / 351 /g' '{}' ';' $ diff -r before after # Linux only: the `package.cache` files differ, presumably due to # an unrelated reproducibility issue. Therefore, bumping this LLVM dependency did not affect the end result of the bootstrap for the only compilers it is used for. --- .../compilers/ghc/9.0.2-binary.nix | 15 ++++ pkgs/development/compilers/ghc/subopt.bash | 80 +++++++++++++++++++ pkgs/top-level/haskell-packages.nix | 3 +- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 pkgs/development/compilers/ghc/subopt.bash diff --git a/pkgs/development/compilers/ghc/9.0.2-binary.nix b/pkgs/development/compilers/ghc/9.0.2-binary.nix index 0b077dc8ae96..e99a7fe331c8 100644 --- a/pkgs/development/compilers/ghc/9.0.2-binary.nix +++ b/pkgs/development/compilers/ghc/9.0.2-binary.nix @@ -11,6 +11,7 @@ numactl, libffi, llvmPackages, + replaceVarsWith, coreutils, targetPackages, @@ -214,6 +215,20 @@ let coreutils # for cat ] ++ lib.optionals useLLVM [ + # Allow the use of newer LLVM versions; see the script for details. + (replaceVarsWith { + name = "subopt"; + src = ./subopt.bash; + dir = "bin"; + isExecutable = true; + preBuild = '' + name=opt + ''; + replacements = { + inherit (stdenv) shell; + opt = lib.getExe' llvmPackages.llvm "opt"; + }; + }) (lib.getBin llvmPackages.llvm) ] # On darwin, we need unwrapped bintools as well (for otool) diff --git a/pkgs/development/compilers/ghc/subopt.bash b/pkgs/development/compilers/ghc/subopt.bash new file mode 100644 index 000000000000..1f3d3a3ebdcc --- /dev/null +++ b/pkgs/development/compilers/ghc/subopt.bash @@ -0,0 +1,80 @@ +#!@shell@ + +# This script wraps the LLVM `opt(1)` executable and maps the options +# passed by old versions of GHC to the equivalents passed by newer +# versions that support recent versions of LLVM. +# +# It achieves the same effect as the following GHC change externally: +# . +# +# This is used solely for bootstrapping newer GHCs from the GHC 9.0.2 +# binary on AArch64, as that is the only architecture supported by that +# binary distribution that requires LLVM, and our later binary packages +# all use the native code generator for all supported platforms. +# +# No attempt is made to support custom LLVM optimization flags, or the +# undocumented flag to disable TBAA, or avoid +# , as these are not +# required to bootstrap GHC and at worst will produce an error message. +# +# It is called `subopt` to reflect the fact that it uses `opt(1)` as a +# subprocess, and the fact that the GHC build system situation +# requiring this hack is suboptimal. + +set -e + +expect() { + if [[ $1 != $2 ]]; then + printf >&2 'subopt: got %q; expected %q\n' "$1" "$2" + return 2 + fi +} + +if [[ $NIX_DEBUG -ge 1 ]]; then + printf >&2 'subopt: before:' + printf >&2 ' %q' "$@" + printf >&2 '\n' +fi + +args=() + +while [[ $# -gt 0 ]]; do + case "$1" in + -enable-new-pm=0) + shift 1 + ;; + -mem2reg) + expect "$2" -globalopt + expect "$3" -lower-expect + expect "$4" -enable-tbaa + expect "$5" -tbaa + args+=('-passes=function(require),function(mem2reg),globalopt,function(lower-expect)') + shift 5 + ;; + -O1) + expect "$2" -globalopt + expect "$3" -enable-tbaa + expect "$4" -tbaa + args+=('-passes=default') + shift 4 + ;; + -O2) + expect "$2" -enable-tbaa + expect "$3" -tbaa + args+=('-passes=default') + shift 3 + ;; + *) + args+=("$1") + shift 1 + ;; + esac +done + +if [[ $NIX_DEBUG -ge 1 ]]; then + printf >&2 'subopt: after:' + printf >&2 ' %q' "${args[@]}" + printf >&2 '\n' +fi + +exec @opt@ "${args[@]}" diff --git a/pkgs/top-level/haskell-packages.nix b/pkgs/top-level/haskell-packages.nix index ab8358c19a00..d9da08cfeb1b 100644 --- a/pkgs/top-level/haskell-packages.nix +++ b/pkgs/top-level/haskell-packages.nix @@ -70,8 +70,9 @@ in bb = pkgsBuildBuild.haskell; in { + # Required to bootstrap 9.4.8. ghc902Binary = callPackage ../development/compilers/ghc/9.0.2-binary.nix { - llvmPackages = pkgs.llvmPackages_12; + llvmPackages = pkgs.llvmPackages_20; }; ghc924Binary = callPackage ../development/compilers/ghc/9.2.4-binary.nix { };