[Git][ghc/ghc][wip/backports-9.4] 24 commits: configure: Set RELEASE=NO

Ben Gamari (@bgamari) gitlab at gitlab.haskell.org
Wed Aug 10 22:55:36 UTC 2022



Ben Gamari pushed to branch wip/backports-9.4 at Glasgow Haskell Compiler / GHC


Commits:
616c77fa by Ben Gamari at 2022-08-07T17:42:19-04:00
configure: Set RELEASE=NO

- - - - -
1270bfc3 by Ben Gamari at 2022-08-07T18:39:38-04:00
rts/linker: Resolve iconv_* on FreeBSD

FreeBSD's libiconv includes an implementation of the
iconv_* functions in libc. Unfortunately these can
only be resolved using dlvsym, which is how the RTS linker
usually resolves such functions. To fix this we include an ad-hoc
special case for iconv_*.

Fixes #20354.

(cherry picked from commit 844df61e8de5e2d9a058e6cbe388802755fc0305)
(cherry picked from commit d8961a2dc974b7f8f8752781c4aec261ae8f8c0f)

- - - - -
b40accc1 by Ben Gamari at 2022-08-07T20:09:24-04:00
users-guide: Fix typo in release notes

- - - - -
c6c9a939 by Ben Gamari at 2022-08-08T09:37:40-04:00
users-guide: Fix incorrect directives

- - - - -
4e21fb9d by Ben Gamari at 2022-08-09T12:29:51-04:00
relnotes: Reintroduce "included libraries" section

As requested in #21988.

- - - - -
47b4fea0 by Ben Gamari at 2022-08-09T12:31:10-04:00
make: Fix bootstrapping with profiling enabled

12ae2a9cf89af3ae9e4df051818b631cf213a1b8 attempted to work around a make
build system deficiency by adding some dependencies from modules of
`containers` which contain TH splices to the `template-haskell` package.
However, it only did this for the vanilla way. Here we add similar edges
for profiled objects.

Fixes #21987.

- - - - -
dbb74a20 by normalcoder at 2022-08-10T18:48:53-04:00
ncg/aarch64: Don't use x18 register on AArch64/Darwin

Apple's ABI documentation [1] says: "The platforms reserve register x18.
Don’t use this register." While this wasn't problematic in previous
Darwin releases, macOS 13 appears to start zeroing this register
periodically. See #21964.

