Unverified Commit e288ae70 authored by sternenseemann's avatar sternenseemann Committed by GitHub
Browse files

haskell.compiler.ghc91{0,2}: provide LLVM compatible assembler (#440761)

parents 3e33e848 a2b66241
Loading
Loading
Loading
Loading
+23 −10
Original line number Diff line number Diff line
@@ -433,7 +433,10 @@ let
        }
        .${name};
    in
    "${tools}/bin/${tools.targetPrefix}${name}";
    getToolExe tools name;

  # targetPrefix aware lib.getExe'
  getToolExe = drv: name: lib.getExe' drv "${drv.targetPrefix or ""}${name}";

  # Use gold either following the default, or to avoid the BFD linker due to some bugs / perf issues.
  # But we cannot avoid BFD when using musl libc due to https://sourceware.org/bugzilla/show_bug.cgi?id=23856
@@ -530,8 +533,15 @@ stdenv.mkDerivation (
      export INSTALL_NAME_TOOL="${toolPath "install_name_tool" targetCC}"
    ''
    + lib.optionalString useLLVM ''
      export LLC="${lib.getBin buildTargetLlvmPackages.llvm}/bin/llc"
      export OPT="${lib.getBin buildTargetLlvmPackages.llvm}/bin/opt"
      export LLC="${getToolExe buildTargetLlvmPackages.llvm "llc"}"
      export OPT="${getToolExe buildTargetLlvmPackages.llvm "opt"}"
    ''
    # LLVMAS should be a "specific LLVM compatible assembler" which needs to understand
    # assembly produced by LLVM. The easiest way to be sure is to use clang from the same
    # version as llc and opt. Note that the naming chosen by GHC is misleading, clang can
    # be used as an assembler, llvm-as converts IR into machine code.
    + lib.optionalString (useLLVM && lib.versionAtLeast version "9.10") ''
      export LLVMAS="${getToolExe buildTargetLlvmPackages.clang "clang"}"
    ''
    + lib.optionalString (useLLVM && stdenv.targetPlatform.isDarwin) ''
      # LLVM backend on Darwin needs clang: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
@@ -541,11 +551,12 @@ stdenv.mkDerivation (
      # the assembly it is given, we need to make sure that it matches the LLVM version of $CC if possible.
      # It is unclear (at the time of writing 2024-09-01)  whether $CC should match the LLVM version we use
      # for llc and opt which would require using a custom darwin stdenv for targetCC.
      # 2025-09-06: The existence of LLVMAS suggests that matching $CC is fine (correct?) here.
      export CLANG="${
        if targetCC.isClang then
          toolPath "clang" targetCC
        else
          "${buildTargetLlvmPackages.clang}/bin/${buildTargetLlvmPackages.clang.targetPrefix}clang"
          getToolExe buildTargetLlvmPackages.clang "clang"
      }"
    ''
    + lib.optionalString (stdenv.buildPlatform.libc == "glibc") ''
@@ -826,17 +837,19 @@ stdenv.mkDerivation (
    ''
    + lib.optionalString useLLVM ''
      ghc-settings-edit "$settingsFile" \
        "LLVM llc command" "${lib.getBin llvmPackages.llvm}/bin/llc" \
        "LLVM opt command" "${lib.getBin llvmPackages.llvm}/bin/opt"
        "LLVM llc command" "${getToolExe llvmPackages.llvm "llc"}" \
        "LLVM opt command" "${getToolExe llvmPackages.llvm "opt"}"
    ''
    # See comment for LLVMAS in preConfigure
    + lib.optionalString (useLLVM && lib.versionAtLeast version "9.10") ''
      ghc-settings-edit "$settingsFile" \
        "LLVM llvm-as command" "${getToolExe llvmPackages.clang "clang"}"
    ''
    + lib.optionalString (useLLVM && stdenv.targetPlatform.isDarwin) ''
      ghc-settings-edit "$settingsFile" \
        "LLVM clang command" "${
          # See comment for CLANG in preConfigure
          if installCC.isClang then
            toolPath "clang" installCC
          else
            "${llvmPackages.clang}/bin/${llvmPackages.clang.targetPrefix}clang"
          if installCC.isClang then toolPath "clang" installCC else getToolExe llvmPackages.clang "clang"
        }"
    ''
    + lib.optionalString stdenv.targetPlatform.isWindows ''
+10 −10
Original line number Diff line number Diff line
@@ -225,7 +225,10 @@ let
        }
        .${name};
    in
    "${tools}/bin/${tools.targetPrefix}${name}";
    getToolExe tools name;

  # targetPrefix aware lib.getExe'
  getToolExe = drv: name: lib.getExe' drv "${drv.targetPrefix or ""}${name}";

  # Use gold either following the default, or to avoid the BFD linker due to some bugs / perf issues.
  # But we cannot avoid BFD when using musl libc due to https://sourceware.org/bugzilla/show_bug.cgi?id=23856