[1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms

(cherry picked from commit 67575f2004340564d6e52af055ed6fb43d3f9711)

- - - - -
e6d3fe19 by Ben Gamari at 2022-08-10T18:52:33-04:00
hadrian: Don't use mk/config.mk.in

Ultimately we want to drop mk/config.mk so here I extract the bits
needed by the Hadrian bindist installation logic into a Hadrian-specific
file. While doing this I fixed binary distribution installation, #21901.

(cherry picked from commit afa584a327ce9aaf560c6ff09781c6e810c23a60)

- - - - -
ed9e9216 by Ben Gamari at 2022-08-10T18:52:40-04:00
hadrian: Fix naming of cross-compiler wrappers

(cherry picked from commit b9bb45d7368ceeb874ded7e55e603327c103ce9f)

- - - - -
0f587c14 by Ben Gamari at 2022-08-10T18:52:58-04:00
gitlab-ci: Add release job for aarch64/debian 11

(cherry picked from commit 5765e13370634979eb6a0d9f67aa9afa797bee46)

- - - - -
8bf86cc9 by Ben Gamari at 2022-08-10T18:53:02-04:00
gitlab-ci: Introduce validation job for aarch64 cross-compilation

Begins to address #11958.

(cherry picked from commit 5b26f32412d503c9004fc0a2e6e9a2ab680d43f3)

- - - - -
302505a3 by Ben Gamari at 2022-08-10T18:53:19-04:00
gitlab-ci: Add basic support for cross-compiler testiing

Here we add a simple qemu-based test for cross-compilers.

(cherry picked from commit ae707762335dabe2bb7e40639fd2ab2c7d3234fd)

- - - - -
342637e5 by Ben Gamari at 2022-08-10T18:53:27-04:00
gitlab-ci: Don't use coreutils on Darwin

In general we want to ensure that the tested environment is as similar
as possible to the environment the user will use. In the case of Darwin,
this means we want to use the system's BSD command-line utilities, not
coreutils.

This would have caught #21974.

(cherry picked from commit c1c08bd829fb33a185f0a71f08babe5d7e6556fc)

- - - - -
dcca4858 by Ben Gamari at 2022-08-10T18:53:31-04:00
hadrian: Fix bindist installation on Darwin

It turns out that `cp -P` on Darwin does not always copy a symlink as
a symlink. In order to get these semantics one must pass `-RP`. It's not
entirely clear whether this is valid under POSIX, but it is nevertheless
what Apple does.

(cherry picked from commit 1c582f44e41f534a8506a76618f6cffe5d71ed42)

- - - - -
a38a4ce4 by Ben Gamari at 2022-08-10T18:53:35-04:00
hadrian: Fix access mode of installed package registration files

Previously hadrian's bindist Makefile would modify package
registrations placed by `install` via a shell pipeline and `mv`.
However, the use of `mv` means that if umask is set then the user may
otherwise end up with package registrations which are inaccessible.
Fix this by ensuring that the mode is 0644.

(cherry picked from commit 681aa076259c05c626266cf516de7e7c5524eadb)

- - - - -
da22f74d by Ben Gamari at 2022-08-10T18:53:47-04:00
system-cxx-std-lib: Add support for FreeBSD libcxxrt

(cherry picked from commit 5d66a0ce39f47b7b9f6c732a18ac6e102a21ee6b)

- - - - -
3a31aaf5 by Ben Gamari at 2022-08-10T18:53:53-04:00
gitlab-ci: Bump to use freebsd13 runners

(cherry picked from commit ea90e61dc3c6ba0433e008284dc6c3970ead98a7)

- - - - -
3a41eaa0 by sheaf at 2022-08-10T18:54:04-04:00
Fix size_up_alloc to account for UnliftedDatatypes

The size_up_alloc function mistakenly considered any type that isn't
lifted to not allocate anything, which is wrong. What we want instead
is to check the type isn't boxed. This accounts for (BoxedRep Unlifted).

Fixes #21939

(cherry picked from commit d71a20514546e0befe6e238d0658cbaad5a13996)

- - - - -
87846991 by Douglas Wilson at 2022-08-10T18:54:11-04:00
testsuite: 21651 add test for closeFdWith + setNumCapabilities

This bug does not affect windows, which does not use the
base module GHC.Event.Thread.

(cherry picked from commit 76b52cf0c52ee05c20f7d1b80f5600eecab3c42a)

- - - - -
624f72e3 by Douglas Wilson at 2022-08-10T18:54:15-04:00
base: Fix races in IOManager (setNumCapabilities,closeFdWith)

Fix for #21651

Fixes three bugs:

- writes to eventManager should be atomic. It is accessed concurrently by ioManagerCapabilitiesChanged and closeFdWith.
- The race in closeFdWith described in the ticket.
- A race in getSystemEventManager where it accesses the 'IOArray' in
  'eventManager' before 'ioManagerCapabilitiesChanged' has written to
  'eventManager', causing an Array Index exception. The fix here is to
  'yield' and retry.

(cherry picked from commit 7589ee7241d46b393979d98d4ded17a15ee974fb)

- - - - -
f7762eb7 by Jens Petersen at 2022-08-10T18:54:28-04:00
hadrian RunRest: add type signature for stageNumber

avoids warning seen on 9.4.1:

src/Settings/Builders/RunTest.hs:264:53: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Integer’
        (Show a0)
          arising from a use of ‘show’
          at src/Settings/Builders/RunTest.hs:264:53-84
        (Num a0)
          arising from a use of ‘stageNumber’
          at src/Settings/Builders/RunTest.hs:264:59-83
    • In the second argument of ‘(++)’, namely
        ‘show (stageNumber (C.stage ctx))’
      In the second argument of ‘($)’, namely
        ‘"config.stage=" ++ show (stageNumber (C.stage ctx))’
      In the expression:
        arg $ "config.stage=" ++ show (stageNumber (C.stage ctx))
    |
264 |             , arg "-e", arg $ "config.stage="    ++ show (stageNumber (C.stage ctx))
    |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

compilation tested locally

(cherry picked from commit 823fe5b56450a7eefbf41ce8ece34095bf2217ee)

- - - - -
81977824 by Ben Gamari at 2022-08-10T18:54:34-04:00
gitlab-ci: Fix ARMv7 build

It appears that the CI refactoring carried out in
5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some
critical configuration: setting the build/host/target platforms and
forcing use of a non-broken linker.

(cherry picked from commit 5bc489cac104717f09be73f2b578719bcc1e3fcb)

- - - - -
5f259b8f by Ben Gamari at 2022-08-10T18:54:39-04:00
gitlab-ci: Run ARMv7 jobs when ~ARM label is used

(cherry picked from commit 596db9a5f966643bcc9994d45f2f6ffb4037ad74)

- - - - -
480b066d by Ben Gamari at 2022-08-10T18:54:43-04:00
hadrian: Don't attempt to install documentation if doc/ doesn't exist

Previously we would attempt to install documentation even if the `doc`
directory doesn't exist (e.g. due to `--docs=none`). This would result
in the surprising side-effect of the entire contents of the bindist
being installed in the destination documentation directory. Fix this.

Fixes #21976.

(cherry picked from commit 7cabea7c9b10d2d15a4798be9f3130994393dd9c)

- - - - -


23 changed files:

- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/darwin/toolchain.nix
- .gitlab/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/CodeGen.Platform.h
- compiler/GHC/Core/Unfold.hs
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/9.4.1-notes.rst
- ghc.mk
- hadrian/bindist/Makefile
- + hadrian/bindist/config.mk.in
- hadrian/src/Packages.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Settings/Builders/RunTest.hs
- libraries/base/GHC/Event/Thread.hs
- m4/fp_find_cxx_std_lib.m4
- + mk/install_script.sh
- rts/Linker.c
- + testsuite/tests/concurrent/should_run/T21651.hs
- + testsuite/tests/concurrent/should_run/T21651.stdout
- testsuite/tests/concurrent/should_run/all.T


Changes:

=====================================
.gitlab-ci.yml
=====================================
@@ -2,7 +2,7 @@ variables:
   GIT_SSL_NO_VERIFY: "1"
 
   # Commit of ghc/ci-images repository from which to pull Docker images
-  DOCKER_REV: 58d08589371e78829a3279c6f8b1241e155d7f70
+  DOCKER_REV: 9e4c540d9e4972a36291dfdf81f079f37d748890
 
   # Sequential version number of all cached things.
   # Bump to invalidate GitLab CI cache.


=====================================
.gitlab/ci.sh
=====================================
@@ -93,6 +93,7 @@ Environment variables determining build configuration of Hadrian system:
   BUILD_FLAVOUR     Which flavour to build.
   REINSTALL_GHC     Build and test a reinstalled "stage3" ghc built using cabal-install
                     This tests the "reinstall" configuration
+  CROSS_EMULATOR    The emulator to use for testing of cross-compilers.
 
 Environment variables determining bootstrap toolchain (Linux):
 
@@ -206,6 +207,9 @@ function set_toolchain_paths() {
       CABAL="$toolchain/bin/cabal$exe"
       HAPPY="$toolchain/bin/happy$exe"
       ALEX="$toolchain/bin/alex$exe"
+      if [ "$(uname)" = "FreeBSD" ]; then
+        GHC=/usr/local/bin/ghc
+      fi
       ;;
     nix)
       if [[ ! -f toolchain.sh ]]; then
@@ -287,7 +291,7 @@ function fetch_ghc() {
           cp -r ghc-${GHC_VERSION}*/* "$toolchain"
           ;;
         *)
-          pushd "ghc-${GHC_VERSION}*"
+          pushd ghc-${GHC_VERSION}*
           ./configure --prefix="$toolchain"
           "$MAKE" install
           popd
@@ -325,9 +329,7 @@ function fetch_cabal() {
           local base_url="https://downloads.haskell.org/~cabal/cabal-install-$v/"
           case "$(uname)" in
             Darwin) cabal_url="$base_url/cabal-install-$v-x86_64-apple-darwin17.7.0.tar.xz" ;;
-            FreeBSD)
-              #cabal_url="$base_url/cabal-install-$v-x86_64-portbld-freebsd.tar.xz" ;;
-              cabal_url="http://home.smart-cactus.org/~ben/ghc/cabal-install-3.0.0.0-x86_64-portbld-freebsd.tar.xz" ;;
+            FreeBSD) cabal_url="$base_url/cabal-install-$v-x86_64-freebsd13.tar.xz" ;;
             *) fail "don't know where to fetch cabal-install for $(uname)"
           esac
           echo "Fetching cabal-install from $cabal_url"
@@ -564,15 +566,38 @@ function make_install_destdir() {
   fi
   info "merging file tree from $destdir to $instdir"
   cp -a "$destdir/$instdir"/* "$instdir"/
-  "$instdir"/bin/ghc-pkg recache
+  "$instdir"/bin/${cross_prefix}ghc-pkg recache
 }
 
-function test_hadrian() {
-  if [ -n "${CROSS_TARGET:-}" ]; then
-    info "Can't test cross-compiled build."
-    return
-  fi
+# install the binary distribution in directory $1 to $2.
+function install_bindist() {
+  local bindist="$1"
+  local instdir="$2"
+  pushd "$bindist"
+  case "$(uname)" in
+    MSYS_*|MINGW*)
+      mkdir -p "$instdir"
+      cp -a * "$instdir"
+      ;;
+    *)
+      read -r -a args <<< "${INSTALL_CONFIGURE_ARGS:-}"
+
+      # FIXME: The bindist configure script shouldn't need to be reminded of
+      # the target platform. See #21970.
+      if [ -n "${CROSS_TARGET:-}" ]; then
+          args+=( "--target=$CROSS_TARGET" "--host=$CROSS_TARGET" )
+      fi
+
+      run ./configure \
+          --prefix="$instdir" \
+          "${args[@]+"${args[@]}"}"
+      make_install_destdir "$TOP"/destdir "$instdir"
+      ;;
+  esac
+  popd
+}
 
+function test_hadrian() {
   check_msys2_deps _build/stage1/bin/ghc --version
   check_release_build
 
@@ -593,7 +618,21 @@ function test_hadrian() {
   fi
 
 
-  if [[ -n "${REINSTALL_GHC:-}" ]]; then
+  if [ -n "${CROSS_TARGET:-}" ]; then
+    if [ -n "${CROSS_EMULATOR:-}" ]; then
+      local instdir="$TOP/_build/install"
+      local test_compiler="$instdir/bin/${cross_prefix}ghc$exe"
+      install_bindist _build/bindist/ghc-*/ "$instdir"
+      echo 'main = putStrLn "hello world"' > hello.hs
+      echo "hello world" > expected
+      run "$test_compiler" hello.hs
+      $CROSS_EMULATOR ./hello > actual
+      run diff expected actual
+    else
+      info "Cannot test cross-compiled build without CROSS_EMULATOR being set."
+      return
+    fi
+  elif [[ -n "${REINSTALL_GHC:-}" ]]; then
     run_hadrian \
       test \
       --test-root-dirs=testsuite/tests/stage1 \
@@ -602,20 +641,9 @@ function test_hadrian() {
       --test-root-dirs=testsuite/tests/typecheck \
       "runtest.opts+=${RUNTEST_ARGS:-}" || fail "hadrian cabal-install test"
   else
-    cd _build/bindist/ghc-*/
-    case "$(uname)" in
-      MSYS_*|MINGW*)
-        mkdir -p "$TOP"/_build/install
-        cp -a * "$TOP"/_build/install
-        ;;
-      *)
-        read -r -a args <<< "${INSTALL_CONFIGURE_ARGS:-}"
-        run ./configure --prefix="$TOP"/_build/install "${args[@]+"${args[@]}"}"
-        make_install_destdir "$TOP"/destdir "$TOP"/_build/install
-        ;;
-    esac
-    cd ../../../
-    test_compiler="$TOP/_build/install/bin/ghc$exe"
+    local instdir="$TOP/_build/install"
+    local test_compiler="$instdir/bin/ghc$exe"
+    install_bindist _build/bindist/ghc-*/ "$instdir"
 
     # Disabled, see #21072
     # run_hadrian \
@@ -776,6 +804,9 @@ esac
 if [ -n "${CROSS_TARGET:-}" ]; then
   info "Cross-compiling for $CROSS_TARGET..."
   target_triple="$CROSS_TARGET"
+  cross_prefix="$target_triple-"
+else
+  cross_prefix=""
 fi
 
 echo "Branch name ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-}"


=====================================
.gitlab/darwin/toolchain.nix
=====================================
@@ -85,7 +85,6 @@ pkgs.writeTextFile {
     export PATH
     PATH="${pkgs.autoconf}/bin:$PATH"
     PATH="${pkgs.automake}/bin:$PATH"
-    PATH="${pkgs.coreutils}/bin:$PATH"
     export FONTCONFIG_FILE=${fonts}
     export XELATEX="${ourtexlive}/bin/xelatex"
     export MAKEINDEX="${ourtexlive}/bin/makeindex"


=====================================
.gitlab/gen_ci.hs
=====================================
@@ -92,7 +92,7 @@ names of jobs to update these other places.
 data Opsys
   = Linux LinuxDistro
   | Darwin
-  | FreeBSD
+  | FreeBSD13
   | Windows deriving (Eq)
 
 data LinuxDistro
@@ -116,6 +116,8 @@ data BuildConfig
                 , llvmBootstrap  :: Bool
                 , withAssertions :: Bool
                 , withNuma       :: Bool
+                , crossTarget    :: Maybe String
+                , crossEmulator  :: Maybe String
                 , fullyStatic    :: Bool
                 , tablesNextToCode :: Bool
                 , threadSanitiser :: Bool
@@ -126,6 +128,7 @@ configureArgsStr :: BuildConfig -> String
 configureArgsStr bc = intercalate " " $
   ["--enable-unregisterised"| unregisterised bc ]
   ++ ["--disable-tables-next-to-code" | not (tablesNextToCode bc) ]
+  ++ ["--with-intree-gmp" | Just _ <- pure (crossTarget bc) ]
 
 -- Compute the hadrian flavour from the BuildConfig
 mkJobFlavour :: BuildConfig -> Flavour
@@ -156,6 +159,8 @@ vanilla = BuildConfig
   , llvmBootstrap  = False
   , withAssertions = False
   , withNuma = False
+  , crossTarget = Nothing
+  , crossEmulator = Nothing
   , fullyStatic = False
   , tablesNextToCode = True
   , threadSanitiser = False
@@ -186,6 +191,14 @@ static = vanilla { fullyStatic = True }
 staticNativeInt :: BuildConfig
 staticNativeInt = static { bignumBackend = Native }
 
+crossConfig :: String       -- ^ target triple
+            -> Maybe String -- ^ emulator for testing
+            -> BuildConfig
+crossConfig triple emulator =
+    vanilla { crossTarget = Just triple
+            , crossEmulator = emulator
+            }
+
 llvm :: BuildConfig
 llvm = vanilla { llvmBootstrap = True }
 
@@ -210,7 +223,7 @@ runnerTag arch (Linux distro) =
 runnerTag AArch64 Darwin = "aarch64-darwin"
 runnerTag Amd64 Darwin = "x86_64-darwin-m1"
 runnerTag Amd64 Windows = "new-x86_64-windows"
-runnerTag Amd64 FreeBSD = "x86_64-freebsd"
+runnerTag Amd64 FreeBSD13 = "x86_64-freebsd13"
 
 tags :: Arch -> Opsys -> BuildConfig -> [String]
 tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use
@@ -229,7 +242,7 @@ distroName Alpine     = "alpine3_12"
 opsysName :: Opsys -> String
 opsysName (Linux distro) = "linux-" ++ distroName distro
 opsysName Darwin = "darwin"
-opsysName FreeBSD = "freebsd"
+opsysName FreeBSD13 = "freebsd13"
 opsysName Windows = "windows"
 
 archName :: Arch -> String
@@ -252,6 +265,7 @@ testEnv arch opsys bc = intercalate "-" $
                         ++ ["unreg" | unregisterised bc ]
                         ++ ["numa"  | withNuma bc ]
                         ++ ["no_tntc"  | not (tablesNextToCode bc) ]
+                        ++ ["cross_"++triple  | Just triple <- pure $ crossTarget bc ]
                         ++ [flavourString (mkJobFlavour bc)]
 
 -- | The hadrian flavour string we are going to use for this build
@@ -299,7 +313,7 @@ type Variables = M.MonoidalMap String [String]
 a =: b = M.singleton a [b]
 
 opsysVariables :: Arch -> Opsys -> Variables
-opsysVariables _ FreeBSD = mconcat
+opsysVariables _ FreeBSD13 = mconcat
   [ -- N.B. we use iconv from ports as I see linker errors when we attempt
     -- to use the "native" iconv embedded in libc as suggested by the
     -- porting guide [1].
@@ -307,12 +321,19 @@ opsysVariables _ FreeBSD = mconcat
     "CONFIGURE_ARGS" =:  "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib"
   , "HADRIAN_ARGS" =: "--docs=no-sphinx"
   , "GHC_VERSION" =: "9.2.2"
-  , "CABAL_INSTALL_VERSION" =: "3.2.0.0"
+  , "CABAL_INSTALL_VERSION" =: "3.6.2.0"
   ]
 opsysVariables ARMv7 (Linux distro) =
   distroVariables distro <>
-  mconcat [ -- ld.gold is affected by #16177 and therefore cannot be used.
-            "CONFIGURE_ARGS" =: "LD=ld.lld"
+  mconcat [ "CONFIGURE_ARGS" =: "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf"
+            -- N.B. We disable ld.lld explicitly here because it appears to fail
+            -- non-deterministically on ARMv7. See #18280.
+          , "LD" =: "ld.gold"
+          , "GccUseLdOpt" =: "-fuse-ld=gold"
+            -- Awkwardly, this appears to be necessary to work around a
+            -- live-lock exhibited by the CPython (at least in 3.9 and 3.8)
+            -- interpreter on ARMv7
+          , "HADRIAN_ARGS" =: "--test-verbose=3"
           ]
 opsysVariables _ (Linux distro) = distroVariables distro
 opsysVariables AArch64 (Darwin {}) =
@@ -475,12 +496,13 @@ instance ToJSON OnOffRules where
 
 -- | A Rule corresponds to some condition which must be satisifed in order to
 -- run the job.
-data Rule = FastCI -- ^ Run this job when the fast-ci label is set
-          | ReleaseOnly -- ^ Only run this job in a release pipeline
-          | Nightly     -- ^ Only run this job in the nightly pipeline
-          | LLVMBackend -- ^ Only run this job when the "LLVM backend" label is present
-          | FreeBSDTag  -- ^ Only run this job when the "FreeBSD" label is set.
-          | Disable     -- ^ Don't run this job.
+data Rule = FastCI       -- ^ Run this job when the fast-ci label is set
+          | ReleaseOnly  -- ^ Only run this job in a release pipeline
+          | Nightly      -- ^ Only run this job in the nightly pipeline
+          | LLVMBackend  -- ^ Only run this job when the "LLVM backend" label is present
+          | FreeBSDLabel -- ^ Only run this job when the "FreeBSD" label is set.
+          | ARMLabel    -- ^ Only run this job when the "ARM" label is set.
+          | Disable      -- ^ Don't run this job.
           deriving (Bounded, Enum, Ord, Eq)
 
 -- A constant evaluating to True because gitlab doesn't support "true" in the
@@ -498,8 +520,10 @@ ruleString On FastCI = true
 ruleString Off FastCI = "$CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/"
 ruleString On LLVMBackend = "$CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/"
 ruleString Off LLVMBackend = true
-ruleString On FreeBSDTag = "$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/"
-ruleString Off FreeBSDTag = true
+ruleString On FreeBSDLabel = "$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/"
+ruleString Off FreeBSDLabel = true
+ruleString On ARMLabel = "$CI_MERGE_REQUEST_LABELS =~ /.*ARM.*/"
+ruleString Off ARMLabel = true
 ruleString On ReleaseOnly = "$RELEASE_JOB == \"yes\""
 ruleString Off ReleaseOnly = "$RELEASE_JOB != \"yes\""
 ruleString On Nightly = "$NIGHTLY"
@@ -597,7 +621,8 @@ job arch opsys buildConfig = (jobName, Job {..})
       , "BUILD_FLAVOUR" =: flavourString jobFlavour
       , "BIGNUM_BACKEND" =: bignumString (bignumBackend buildConfig)
       , "CONFIGURE_ARGS" =: configureArgsStr buildConfig
-
+      , maybe M.empty ("CROSS_TARGET" =:) (crossTarget buildConfig)
+      , maybe M.empty ("CROSS_EMULATOR" =:) (crossEmulator buildConfig)
       , if withNuma buildConfig then "ENABLE_NUMA" =: "1" else M.empty
       ]
 
@@ -766,13 +791,15 @@ jobs = M.fromList $ concatMap flattenJobGroup $
      , fastCI (standardBuilds Amd64 Windows)
      , disableValidate (standardBuildsWithConfig Amd64 Windows nativeInt)
      , standardBuilds Amd64 Darwin
-     , allowFailureGroup (addValidateRule FreeBSDTag (standardBuilds Amd64 FreeBSD))
+     , allowFailureGroup (addValidateRule FreeBSDLabel (standardBuilds Amd64 FreeBSD13))
      , standardBuilds AArch64 Darwin
      , standardBuilds AArch64 (Linux Debian10)
-     , allowFailureGroup (disableValidate (standardBuilds ARMv7 (Linux Debian10)))
+     , disableValidate (standardBuilds AArch64 (Linux Debian11))
+     , allowFailureGroup (addValidateRule ARMLabel (standardBuilds ARMv7 (Linux Debian10)))
      , standardBuilds I386 (Linux Debian9)
      , allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine) static)
      , disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine) staticNativeInt))
+     , validateBuilds Amd64 (Linux Debian11) (crossConfig "aarch64-linux-gnu" (Just "qemu-aarch64 -L /usr/aarch64-linux-gnu"))
      ]
 
   where


=====================================
.gitlab/jobs.yaml
=====================================
@@ -35,7 +35,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -97,7 +97,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -120,6 +120,64 @@
       "TEST_ENV": "aarch64-linux-deb10-validate"
     }
   },
+  "aarch64-linux-deb11-validate": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "2 weeks",
+      "paths": [
+        "ghc-aarch64-linux-deb11-validate.tar.xz",
+        "junit.xml"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "aarch64-linux-deb11-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb11:$DOCKER_REV",
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "sudo chown ghc:ghc -R .",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "aarch64-linux"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-aarch64-linux-deb11-validate",
+      "BUILD_FLAVOUR": "validate",
+      "CONFIGURE_ARGS": "",
+      "TEST_ENV": "aarch64-linux-deb11-validate"
+    }
+  },
   "armv7-linux-deb10-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -155,7 +213,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*ARM.*/) && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -174,7 +232,10 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-armv7-linux-deb10-validate",
       "BUILD_FLAVOUR": "validate",
-      "CONFIGURE_ARGS": "LD=ld.lld ",
+      "CONFIGURE_ARGS": "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf ",
+      "GccUseLdOpt": "-fuse-ld=gold",
+      "HADRIAN_ARGS": "--test-verbose=3",
+      "LD": "ld.gold",
       "TEST_ENV": "armv7-linux-deb10-validate"
     }
   },
@@ -213,7 +274,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -271,7 +332,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -334,7 +395,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -358,6 +419,65 @@
       "XZ_OPT": "-9"
     }
   },
+  "nightly-aarch64-linux-deb11-validate": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "8 weeks",
+      "paths": [
+        "ghc-aarch64-linux-deb11-validate.tar.xz",
+        "junit.xml"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "aarch64-linux-deb11-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb11:$DOCKER_REV",
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "sudo chown ghc:ghc -R .",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "aarch64-linux"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-aarch64-linux-deb11-validate",
+      "BUILD_FLAVOUR": "validate",
+      "CONFIGURE_ARGS": "",
+      "TEST_ENV": "aarch64-linux-deb11-validate",
+      "XZ_OPT": "-9"
+    }
+  },
   "nightly-armv7-linux-deb10-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -393,7 +513,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -412,7 +532,10 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-armv7-linux-deb10-validate",
       "BUILD_FLAVOUR": "validate",
-      "CONFIGURE_ARGS": "LD=ld.lld ",
+      "CONFIGURE_ARGS": "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf ",
+      "GccUseLdOpt": "-fuse-ld=gold",
+      "HADRIAN_ARGS": "--test-verbose=3",
+      "LD": "ld.gold",
       "TEST_ENV": "armv7-linux-deb10-validate",
       "XZ_OPT": "-9"
     }
@@ -452,7 +575,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -511,7 +634,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -541,7 +664,7 @@
       "ac_cv_func_utimensat": "no"
     }
   },
-  "nightly-x86_64-freebsd-validate": {
+  "nightly-x86_64-freebsd13-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh clean",
@@ -551,7 +674,7 @@
     "artifacts": {
       "expire_in": "8 weeks",
       "paths": [
-        "ghc-x86_64-freebsd-validate.tar.xz",
+        "ghc-x86_64-freebsd13-validate.tar.xz",
         "junit.xml"
       ],
       "reports": {
@@ -560,7 +683,7 @@
       "when": "always"
     },
     "cache": {
-      "key": "x86_64-freebsd-$CACHE_REV",
+      "key": "x86_64-freebsd13-$CACHE_REV",
       "paths": [
         "cabal-cache",
         "toolchain"
@@ -576,7 +699,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -588,17 +711,17 @@
     ],
     "stage": "full-build",
     "tags": [
-      "x86_64-freebsd"
+      "x86_64-freebsd13"
     ],
     "variables": {
       "BIGNUM_BACKEND": "gmp",
-      "BIN_DIST_NAME": "ghc-x86_64-freebsd-validate",
+      "BIN_DIST_NAME": "ghc-x86_64-freebsd13-validate",
       "BUILD_FLAVOUR": "validate",
-      "CABAL_INSTALL_VERSION": "3.2.0.0",
+      "CABAL_INSTALL_VERSION": "3.6.2.0",
       "CONFIGURE_ARGS": "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib ",
       "GHC_VERSION": "9.2.2",
       "HADRIAN_ARGS": "--docs=no-sphinx",
-      "TEST_ENV": "x86_64-freebsd-validate",
+      "TEST_ENV": "x86_64-freebsd13-validate",
       "XZ_OPT": "-9"
     }
   },
@@ -637,7 +760,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -699,7 +822,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -761,7 +884,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -821,7 +944,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -880,7 +1003,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -939,7 +1062,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -999,7 +1122,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1058,7 +1181,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1117,7 +1240,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1176,7 +1299,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1235,7 +1358,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1261,6 +1384,67 @@
       "XZ_OPT": "-9"
     }
   },
+  "nightly-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "8 weeks",
+      "paths": [
+        "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz",
+        "junit.xml"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "x86_64-linux-deb11-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV",
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "sudo chown ghc:ghc -R .",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "x86_64-linux"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate",
+      "BUILD_FLAVOUR": "validate",
+      "CONFIGURE_ARGS": "--with-intree-gmp",
+      "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu",
+      "CROSS_TARGET": "aarch64-linux-gnu",
+      "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate",
+      "XZ_OPT": "-9"
+    }
+  },
   "nightly-x86_64-linux-deb11-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -1296,7 +1480,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1355,7 +1539,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1414,7 +1598,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1475,7 +1659,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1537,7 +1721,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1598,7 +1782,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1653,7 +1837,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1712,7 +1896,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1775,7 +1959,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1839,7 +2023,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1864,6 +2048,66 @@
       "XZ_OPT": "-9"
     }
   },
+  "release-aarch64-linux-deb11-release": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "1 year",
+      "paths": [
+        "ghc-aarch64-linux-deb11-release.tar.xz",
+        "junit.xml"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "aarch64-linux-deb11-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb11:$DOCKER_REV",
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "sudo chown ghc:ghc -R .",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "aarch64-linux"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-aarch64-linux-deb11-release",
+      "BUILD_FLAVOUR": "release",
+      "CONFIGURE_ARGS": "",
+      "IGNORE_PERF_FAILURES": "all",
+      "TEST_ENV": "aarch64-linux-deb11-release",
+      "XZ_OPT": "-9"
+    }
+  },
   "release-armv7-linux-deb10-release": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -1899,7 +2143,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1918,8 +2162,11 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-armv7-linux-deb10-release",
       "BUILD_FLAVOUR": "release",
-      "CONFIGURE_ARGS": "LD=ld.lld ",
+      "CONFIGURE_ARGS": "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf ",
+      "GccUseLdOpt": "-fuse-ld=gold",
+      "HADRIAN_ARGS": "--test-verbose=3",
       "IGNORE_PERF_FAILURES": "all",
+      "LD": "ld.gold",
       "TEST_ENV": "armv7-linux-deb10-release",
       "XZ_OPT": "-9"
     }
@@ -1959,7 +2206,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2019,7 +2266,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2050,7 +2297,7 @@
       "ac_cv_func_utimensat": "no"
     }
   },
-  "release-x86_64-freebsd-release": {
+  "release-x86_64-freebsd13-release": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh clean",
@@ -2060,7 +2307,7 @@
     "artifacts": {
       "expire_in": "1 year",
       "paths": [
-        "ghc-x86_64-freebsd-release.tar.xz",
+        "ghc-x86_64-freebsd13-release.tar.xz",
         "junit.xml"
       ],
       "reports": {
@@ -2069,7 +2316,7 @@
       "when": "always"
     },
     "cache": {
-      "key": "x86_64-freebsd-$CACHE_REV",
+      "key": "x86_64-freebsd13-$CACHE_REV",
       "paths": [
         "cabal-cache",
         "toolchain"
@@ -2085,7 +2332,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2097,18 +2344,18 @@
     ],
     "stage": "full-build",
     "tags": [
-      "x86_64-freebsd"
+      "x86_64-freebsd13"
     ],
     "variables": {
       "BIGNUM_BACKEND": "gmp",
-      "BIN_DIST_NAME": "ghc-x86_64-freebsd-release",
+      "BIN_DIST_NAME": "ghc-x86_64-freebsd13-release",
       "BUILD_FLAVOUR": "release",
-      "CABAL_INSTALL_VERSION": "3.2.0.0",
+      "CABAL_INSTALL_VERSION": "3.6.2.0",
       "CONFIGURE_ARGS": "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib ",
       "GHC_VERSION": "9.2.2",
       "HADRIAN_ARGS": "--docs=no-sphinx",
       "IGNORE_PERF_FAILURES": "all",
-      "TEST_ENV": "x86_64-freebsd-release",
+      "TEST_ENV": "x86_64-freebsd13-release",
       "XZ_OPT": "-9"
     }
   },
@@ -2147,7 +2394,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2210,7 +2457,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2273,7 +2520,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2334,7 +2581,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2394,7 +2641,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2454,7 +2701,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2514,7 +2761,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2574,7 +2821,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2636,7 +2883,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2698,7 +2945,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2761,7 +3008,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2817,7 +3064,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2877,7 +3124,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2941,7 +3188,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2970,7 +3217,7 @@
       "ac_cv_func_utimensat": "no"
     }
   },