@@ -408,8 +411,8 @@ stdenv.mkDerivation (
      export INSTALL_NAME_TOOL="${toolPath "install_name_tool" targetCC}"
    ''
    + lib.optionalString useLLVM ''
      export LLC="${lib.getBin buildTargetLlvmPackages.llvm}/bin/llc"
      export OPT="${lib.getBin buildTargetLlvmPackages.llvm}/bin/opt"
      export LLC="${getToolExe buildTargetLlvmPackages.llvm "llc"}"
      export OPT="${getToolExe buildTargetLlvmPackages.llvm "opt"}"
    ''
    + lib.optionalString (useLLVM && stdenv.targetPlatform.isDarwin) ''
      # LLVM backend on Darwin needs clang: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
@@ -423,7 +426,7 @@ stdenv.mkDerivation (
        if targetCC.isClang then
          toolPath "clang" targetCC
        else
          "${buildTargetLlvmPackages.clang}/bin/${buildTargetLlvmPackages.clang.targetPrefix}clang"
          getToolExe buildTargetLlvmPackages.clang "clang"
      }"
    ''
    + ''
@@ -624,17 +627,14 @@ stdenv.mkDerivation (
    ''
    + lib.optionalString useLLVM ''
      ghc-settings-edit "$settingsFile" \
        "LLVM llc command" "${lib.getBin llvmPackages.llvm}/bin/llc" \
        "LLVM opt command" "${lib.getBin llvmPackages.llvm}/bin/opt"
        "LLVM llc command" "${getToolExe llvmPackages.llvm "llc"}" \
        "LLVM opt command" "${getToolExe llvmPackages.llvm "opt"}"
    ''
    + lib.optionalString (useLLVM && stdenv.targetPlatform.isDarwin) ''
      ghc-settings-edit "$settingsFile" \
        "LLVM clang command" "${
          # See comment for CLANG in preConfigure
          if installCC.isClang then
            toolPath "clang" installCC
          else
            "${llvmPackages.clang}/bin/${llvmPackages.clang.targetPrefix}clang"
          if installCC.isClang then toolPath "clang" installCC else getToolExe llvmPackages.clang "clang"
        }"
    ''
    + ''
+8 −1
Original line number Diff line number Diff line
@@ -734,6 +734,13 @@ package-set { inherit pkgs lib callPackage; } self
  */
  forceLlvmCodegenBackend = overrideCabal (drv: {
    configureFlags = drv.configureFlags or [ ] ++ [ "--ghc-option=-fllvm" ];
    buildTools = drv.buildTools or [ ] ++ [ self.ghc.llvmPackages.llvm ];
    buildTools =
      drv.buildTools or [ ]
      ++ [ self.ghc.llvmPackages.llvm ]
      # GHC >= 9.10 needs LLVM specific assembler, i.e. clang
      # On Darwin clang is always required
      ++ lib.optionals (lib.versionAtLeast self.ghc.version "9.10" || stdenv.hostPlatform.isDarwin) [
        self.ghc.llvmPackages.clang
      ];
  });
}
+6 −2
Original line number Diff line number Diff line
@@ -68,10 +68,14 @@ let
    )
  );
  hasLibraries = lib.any (x: x.isHaskellLibrary) paths;
  # CLang is needed on Darwin for -fllvm to work:
  # Clang is needed on Darwin for -fllvm to work.
  # GHC >= 9.10 needs an LLVM specific assembler which we use clang for.
  # https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
  llvm = lib.makeBinPath (
    [ ghc.llvmPackages.llvm ] ++ lib.optional stdenv.targetPlatform.isDarwin ghc.llvmPackages.clang
    [ ghc.llvmPackages.llvm ]
    ++ lib.optionals (lib.versionAtLeast ghc.version "9.10" || stdenv.targetPlatform.isDarwin) [
      ghc.llvmPackages.clang
    ]
  );
in