-  "x86_64-freebsd-validate": {
+  "x86_64-freebsd13-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh clean",
@@ -2980,7 +3227,7 @@
     "artifacts": {
       "expire_in": "2 weeks",
       "paths": [
-        "ghc-x86_64-freebsd-validate.tar.xz",
+        "ghc-x86_64-freebsd13-validate.tar.xz",
         "junit.xml"
       ],
       "reports": {
@@ -2989,7 +3236,7 @@
       "when": "always"
     },
     "cache": {
-      "key": "x86_64-freebsd-$CACHE_REV",
+      "key": "x86_64-freebsd13-$CACHE_REV",
       "paths": [
         "cabal-cache",
         "toolchain"
@@ -3005,7 +3252,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/) && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/) && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3017,17 +3264,17 @@
     ],
     "stage": "full-build",
     "tags": [
-      "x86_64-freebsd"
+      "x86_64-freebsd13"
     ],
     "variables": {
       "BIGNUM_BACKEND": "gmp",
-      "BIN_DIST_NAME": "ghc-x86_64-freebsd-validate",
+      "BIN_DIST_NAME": "ghc-x86_64-freebsd13-validate",
       "BUILD_FLAVOUR": "validate",
-      "CABAL_INSTALL_VERSION": "3.2.0.0",
+      "CABAL_INSTALL_VERSION": "3.6.2.0",
       "CONFIGURE_ARGS": "--with-gmp-includes=/usr/local/include --with-gmp-libraries=/usr/local/lib --with-iconv-includes=/usr/local/include --with-iconv-libraries=/usr/local/lib ",
       "GHC_VERSION": "9.2.2",
       "HADRIAN_ARGS": "--docs=no-sphinx",
-      "TEST_ENV": "x86_64-freebsd-validate"
+      "TEST_ENV": "x86_64-freebsd13-validate"
     }
   },
   "x86_64-linux-alpine3_12-int_native-validate+fully_static": {
@@ -3065,7 +3312,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3126,7 +3373,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3187,7 +3434,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3246,7 +3493,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3305,7 +3552,7 @@
     "rules": [
       {
         "allow_failure": true,
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "manual"
       }
     ],
@@ -3363,7 +3610,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3422,7 +3669,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3480,7 +3727,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3538,7 +3785,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3596,7 +3843,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && ($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/) && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && ($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3655,7 +3902,7 @@
     "rules": [
       {
         "allow_failure": true,
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "manual"
       }
     ],
@@ -3680,6 +3927,66 @@
       "TSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.tsan-suppressions"
     }
   },
+  "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "2 weeks",
+      "paths": [
+        "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate.tar.xz",
+        "junit.xml"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "x86_64-linux-deb11-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb11:$DOCKER_REV",
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "sudo chown ghc:ghc -R .",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "x86_64-linux"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-deb11-cross_aarch64-linux-gnu-validate",
+      "BUILD_FLAVOUR": "validate",
+      "CONFIGURE_ARGS": "--with-intree-gmp",
+      "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu",
+      "CROSS_TARGET": "aarch64-linux-gnu",
+      "TEST_ENV": "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate"
+    }
+  },
   "x86_64-linux-deb11-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -3715,7 +4022,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3773,7 +4080,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3831,7 +4138,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3891,7 +4198,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3952,7 +4259,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4012,7 +4319,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4066,7 +4373,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4124,7 +4431,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],


=====================================
compiler/CodeGen.Platform.h
=====================================
@@ -926,6 +926,14 @@ freeReg 29 = False
 -- ip0 -- used for spill offset computations
 freeReg 16 = False
 
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
+-- x18 is reserved by the platform on Darwin/iOS, and can not be used
+-- More about ARM64 ABI that Apple platforms support:
+-- https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
+-- https://github.com/Siguza/ios-resources/blob/master/bits/arm64.md
+freeReg 18 = False
+#endif
+
 # if defined(REG_Base)
 freeReg REG_Base  = False
 # endif


=====================================
compiler/GHC/Core/Unfold.hs
=====================================
@@ -580,10 +580,9 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr
     ------------
     -- Cost to allocate binding with given binder
     size_up_alloc bndr
-      |  isTyVar bndr                 -- Doesn't exist at runtime
-      || isJoinId bndr                -- Not allocated at all
-      || isUnliftedType (idType bndr) -- Doesn't live in heap
-           -- OK to call isUnliftedType: binders have a fixed RuntimeRep (search for FRRBinder)
+      |  isTyVar bndr                    -- Doesn't exist at runtime
+      || isJoinId bndr                   -- Not allocated at all
+      || not (isBoxedType (idType bndr)) -- Doesn't live in heap
       = 0
       | otherwise
       = 10


=====================================
configure.ac
=====================================
@@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.4.1], [glasgow-has
 AC_CONFIG_MACRO_DIRS([m4])
 
 # Set this to YES for a released version, otherwise NO
-: ${RELEASE=YES}
+: ${RELEASE=NO}
 
 # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line
 # above.  If this is not a released version, then we will append the


=====================================
distrib/configure.ac.in
=====================================
@@ -256,7 +256,7 @@ AC_SUBST(UseLibdw)
 FP_SETTINGS
 
 #
-AC_CONFIG_FILES(mk/config.mk mk/install.mk)
+AC_CONFIG_FILES(config.mk mk/config.mk mk/install.mk)
 AC_OUTPUT
 
 # We get caught by


=====================================
docs/users_guide/9.4.1-notes.rst
=====================================
@@ -31,7 +31,7 @@ upgrading to GHC 9.4:
   and are deprecated, having been superceded by the now levity-polymorphic
   ``Array#`` type.
 
-- The type equality operator, ``(~)``, is not considered to be a type operator
+- The type equality operator, ``(~)``, is now considered to be a type operator
   (exported from ``Prelude``) and therefore requires the enabling of the
   :extension:`TypeOperators` extension rather than :extension:`GADTs` or
   :extension:`TypeFamilies` as was sufficient previously.
@@ -62,7 +62,7 @@ Language
 - GHC Proposal `#511
   <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0511-deep-subsumption.rst>`_
   has been implemented, introducing a new language extension,
-  :lang-ext:`DeepSubsumption`. This extension allows the user
+  :extension:`DeepSubsumption`. This extension allows the user
   to opt-in to the deep type subsumption-checking behavior implemented by GHC
   8.10 and earlier.
 
@@ -283,7 +283,7 @@ Runtime system
 ~~~~~~~~~~~~~~~~
 
 - ``GHC.Generics`` now provides a set of newtypes, ``Generically`` and
-  ``Generically1``, for deriving generic instances via :lang-ext:`DerivingVia`.
+  ``Generically1``, for deriving generic instances via :extension:`DerivingVia`.
   ``Generically`` instances include ``Semigroup`` and ``Monoid``.
 
 - There's a new special function ``withDict`` in ``GHC.Exts``: ::
@@ -513,3 +513,50 @@ Runtime system
 - The ``link`` field of ``GHC.Exts.Heap.WeakClosure`` has been replaced with a
   ``weakLink`` field which is ``Nothing`` if and only if ``link`` would have
   been NULL.
+
+
+Included libraries
+------------------
+
+The package database provided with this distribution also contains a number of
+packages other than GHC itself. See the changelogs provided with these packages
+for further change information.
+
+.. ghc-package-list::
+
+    libraries/array/array.cabal:             Dependency of ``ghc`` library
+    libraries/base/base.cabal:               Core library
+    libraries/binary/binary.cabal:           Dependency of ``ghc`` library
+    libraries/bytestring/bytestring.cabal:   Dependency of ``ghc`` library
+    libraries/Cabal/Cabal/Cabal.cabal:       Dependency of ``ghc-pkg`` utility
+    libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal:  Dependency of ``ghc-pkg`` utility
+    libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library
+    libraries/deepseq/deepseq.cabal:         Dependency of ``ghc`` library
+    libraries/directory/directory.cabal:     Dependency of ``ghc`` library
+    libraries/exceptions/exceptions.cabal:   Dependency of ``ghc`` and ``haskeline`` library
+    libraries/filepath/filepath.cabal:       Dependency of ``ghc`` library
+    compiler/ghc.cabal:                      The compiler itself
+    libraries/ghci/ghci.cabal:               The REPL interface
+    libraries/ghc-boot/ghc-boot.cabal:       Internal compiler library
+    libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library
+    libraries/ghc-compact/ghc-compact.cabal: Core library
+    libraries/ghc-heap/ghc-heap.cabal:       GHC heap-walking library
+    libraries/ghc-prim/ghc-prim.cabal:       Core library
+    libraries/haskeline/haskeline.cabal:     Dependency of ``ghci`` executable
+    libraries/hpc/hpc.cabal:                 Dependency of ``hpc`` executable
+    libraries/integer-gmp/integer-gmp.cabal: Core library
+    libraries/libiserv/libiserv.cabal:       Internal compiler library
+    libraries/mtl/mtl.cabal:                 Dependency of ``Cabal`` library
+    libraries/parsec/parsec.cabal:           Dependency of ``Cabal`` library
+    libraries/pretty/pretty.cabal:           Dependency of ``ghc`` library
+    libraries/process/process.cabal:         Dependency of ``ghc`` library
+    libraries/stm/stm.cabal:                 Dependency of ``haskeline`` library
+    libraries/template-haskell/template-haskell.cabal: Core library
+    libraries/terminfo/terminfo.cabal:       Dependency of ``haskeline`` library
+    libraries/text/text.cabal:               Dependency of ``Cabal`` library
+    libraries/time/time.cabal:               Dependency of ``ghc`` library
+    libraries/transformers/transformers.cabal: Dependency of ``ghc`` library
+    libraries/unix/unix.cabal:               Dependency of ``ghc`` library
+    libraries/Win32/Win32.cabal:             Dependency of ``ghc`` library
+    libraries/xhtml/xhtml.cabal:             Dependency of ``haddock`` executable
+


=====================================
ghc.mk
=====================================
@@ -510,6 +510,11 @@ libraries/containers/containers/dist-install/build/Data/Graph.o: libraries/templ
 libraries/containers/containers/dist-install/build/Data/Set/Internal.o: libraries/template-haskell/dist-install/build/Language/Haskell/TH/Lib/Internal.hi
 libraries/containers/containers/dist-install/build/Data/IntSet/Internal.o: libraries/template-haskell/dist-install/build/Language/Haskell/TH/Lib/Internal.hi
 
+libraries/containers/containers/dist-install/build/Data/IntMap/Internal.p_o: libraries/template-haskell/dist-install/build/Language/Haskell/TH/Lib/Internal.p_hi
+libraries/containers/containers/dist-install/build/Data/Graph.p_o: libraries/template-haskell/dist-install/build/Language/Haskell/TH/Lib/Internal.p_hi
+libraries/containers/containers/dist-install/build/Data/Set/Internal.p_o: libraries/template-haskell/dist-install/build/Language/Haskell/TH/Lib/Internal.p_hi
+libraries/containers/containers/dist-install/build/Data/IntSet/Internal.p_o: libraries/template-haskell/dist-install/build/Language/Haskell/TH/Lib/Internal.p_hi
+
 ifeq "$(BIGNUM_BACKEND)" "gmp"
 GMP_ENABLED = YES
 libraries/ghc-bignum_CONFIGURE_OPTS += --configure-option="--with-gmp"


=====================================
hadrian/bindist/Makefile
=====================================
@@ -1,7 +1,8 @@
 MAKEFLAGS += --no-builtin-rules
 .SUFFIXES:
 
-include mk/config.mk
+include ./mk/project.mk
+include ./config.mk
 
 .PHONY: default
 default:
@@ -22,43 +23,6 @@ ifeq "$(Darwin_Host)" "YES"
 XATTR ?= /usr/bin/xattr
 endif
 
-# installscript
-#
-# $1 = package name
-# $2 = wrapper path
-# $3 = bindir
-# $4 = ghcbindir
-# $5 = Executable binary path
-# $6 = Library Directory
-# $7 = Docs Directory
-# $8 = Includes Directory
-# We are installing wrappers to programs by searching corresponding
-# wrappers. If wrapper is not found, we are attaching the common wrapper
-# to it. This implementation is a bit hacky and depends on consistency
-# of program names. For hadrian build this will work as programs have a
-# consistent naming procedure.
-define installscript
-	echo "installscript $1 -> $2"
-	@if [ -L 'wrappers/$1' ]; then                \
-		$(CP) -P 'wrappers/$1' '$2' ;             \
-	else								          \
-		rm -f '$2' && 		                      \
-		$(CREATE_SCRIPT) '$2' &&                  \
-		echo "#!$(SHELL)" >>  '$2'  &&            \
-		echo "exedir=\"$4\"" >> '$2'  &&          \
-		echo "exeprog=\"$1\"" >> '$2'  &&         \
-		echo "executablename=\"$5\"" >> '$2'  &&  \
-		echo "bindir=\"$3\"" >> '$2'  &&          \
-		echo "libdir=\"$6\"" >> '$2'  &&          \
-		echo "docdir=\"$7\"" >> '$2'  &&          \
-		echo "includedir=\"$8\"" >> '$2'  &&      \
-		echo "" >> '$2'  &&                       \
-		cat 'wrappers/$1' >> '$2'  &&             \
-		$(EXECUTABLE_FILE) '$2' ;                 \
-	fi
-	@echo "$1 installed to $2"
-endef
-
 # patchpackageconf
 #
 # Hacky function to patch up the 'haddock-interfaces' and 'haddock-html'
@@ -82,6 +46,8 @@ define patchpackageconf \
 	((echo "$1" | grep rts) && (cat '$2.copy' | sed 's|haddock-.*||' > '$2.copy.copy')) || (cat '$2.copy' > '$2.copy.copy')
 	# We finally replace the original file.
 	mv '$2.copy.copy' '$2'
+	# Fix the mode, in case umask is set
+	chmod 644 '$2'
 endef
 
 # QUESTION : should we use shell commands?
@@ -216,10 +182,12 @@ install_lib: lib/settings
 install_docs:
 	@echo "Copying docs to $(DESTDIR)$(docdir)"
 	$(INSTALL_DIR) "$(DESTDIR)$(docdir)"
-	cd doc; $(FIND) . -type f -exec sh -c \
-			'$(INSTALL_DIR) "$(DESTDIR)$(docdir)/`dirname $$1`" && \
-			 $(INSTALL_DATA) "$$1" "$(DESTDIR)$(docdir)/`dirname $$1`" \
-		' sh '{}' \;
+	
+	if [ -d doc ]; then \
+		cd doc; $(FIND) . -type f -exec sh -c \
+			'$(INSTALL_DIR) "$(DESTDIR)$(docdir)/`dirname $$1`" && $(INSTALL_DATA) "$$1" "$(DESTDIR)$(docdir)/`dirname $$1`"' \
+			sh '{}' ';'; \
+	fi
 	
 	if [ -d docs-utils ]; then \
 		$(INSTALL_DIR) "$(DESTDIR)$(docdir)/html/libraries/"; \
@@ -227,12 +195,13 @@ install_docs:
 		$(INSTALL_SCRIPT) docs-utils/gen_contents_index "$(DESTDIR)$(docdir)/html/libraries/"; \
 	fi
 
-BINARY_NAMES=$(shell ls ./wrappers/)
+export SHELL
 install_wrappers: install_bin_libdir
 	@echo "Installing wrapper scripts"
 	$(INSTALL_DIR) "$(DESTDIR)$(WrapperBinsDir)"
-	$(foreach p, $(BINARY_NAMES),\
-		$(call installscript,$p,$(DESTDIR)$(WrapperBinsDir)/$p,$(WrapperBinsDir),$(ActualBinsDir),$(ActualBinsDir)/$p,$(ActualLibsDir),$(docdir),$(includedir)))
+	for p in `cd wrappers; $(FIND) . ! -type d`; do \
+	    mk/install_script.sh "$$p" "$(DESTDIR)/$(WrapperBinsDir)/$$p" "$(WrapperBinsDir)" "$(ActualBinsDir)" "$(ActualBinsDir)/$$p" "$(ActualLibsDir)" "$(docdir)" "$(includedir)"; \
+	done
 
 PKG_CONFS = $(shell find "$(DESTDIR)$(ActualLibsDir)/package.conf.d" -name '*.conf' | sed "s:   :\0xxx\0:g")
 update_package_db: install_bin install_lib


=====================================
hadrian/bindist/config.mk.in
=====================================
@@ -0,0 +1,281 @@
+#-----------------------------------------------------------------------------
+#
+# Definition of installation directories, we don't use half of these, but since
+# the configure script has them on offer while passing through, we might as well
+# set them. Note that we have to be careful, because the GNU coding standards
+# have changed a bit over the course of time, and autoconf development reflects
+# this.
+#
+# A little bit of history regarding autoconf and GNU coding standards, use this
+# as a cheat-sheet for the stuff below:
+#
+# variable    | default < 2.60     | default >= 2.60
+# ------------+--------------------+--------------------------------------
+# exec_prefix | ${prefix}          | ${prefix}
+# libdir      | ${exec_prefix}/lib | ${exec_prefix}/lib
+# datarootdir | NONE!              | ${prefix}/share
+# datadir     | ${prefix}/share    | ${datarootdir}
+# infodir     | ${prefix}/info     | ${datarootdir}/info
+# mandir      | ${prefix}/man      | ${datarootdir}/man
+# docdir      | NONE!              | ${datarootdir}/doc/${PACKAGE_TARNAME}
+# htmldir     | NONE!              | ${docdir}
+# dvidir      | NONE!              | ${docdir}
+# pdfdir      | NONE!              | ${docdir}
+# psdir       | NONE!              | ${docdir}
+#
+# NOTE: The default e.g. ${docdir} above means that autoconf substitutes the
+# string "${docdir}", not the value of docdir! This is crucial for the GNU
+# coding standards. See #1924.
+
+define set_default
+# $1 = variable to set
+# $2 = default value to use, if configure didn't expand it
+# If $1 starts with an @ then configure didn't set it (because a version
+# of autoconf that is too old was used), so set it to a sensible value
+ifneq "$$(filter @%,$$($1))" ""
+$1 = $2
+endif
+endef
+
+prefix          = @prefix@
+
+datarootdir     = @datarootdir@
+$(eval $(call set_default,datarootdir,$${prefix}/share))
+
+exec_prefix     = @exec_prefix@
+bindir          = @bindir@
+datadir         = @datadir@
+libdir          = @libdir@
+includedir      = @includedir@
+mandir          = @mandir@
+
+# Note that `./configure --docdir=/foo/bar` should work.
+docdir = @docdir@
+PACKAGE_TARNAME = ghc-${ProjectVersion}
+$(eval $(call set_default,docdir,$${datarootdir}/doc/$${PACKAGE_TARNAME}))
+
+htmldir = @htmldir@
+dvidir  = @dvidir@
+pdfdir  = @pdfdir@
+psdir   = @psdir@
+$(eval $(call set_default,htmldir,$${docdir}))
+$(eval $(call set_default,dvidir,$${docdir}))
+$(eval $(call set_default,pdfdir,$${docdir}))
+$(eval $(call set_default,psdir,$${docdir}))
+
+ifeq "$(RelocatableBuild)" "YES"
+
+# Hack: our directory layouts tend to be different on Windows, so
+# hack around configure's bogus assumptions here.
+datarootdir = $(prefix)
+datadir     = $(prefix)/lib
+libdir      = $(prefix)/lib
+
+docdir    = $(prefix)/doc
+htmldir   = $(docdir)
+dvidir    = $(docdir)
+pdfdir    = $(docdir)
+psdir     = $(docdir)
+
+ghclibdir = $(libdir)
+
+else
+
+# Unix: override libdir and datadir to put ghc-specific stuff in
+# a subdirectory with the version number included.
+ghclibdir     = $(libdir)/$(CrossCompilePrefix)ghc-$(ProjectVersion)
+endif
+
+ghclibexecdir = $(ghclibdir)
+topdir        = $(ghclibdir)
+ghcheaderdir  = $(ghclibdir)/rts/include
+
+#-----------------------------------------------------------------------------
+# Utilities needed by the installation Makefile
+
+FIND            = @FindCmd@
+INSTALL         = @INSTALL@
+INSTALL        := $(subst .././install-sh,$(TOP)/install-sh,$(INSTALL))
+LN_S            = @LN_S@
+MV              = mv
+SED             = @SedCmd@
+SHELL           = @SHELL@
+RANLIB_CMD      = @RanlibCmd@
+STRIP_CMD       = @StripCmd@
+
+#
+# Invocations of `install' for different classes
+# of targets:
+#
+INSTALL_PROGRAM = $(INSTALL) -m 755
+INSTALL_SCRIPT  = $(INSTALL) -m 755
+INSTALL_SHLIB   = $(INSTALL) -m 755
+INSTALL_DATA    = $(INSTALL) -m 644
+INSTALL_HEADER  = $(INSTALL) -m 644
+INSTALL_MAN     = $(INSTALL) -m 644
+INSTALL_DOC     = $(INSTALL) -m 644
+INSTALL_DIR     = $(INSTALL) -m 755 -d
+
+#-----------------------------------------------------------------------------
+# Build configuration
+
+CrossCompiling        = @CrossCompiling@
+CrossCompilePrefix    = @CrossCompilePrefix@
+GhcUnregisterised     = @Unregisterised@
+
+# ArchSupportsSMP should be set iff there is support for that arch in
+# rts/include/stg/SMP.h
+ifeq "$(TargetArch_CPP)" "arm"
+# We don't support load/store barriers pre-ARMv7. See #10433.
+ArchSupportsSMP=$(if $(filter $(ARM_ISA),ARMv5 ARMv6),NO,YES)
+else
+ArchSupportsSMP=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 sparc powerpc powerpc64 powerpc64le s390x aarch64 riscv64)))
+endif
+
+# The THREADED_RTS requires `BaseReg` to be in a register and the
+# `GhcUnregisterised` mode doesn't allow that.
+GhcWithSMP := $(strip $(if $(filter YESNO, $(ArchSupportsSMP)$(GhcUnregisterised)),YES,NO))
+
+# Whether to include GHCi in the compiler.  Depends on whether the RTS linker
+# has support for this OS/ARCH combination.
+OsSupportsGHCi=$(strip $(patsubst $(TargetOS_CPP), YES, $(findstring $(TargetOS_CPP), mingw32 linux solaris2 freebsd dragonfly netbsd openbsd darwin kfreebsdgnu)))
+ArchSupportsGHCi=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 powerpc powerpc64 powerpc64le sparc sparc64 arm aarch64)))
+
+ifeq "$(OsSupportsGHCi)$(ArchSupportsGHCi)" "YESYES"
+GhcWithInterpreter=YES
+else
+GhcWithInterpreter=$(if $(findstring YES,$(DYNAMIC_GHC_PROGRAMS)),YES,NO)
+endif
+
+# On Windows we normally want to make a relocatable bindist, to we
+# ignore flags like libdir
+ifeq "$(Windows_Host)" "YES"
+RelocatableBuild = YES
+else
+RelocatableBuild = NO
+endif
+
+
+# runhaskell and hsc2hs are special, in that other compilers besides
+# GHC might provide them.  Systems with a package manager often come
+# with tools to manage this kind of clash, e.g. RPM's
+# update-alternatives.  When building a distribution for such a system,
+# we recommend setting both of the following to 'YES'.
+#
+# NO_INSTALL_RUNHASKELL = YES
+# NO_INSTALL_HSC2HS     = YES
+#
+# NB. we use negative tests here because for binary-distributions we cannot
+# test build-time variables at install-time, so they must default to on.
+
+ifneq "$(DESTDIR)" ""
+override DESTDIR := $(abspath $(DESTDIR))
+endif
+
+# We build the libraries at least the "vanilla" way (way "v")
+# Technically we don't need the v way if DYNAMIC_GHC_PROGRAMS is YES,
+# but with -dynamic-too it's cheap, and makes life easier.
+GhcLibWays = v
+
+# In addition to the normal sequential way, the default is to also build
+# profiled prelude libraries
+# $(if $(filter ...)) allows controlling this expression from build.mk.
+GhcLibWays += $(if $(filter $(BUILD_PROF_LIBS),NO),,p)
+
+# Backward compatibility: although it would be cleaner to test for
+# PlatformSupportsSharedLibs, or perhaps a new variable BUILD_SHARED_LIBS,
+# some users currently expect that DYNAMIC_GHC_PROGRAMS=NO in build.mk implies
+# that dyn is not added to GhcLibWays.
+GhcLibWays += $(if $(filter $(DYNAMIC_GHC_PROGRAMS),NO),,dyn)
+
+# Handy way to test whether we're building shared libs or not.
+BuildSharedLibs=$(strip $(if $(findstring dyn,$(GhcLibWays)),YES,NO))
+
+# In addition, the RTS is built in some further variations.  Ways that
+# make sense here:
+#
+#   thr           : threaded
+#   thr_p         : threaded + profiled
+#   debug         : debugging
+#   thr_debug     : debugging + threaded
+#   p             : profiled
+#
+# While the eventlog used to be enabled in only a subset of ways, we now always
+# enable it.
+
+# Usually want the debug version
+GhcRTSWays = debug
+
+# We always have the threaded versions, but note that SMP support may be disabled
+# (see GhcWithSMP).
+GhcRTSWays += thr thr_debug
+GhcRTSWays += $(if $(findstring p, $(GhcLibWays)),thr_p,)
+GhcRTSWays += $(if $(findstring dyn, $(GhcLibWays)),dyn debug_dyn thr_dyn thr_debug_dyn,)
+GhcRTSWays += $(if $(findstring p, $(GhcLibWays)),thr_debug_p debug_p,)
+
+# We can only build GHCi threaded if we have a threaded RTS:
+GhcThreaded = $(if $(findstring thr,$(GhcRTSWays)),YES,NO)
+
+# Configuration for libffi
+UseSystemLibFFI=@UseSystemLibFFI@
+UseLibffiForAdjustors=@UseLibffiForAdjustors@
+
+# GHC needs arch-specific tweak at least in
+#     rts/Libdw.c:set_initial_registers()
+GhcRtsWithLibdw=$(strip $(if $(filter $(TargetArch_CPP),i386 x86_64 s390x), at UseLibdw@,NO))
+
+#-----------------------------------------------------------------------------
+# Settings
+
+# We are in the process of moving the settings file from being entirely
+# generated by configure, to generated being by the build system. Many of these
+# might become redundant.
+# See Note [tooldir: How GHC finds mingw on Windows]
+
+GccExtraViaCOpts = @GccExtraViaCOpts@
+LdHasFilelist = @LdHasFilelist@
+LdHasBuildId = @LdHasBuildId@
+LdHasFilelist = @LdHasFilelist@
+LdIsGNULd = @LdIsGNULd@
+LdHasNoCompactUnwind = @LdHasNoCompactUnwind@
+ArArgs = @ArArgs@
+ArSupportsAtFile = @ArSupportsAtFile@
+ArSupportsDashL  = @ArSupportsDashL@
+HaskellHostOs = @HaskellHostOs@
+HaskellHostArch = @HaskellHostArch@
+HaskellTargetOs = @HaskellTargetOs@
+HaskellTargetArch = @HaskellTargetArch@
+TargetWordSize = @TargetWordSize@
+TargetWordBigEndian = @TargetWordBigEndian@
+TargetHasGnuNonexecStack = @TargetHasGnuNonexecStack@
+TargetHasIdentDirective = @TargetHasIdentDirective@
+TargetHasSubsectionsViaSymbols = @TargetHasSubsectionsViaSymbols@
+TargetHasRTSLinker = @TargetHasRTSLinker@
+TargetHasLibm = @TargetHasLibm@
+TablesNextToCode = @TablesNextToCode@
+
+SettingsCCompilerCommand = @SettingsCCompilerCommand@
+SettingsCxxCompilerCommand = @SettingsCxxCompilerCommand@
+SettingsHaskellCPPCommand = @SettingsHaskellCPPCommand@
+SettingsHaskellCPPFlags = @SettingsHaskellCPPFlags@
+SettingsCCompilerFlags = @SettingsCCompilerFlags@
+SettingsCxxCompilerFlags = @SettingsCxxCompilerFlags@
+SettingsCCompilerLinkFlags = @SettingsCCompilerLinkFlags@
+SettingsCCompilerSupportsNoPie = @SettingsCCompilerSupportsNoPie@
+SettingsLdCommand = @SettingsLdCommand@
+SettingsLdFlags = @SettingsLdFlags@
+SettingsMergeObjectsCommand = @SettingsMergeObjectsCommand@
+SettingsMergeObjectsFlags = @SettingsMergeObjectsFlags@
+SettingsArCommand = @SettingsArCommand@
+SettingsOtoolCommand = @SettingsOtoolCommand@
+SettingsInstallNameToolCommand = @SettingsInstallNameToolCommand@
+SettingsRanlibCommand = @SettingsRanlibCommand@
+SettingsDllWrapCommand = @SettingsDllWrapCommand@
+SettingsWindresCommand = @SettingsWindresCommand@
+SettingsLibtoolCommand = @SettingsLibtoolCommand@
+SettingsTouchCommand = @SettingsTouchCommand@
+SettingsClangCommand = @SettingsClangCommand@
+SettingsLlcCommand = @SettingsLlcCommand@
+SettingsOptCommand = @SettingsOptCommand@
+SettingsUseDistroMINGW = @SettingsUseDistroMINGW@
+


=====================================
hadrian/src/Packages.hs
=====================================
@@ -14,7 +14,7 @@ module Packages (
     ghcPackages, isGhcPackage,
 
     -- * Package information
-    programName, nonHsMainPackage, autogenPath, programPath, timeoutPath,
+    crossPrefix, programName, nonHsMainPackage, autogenPath, programPath, timeoutPath,
     rtsContext, rtsBuildPath, libffiBuildPath,
     ensureConfigured
     ) where
@@ -154,15 +154,20 @@ linter name = program name ("linters" -/- name)
 setPath :: Package -> FilePath -> Package
 setPath pkg path = pkg { pkgPath = path }
 
+-- | Target prefix to prepend to executable names.
+crossPrefix :: Action String
+crossPrefix = do
+    cross <- flag CrossCompiling
+    targetPlatform <- setting TargetPlatformFull
+    return $ if cross then targetPlatform ++ "-" else ""
+
 -- | Given a 'Context', compute the name of the program that is built in it
 -- assuming that the corresponding package's type is 'Program'. For example, GHC
 -- built in 'Stage0' is called @ghc-stage1 at . If the given package is a
 -- 'Library', the function simply returns its name.
 programName :: Context -> Action String
 programName Context {..} = do
-    cross <- flag CrossCompiling
-    targetPlatform <- setting TargetPlatformFull
-    let prefix = if cross then targetPlatform ++ "-" else ""
+    prefix <- crossPrefix
     -- TODO: Can we extract this information from Cabal files?
     -- Alp: We could, but then the iserv package would have to
     --      use Cabal conditionals + a 'profiling' flag


=====================================
hadrian/src/Rules/BinaryDist.hs
=====================================
@@ -1,4 +1,4 @@
-{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE TupleSections, MultiWayIf #-}
 module Rules.BinaryDist where
 
 import Hadrian.Haskell.Cabal
@@ -254,6 +254,7 @@ bindistRules = do
           -- other machine.
           need $ map (bindistFilesDir -/-)
                     (["configure", "Makefile"] ++ bindistInstallFiles)
+          copyFile ("hadrian" -/- "bindist" -/- "config.mk.in") (bindistFilesDir -/- "config.mk.in")
           forM_ bin_targets $ \(pkg, _) -> do
             needed_wrappers <- pkgToWrappers pkg
             forM_ needed_wrappers $ \wrapper_name -> do
@@ -346,9 +347,12 @@ compressorExtension Bzip2 = "bz2"
 bindistInstallFiles :: [FilePath]
 bindistInstallFiles =
     [ "config.sub", "config.guess", "install-sh"
-    , "mk" -/- "config.mk.in", "mk" -/- "install.mk.in", "mk" -/- "project.mk"
+    , "mk" -/- "config.mk.in" -- TODO: Remove when make is gone
+    , "mk" -/- "install.mk.in" -- TODO: Remove when make is gone
+    , "mk" -/- "project.mk"
     , "mk" -/- "relpath.sh"
     , "mk" -/- "system-cxx-std-lib-1.0.conf.in"
+    , "mk" -/- "install_script.sh"
     , "README", "INSTALL" ]
 
 -- | This auxiliary function gives us a top-level 'Filepath' that we can 'need'
@@ -370,19 +374,20 @@ useGhcPrefix pkg
   | pkg == ghciWrapper = False
   | otherwise = True
 
-
 -- | Which wrappers point to a specific package
 pkgToWrappers :: Package -> Action [String]
-pkgToWrappers pkg
-  -- ghc also has the ghci script wrapper
-  | pkg == ghc = pure ["ghc", "ghci"]
-  | pkg == runGhc = pure ["runghc", "runhaskell"]
-  -- These are the packages which we want to expose to the user and hence
-  -- there are wrappers installed in the bindist.
-  | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg]
-    = (:[]) <$> (programName =<< programContext Stage1 pkg)
-  | otherwise = pure []
-
+pkgToWrappers pkg = do
+    prefix <- crossPrefix
+    if  -- ghc also has the ghci script wrapper
+        -- N.B. programName would add the crossPrefix therefore we must do the
+        -- same here.
+      | pkg == ghc    -> pure $ map (prefix++) ["ghc", "ghci"]
+      | pkg == runGhc -> pure $ map (prefix++) ["runghc", "runhaskell"]
+        -- These are the packages which we want to expose to the user and hence
+        -- there are wrappers installed in the bindist.
+      | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg]
+                      -> (:[]) <$> (programName =<< programContext Stage1 pkg)
+      | otherwise     -> pure []
 
 wrapper :: FilePath -> Action String
 wrapper "ghc"         = ghcWrapper


=====================================
hadrian/src/Settings/Builders/RunTest.hs
=====================================
@@ -278,6 +278,7 @@ runTestBuilderArgs = builder Testsuite ? do
       where emitWhenSet Nothing  _ = mempty
             emitWhenSet (Just v) f = f v
 
+            stageNumber :: Stage -> Int
             stageNumber (Stage0 GlobalLibs) = error "stageNumber stageBoot"
             stageNumber (Stage0 InTreeLibs) = 1
             stageNumber Stage1 = 2


=====================================
libraries/base/GHC/Event/Thread.hs
=====================================
@@ -18,7 +18,7 @@ module GHC.Event.Thread
 -- TODO: Use new Windows I/O manager
 import Control.Exception (finally, SomeException, toException)
 import Data.Foldable (forM_, mapM_, sequence_)
-import Data.IORef (IORef, newIORef, readIORef, writeIORef)
+import Data.IORef (IORef, newIORef, readIORef, writeIORef, atomicWriteIORef)
 import Data.Maybe (fromMaybe)
 import Data.Tuple (snd)
 import Foreign.C.Error (eBADF, errnoToIOError)
@@ -29,7 +29,8 @@ import GHC.List (zipWith, zipWith3)
 import GHC.Conc.Sync (TVar, ThreadId, ThreadStatus(..), atomically, forkIO,
                       labelThread, modifyMVar_, withMVar, newTVar, sharedCAF,
                       getNumCapabilities, threadCapability, myThreadId, forkOn,
-                      threadStatus, writeTVar, newTVarIO, readTVar, retry,throwSTM,STM)
+                      threadStatus, writeTVar, newTVarIO, readTVar, retry,
+                      throwSTM, STM, yield)
 import GHC.IO (mask_, uninterruptibleMask_, onException)
 import GHC.IO.Exception (ioError)
 import GHC.IOArray (IOArray, newIOArray, readIOArray, writeIOArray,
@@ -41,6 +42,7 @@ import GHC.Event.Manager (Event, EventManager, evtRead, evtWrite, loop,
                              new, registerFd, unregisterFd_)
 import qualified GHC.Event.Manager as M
 import qualified GHC.Event.TimerManager as TM
+import GHC.Ix (inRange)
 import GHC.Num ((-), (+))
 import GHC.Real (fromIntegral)
 import GHC.Show (showSignedInt)
@@ -98,22 +100,44 @@ threadWaitWrite = threadWait evtWrite
 closeFdWith :: (Fd -> IO ())        -- ^ Action that performs the close.
             -> Fd                   -- ^ File descriptor to close.
             -> IO ()
-closeFdWith close fd = do
-  eventManagerArray <- readIORef eventManager
-  let (low, high) = boundsIOArray eventManagerArray
-  mgrs <- flip mapM [low..high] $ \i -> do
-    Just (_,!mgr) <- readIOArray eventManagerArray i
-    return mgr
-  -- 'takeMVar', and 'M.closeFd_' might block, although for a very short time.
-  -- To make 'closeFdWith' safe in presence of asynchronous exceptions we have
-  -- to use uninterruptible mask.
-  uninterruptibleMask_ $ do
-    tables <- flip mapM mgrs $ \mgr -> takeMVar $ M.callbackTableVar mgr fd
-    cbApps <- zipWithM (\mgr table -> M.closeFd_ mgr table fd) mgrs tables
-    close fd `finally` sequence_ (zipWith3 finish mgrs tables cbApps)
+closeFdWith close fd = close_loop
   where
     finish mgr table cbApp = putMVar (M.callbackTableVar mgr fd) table >> cbApp
     zipWithM f xs ys = sequence (zipWith f xs ys)
+      -- The array inside 'eventManager' can be swapped out at any time, see
+      -- 'ioManagerCapabilitiesChanged'. See #21651. We detect this case by
+      -- checking the array bounds before and after. When such a swap has
+      -- happened we cleanup and try again
+    close_loop = do
+      eventManagerArray <- readIORef eventManager
+      let ema_bounds@(low, high) = boundsIOArray eventManagerArray
+      mgrs <- flip mapM [low..high] $ \i -> do
+        Just (_,!mgr) <- readIOArray eventManagerArray i
+        return mgr
+
+      -- 'takeMVar', and 'M.closeFd_' might block, although for a very short time.
+      -- To make 'closeFdWith' safe in presence of asynchronous exceptions we have
+      -- to use uninterruptible mask.
+      join $ uninterruptibleMask_ $ do
+        tables <- flip mapM mgrs $ \mgr -> takeMVar $ M.callbackTableVar mgr fd
+        new_ema_bounds <- boundsIOArray `fmap` readIORef eventManager
+        -- Here we exploit Note [The eventManager Array]
+        if new_ema_bounds /= ema_bounds
+          then do
+            -- the array has been modified.
+            -- mgrs still holds the right EventManagers, by the Note.
+            -- new_ema_bounds must be larger than ema_bounds, by the note.
+            -- return the MVars we took and try again
+            sequence_ $ zipWith (\mgr table -> finish mgr table (pure ())) mgrs tables
+            pure close_loop
+          else do
+            -- We surely have taken all the appropriate MVars. Even if the array
+            -- has been swapped, our mgrs is still correct.
+            -- Remove the Fd from all callback tables, close the Fd, and run all
+            -- callbacks.
+            cbApps <- zipWithM (\mgr table -> M.closeFd_ mgr table fd) mgrs tables
+            close fd `finally` sequence_ (zipWith3 finish mgrs tables cbApps)
+            pure (pure ())
 
 threadWait :: Event -> Fd -> IO ()
 threadWait evt fd = mask_ $ do
@@ -177,10 +201,24 @@ threadWaitWriteSTM = threadWaitSTM evtWrite
 getSystemEventManager :: IO (Maybe EventManager)
 getSystemEventManager = do
   t <- myThreadId
-  (cap, _) <- threadCapability t
   eventManagerArray <- readIORef eventManager
-  mmgr <- readIOArray eventManagerArray cap
-  return $ fmap snd mmgr
+  let r = boundsIOArray eventManagerArray
+  (cap, _) <- threadCapability t
+  -- It is possible that we've just increased the number of capabilities and the
+  -- new EventManager has not yet been constructed by
+  -- 'ioManagerCapabilitiesChanged'. We expect this to happen very rarely.
+  -- T21561 exercises this.
+  -- Two options to proceed:
+  --  1) return the EventManager for capability 0. This is guaranteed to exist,
+  --     and "shouldn't" cause any correctness issues.
+  --  2) Busy wait, with or without a call to 'yield'. This can't deadlock,
+  --     because we must be on a brand capability and there must be a call to
+  --     'ioManagerCapabilitiesChanged' pending.
+  --
+  -- We take the second option, with the yield, judging it the most robust.
+  if not (inRange r cap)
+    then yield >> getSystemEventManager
+    else fmap snd `fmap` readIOArray eventManagerArray cap
 
 getSystemEventManager_ :: IO EventManager
 getSystemEventManager_ = do
@@ -191,6 +229,22 @@ getSystemEventManager_ = do
 foreign import ccall unsafe "getOrSetSystemEventThreadEventManagerStore"
     getOrSetSystemEventThreadEventManagerStore :: Ptr a -> IO (Ptr a)
 
+-- Note [The eventManager Array]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- A mutable array holding the current EventManager for each capability
+-- An entry is Nothing only while the eventmanagers are initialised, see
+-- 'startIOManagerThread' and 'ioManagerCapabilitiesChanged'.
+-- The 'ThreadId' at array position 'cap'  will have been 'forkOn'ed capabality
+-- 'cap'.
+-- The array will be swapped with newer arrays when the number of capabilities
+-- changes(via 'setNumCapabilities'). However:
+--   * the size of the arrays will never decrease; and
+--   * The 'EventManager's in the array are not replaced with other
+--     'EventManager' constructors.
+--
+-- This is a similar strategy as the rts uses for it's
+-- capabilities array (n_capabilities is the size of the array,
+-- enabled_capabilities' is the number of active capabilities).
 eventManager :: IORef (IOArray Int (Maybe (ThreadId, EventManager)))
 eventManager = unsafePerformIO $ do
     numCaps <- getNumCapabilities
@@ -351,7 +405,9 @@ ioManagerCapabilitiesChanged =
                 startIOManagerThread new_eventManagerArray
 
               -- update the event manager array reference:
-              writeIORef eventManager new_eventManagerArray
+              atomicWriteIORef eventManager new_eventManagerArray
+              -- We need an atomic write here because 'eventManager' is accessed
+              -- unsynchronized in 'getSystemEventManager' and 'closeFdWith'
       else when (new_n_caps > numEnabled) $
             forM_ [numEnabled..new_n_caps-1] $ \i -> do
               Just (_,mgr) <- readIOArray eventManagerArray i


=====================================
m4/fp_find_cxx_std_lib.m4
=====================================
@@ -18,10 +18,44 @@ unknown
 #endif
 EOF
         AC_MSG_CHECKING([C++ standard library flavour])
-        if "$CXX" -E actest.cpp -o actest.out; then
-            if grep "libc++" actest.out >/dev/null; then
-                CXX_STD_LIB_LIBS="c++ c++abi"
-                p="`"$CXX" --print-file-name libc++.so`"
+        if ! "$CXX" -E actest.cpp -o actest.out; then
+            rm -f actest.cpp actest.out
+            AC_MSG_ERROR([Failed to compile test program])
+        fi
+
+        dnl Identify standard library type
+        if grep "libc++" actest.out >/dev/null; then
+            CXX_STD_LIB_FLAVOUR="c++"
+            AC_MSG_RESULT([libc++])
+        elif grep "libstdc++" actest.out >/dev/null; then
+            CXX_STD_LIB_FLAVOUR="stdc++"
+            AC_MSG_RESULT([libstdc++])
+        else
+            rm -f actest.cpp actest.out
+            AC_MSG_ERROR([Unknown C++ standard library implementation.])
+        fi
+        rm -f actest.cpp actest.out
+
+        dnl -----------------------------------------
+        dnl Figure out how to link...
+        dnl -----------------------------------------
+        cat >actest.cpp <<-EOF
+#include <iostream>
+int main(int argc, char** argv) {
+    std::cout << "hello world\n";
+    return 0;
+}
+EOF
+        if ! "$CXX" -c actest.cpp; then
+            AC_MSG_ERROR([Failed to compile test object])
+        fi
+
+        try_libs() {
+            dnl Try to link a plain object with CC manually
+            AC_MSG_CHECKING([for linkage against '${3}'])
+            if "$CC" -o actest actest.o ${1} 2>/dev/null; then
+                CXX_STD_LIB_LIBS="${3}"
+                p="`"$CXX" --print-file-name ${2}`"
                 d="`dirname "$p"`"
                 dnl On some platforms (e.g. Windows) the C++ standard library
                 dnl can be found in the system search path. In this case $CXX
@@ -31,24 +65,25 @@ EOF
                 if test "$d" = "."; then d=""; fi
                 CXX_STD_LIB_LIB_DIRS="$d"
                 CXX_STD_LIB_DYN_LIB_DIRS="$d"
-                AC_MSG_RESULT([libc++])
-            elif grep "libstdc++" actest.out >/dev/null; then
-                CXX_STD_LIB_LIBS="stdc++"
-                p="`"$CXX" --print-file-name libstdc++.so`"
-                d="`dirname "$p"`"
-                if test "$d" = "."; then d=""; fi
-                CXX_STD_LIB_LIB_DIRS="$d"
-                CXX_STD_LIB_DYN_LIB_DIRS="$d"
-                AC_MSG_RESULT([libstdc++])
+                AC_MSG_RESULT([success])
+                true
             else
-                rm -f actest.cpp actest.out
-                AC_MSG_ERROR([Unknown C++ standard library implementation.])
+                AC_MSG_RESULT([failed])
+                false
             fi
-            rm -f actest.cpp actest.out
-        else
-            rm -f actest.cpp actest.out
-            AC_MSG_ERROR([Failed to compile test program])
-        fi
+        }
+        case $CXX_STD_LIB_FLAVOUR in
+        c++)
+            try_libs "-lc++ -lc++abi" "libc++.so" "c++ c++abi" || \
+            try_libs "-lc++ -lcxxrt" "libc++.so" "c++ cxxrt" ||
+            AC_MSG_ERROR([Failed to find C++ standard library]) ;;
+        stdc++)
+            try_libs "-lstdc++" "libstdc++.so" "stdc++" || \
+            try_libs "-lstdc++ -lsupc++" "libstdc++.so" "stdc++ supc++" || \
+            AC_MSG_ERROR([Failed to find C++ standard library]) ;;
+        esac
+
+        rm -f actest.cpp actest.o actest
     fi
 
     AC_SUBST([CXX_STD_LIB_LIBS])


=====================================
mk/install_script.sh
=====================================
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# $1 = executable name
+# $2 = wrapper path
+# $3 = bindir
+# $4 = ghcbindir
+# $5 = Executable binary path
+# $6 = Library Directory
+# $7 = Docs Directory
+# $8 = Includes Directory
+# We are installing wrappers to programs by searching corresponding
+# wrappers. If wrapper is not found, we are attaching the common wrapper
+# to it. This implementation is a bit hacky and depends on consistency
+# of program names. For hadrian build this will work as programs have a
+# consistent naming procedure.
+
+echo "Installing $1 -> $2"
+if [ -L "wrappers/$1" ]; then
+    cp -RP "wrappers/$1" "$2"
+else
+    rm -f "$2" &&
+    touch "$2" &&
+    echo "#!$SHELL" >> "$2"  &&
+    echo "exedir=\"$4\"" >> "$2"  &&
+    echo "exeprog=\"$1\"" >> "$2"  &&
+    echo "executablename=\"$5\"" >> "$2"  &&
+    echo "bindir=\"$3\"" >> "$2"  &&
+    echo "libdir=\"$6\"" >> "$2"  &&
+    echo "docdir=\"$7\"" >> "$2"  &&
+    echo "includedir=\"$8\"" >> "$2"  &&
+    echo "" >> "$2"  &&
+    cat "wrappers/$1" >> "$2"  &&
+    chmod 755 "$2"
+fi


=====================================
rts/Linker.c
=====================================
@@ -80,6 +80,33 @@
 #if defined(dragonfly_HOST_OS)
 #include <sys/tls.h>
 #endif
+
+/*
+ * Note [iconv and FreeBSD]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * On FreeBSD libc.so provides an implementation of the iconv_* family of
+ * functions. However, due to their implementation, these symbols cannot be
+ * resolved via dlsym(); rather, they can only be resolved using the
+ * explicitly-versioned dlvsym().
+ *
+ * This is problematic for the RTS linker since we may be asked to load
+ * an object that depends upon iconv. To handle this we include a set of
+ * fallback cases for these functions, allowing us to resolve them to the
+ * symbols provided by the libc against which the RTS is linked.
+ *
+ * See #20354.
+ */
+
+#if defined(freebsd_HOST_OS)
+extern void iconvctl();
+extern void iconv_open_into();
+extern void iconv_open();
+extern void iconv_close();
+extern void iconv_canonicalize();
+extern void iconv();
+#endif
+
 /*
    Note [runtime-linker-support]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -637,6 +664,10 @@ internal_dlsym(const char *symbol) {
     }
     RELEASE_LOCK(&dl_mutex);
 
+    IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol));
+#   define SPECIAL_SYMBOL(sym) \
+      if (strcmp(symbol, #sym) == 0) return (void*)&sym;
+
 #   if defined(HAVE_SYS_STAT_H) && defined(linux_HOST_OS) && defined(__GLIBC__)
     // HACK: GLIBC implements these functions with a great deal of trickery where
     //       they are either inlined at compile time to their corresponding
@@ -646,18 +677,28 @@ internal_dlsym(const char *symbol) {
     //       We borrow the approach that the LLVM JIT uses to resolve these
     //       symbols. See http://llvm.org/PR274 and #7072 for more info.
 
-    IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in GLIBC special cases\n", symbol));
+    SPECIAL_SYMBOL(stat);
+    SPECIAL_SYMBOL(fstat);
+    SPECIAL_SYMBOL(lstat);
+    SPECIAL_SYMBOL(stat64);
+    SPECIAL_SYMBOL(fstat64);
+    SPECIAL_SYMBOL(lstat64);
+    SPECIAL_SYMBOL(atexit);
+    SPECIAL_SYMBOL(mknod);
+#   endif
 
-    if (strcmp(symbol, "stat") == 0) return (void*)&stat;
-    if (strcmp(symbol, "fstat") == 0) return (void*)&fstat;
-    if (strcmp(symbol, "lstat") == 0) return (void*)&lstat;
-    if (strcmp(symbol, "stat64") == 0) return (void*)&stat64;
-    if (strcmp(symbol, "fstat64") == 0) return (void*)&fstat64;
-    if (strcmp(symbol, "lstat64") == 0) return (void*)&lstat64;
-    if (strcmp(symbol, "atexit") == 0) return (void*)&atexit;
-    if (strcmp(symbol, "mknod") == 0) return (void*)&mknod;
+    // See Note [iconv and FreeBSD]
+#   if defined(freebsd_HOST_OS)
+    SPECIAL_SYMBOL(iconvctl);
+    SPECIAL_SYMBOL(iconv_open_into);
+    SPECIAL_SYMBOL(iconv_open);
+    SPECIAL_SYMBOL(iconv_close);
+    SPECIAL_SYMBOL(iconv_canonicalize);
+    SPECIAL_SYMBOL(iconv);
 #   endif
 
+#undef SPECIAL_SYMBOL
+
     // we failed to find the symbol
     return NULL;
 }


=====================================
testsuite/tests/concurrent/should_run/T21651.hs
=====================================
@@ -0,0 +1,124 @@
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+
+-- This test is adapted from setnumcapabilities001.
+
+import GHC.Conc hiding (threadWaitRead, threadWaitWrite)
+import GHC.Exts
+import GHC.IO.Encoding
+import System.Environment
+import System.IO
+import Control.Monad
+import Text.Printf
+import Data.Time.Clock
+import Control.DeepSeq
+
+import System.Posix.IO
+import System.Posix.Types
+import Control.Concurrent
+import Control.Exception
+
+passTheParcel :: Int -> IO (IO ())
+passTheParcel n = do
+  pipes@(p1 : rest) <- forM [0..n-1] $ \_ -> createPipe
+  rs@((_,tid1) : _) <- forM (pipes `zip` (rest ++ [p1])) $ \((readfd, _), (_, writefd)) -> do
+    let
+      read = fdRead readfd $ fromIntegral 1
+      write = fdWrite writefd
+    mv <- newEmptyMVar
+    tid <- forkIO $ let
+      loop = flip catch (\(x :: IOException) -> pure ()) $ forever $ do
+        threadWaitRead readfd
+        (s, _) <- read
+        threadWaitWrite writefd
+        write s
+      cleanup = do
+        closeFdWith closeFd readfd
+        closeFdWith closeFd writefd
+        putMVar mv ()
+      in loop `finally` cleanup
+    pure (mv, tid)
+
+  let
+    cleanup = do
+      killThread tid1
+      forM_ rs $ \(mv, _) -> takeMVar mv
+
+  fdWrite (snd p1) "a"
+  pure cleanup
+
+
+main = do
+  setLocaleEncoding latin1 -- fdRead and fdWrite depend on the current locale
+  [n,q,t,z] <- fmap (fmap read) getArgs
+  cleanup_ptp <- passTheParcel z
+  t <- forkIO $ do
+    forM_ (cycle ([n,n-1..1] ++ [2..n-1])) $ \m -> do
+      setNumCapabilities m
+      threadDelay t
+  printf "%d\n" (nqueens q)
+  cleanup_ptp
+  killThread t
+      -- If we don't kill the child thread, it might be about to
+      -- call setNumCapabilities() in C when the main thread exits,
+      -- and chaos can ensue.  See #12038
+
+nqueens :: Int -> Int
+nqueens nq = length (pargen 0 [])
+ where
+    safe :: Int -> Int -> [Int] -> Bool
+    safe x d []    = True
+    safe x d (q:l) = x /= q && x /= q+d && x /= q-d && safe x (d+1) l
+
+    gen :: [[Int]] -> [[Int]]
+    gen bs = [ (q:b) | b <- bs, q <- [1..nq], safe q 1 b ]
+
+    pargen :: Int -> [Int] -> [[Int]]
+    pargen n b
+       | n >= threshold = iterate gen [b] !! (nq - n)
+       | otherwise      = concat bs
+       where bs = map (pargen (n+1)) (gen [b]) `using` parList rdeepseq
+
+    threshold = 3
+
+using :: a -> Strategy a -> a
+x `using` strat = runEval (strat x)
+
+type Strategy a = a -> Eval a
+
+newtype Eval a = Eval (State# RealWorld -> (# State# RealWorld, a #))
+
+runEval :: Eval a -> a
+runEval (Eval x) = case x realWorld# of (# _, a #) -> a
+
+instance Functor Eval where
+  fmap = liftM
+
+instance Applicative Eval where
+  pure x = Eval $ \s -> (# s, x #)
+  (<*>)  = ap
+
+instance Monad Eval where
+  return = pure
+  Eval x >>= k = Eval $ \s -> case x s of
+                                (# s', a #) -> case k a of
+                                                      Eval f -> f s'
+
+parList :: Strategy a -> Strategy [a]
+parList strat = traverse (rparWith strat)
+
+rpar :: Strategy a
+rpar  x = Eval $ \s -> spark# x s
+
+rseq :: Strategy a
+rseq x = Eval $ \s -> seq# x s
+
+rparWith :: Strategy a -> Strategy a
+rparWith s a = do l <- rpar r; return (case l of Lift x -> x)
+  where r = case s a of
+              Eval f -> case f realWorld# of
+                          (# _, a' #) -> Lift a'
+
+data Lift a = Lift a
+
+rdeepseq :: NFData a => Strategy a
+rdeepseq x = do rseq (rnf x); return x


=====================================
testsuite/tests/concurrent/should_run/T21651.stdout
=====================================
@@ -0,0 +1 @@
+14200


=====================================
testsuite/tests/concurrent/should_run/all.T
=====================================
@@ -218,12 +218,20 @@ test('conc067', ignore_stdout, compile_and_run, [''])
 test('conc068', [ omit_ways(concurrent_ways), exit_code(1) ], compile_and_run, [''])
 
 test('setnumcapabilities001',
-     [ only_ways(['threaded1','threaded2', 'nonmoving_thr']),
+     [ only_ways(['threaded1','threaded2', 'nonmoving_thr', 'profthreaded']),
        extra_run_opts('8 12 2000'),
        when(have_thread_sanitizer(), expect_broken(18808)),
        req_smp ],
      compile_and_run, [''])
 
+test('T21651',
+     [ only_ways(['threaded1','threaded2', 'nonmoving_thr', 'profthreaded']),
+       when(opsys('mingw32'),skip), # uses POSIX pipes
+       when(opsys('darwin'),extra_run_opts('8 12 2000 100')),
+       unless(opsys('darwin'),extra_run_opts('8 12 2000 200')), # darwin runners complain of too many open files
+       req_smp ],
+     compile_and_run, [''])
+
 test('hs_try_putmvar001',
      [
      when(opsys('mingw32'),skip), # uses pthread APIs in the C code



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6d01245c458c49ca25c89ec13be3268ab6930a27...480b066d06e6f7a0fa66c0e73e917935a76390a9

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6d01245c458c49ca25c89ec13be3268ab6930a27...480b066d06e6f7a0fa66c0e73e917935a76390a9
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20220810/e4987dad/attachment-0001.html>


More information about the ghc-commits mailing list