Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

22 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -1300,7 +1300,7 @@ ghcup-metadata-nightly:
    1300 1300
           artifacts: false
    
    1301 1301
         - job: project-version
    
    1302 1302
       script:
    
    1303
    -    - nix shell -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --date="$(date -d $CI_PIPELINE_CREATED_AT +%Y-%m-%d)" --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml"
    
    1303
    +    - nix shell -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --date="$(date -d $CI_PIPELINE_CREATED_AT +%Y-%m-%d)" --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" metadata_test.yaml
    
    1304 1304
       rules:
    
    1305 1305
         - if: $NIGHTLY
    
    1306 1306
     
    

  • .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
    ... ... @@ -324,6 +324,7 @@ def main() -> None:
    324 324
         # TODO: We could work out the --version from the project-version CI job.
    
    325 325
         parser.add_argument('--version', required=True, type=str, help='Version of the GHC compiler')
    
    326 326
         parser.add_argument('--date', required=True, type=str, help='Date of the compiler release')
    
    327
    +    parser.add_argument('output_path', nargs='?', type=Path, help='Path to write the output to, if not set, dump to stdout')
    
    327 328
         args = parser.parse_args()
    
    328 329
     
    
    329 330
         project = gl.projects.get(1, lazy=True)
    
    ... ... @@ -352,13 +353,14 @@ def main() -> None:
    352 353
             with open(args.metadata, 'r') as file:
    
    353 354
                 ghcup_metadata = yaml.safe_load(file)
    
    354 355
                 if  args.version in ghcup_metadata['ghcupDownloads']['GHC']:
    
    355
    -                # if there are days without a commit, then the nightly metadata
    
    356
    -                # is up to date by default, no need to fail, no need to upload anything
    
    357
    -                print("Refusing to override existing version in metadata, exiting")
    
    358
    -                sys.exit()
    
    356
    +                eprint("GHCUp nightly run produced the same metadata as last night")
    
    359 357
                 setNightlyTags(ghcup_metadata)
    
    360 358
                 ghcup_metadata['ghcupDownloads']['GHC'][args.version] = new_yaml
    
    361
    -            print(yaml.dump(ghcup_metadata))
    
    359
    +            if args.output_path:
    
    360
    +                with open(args.output_path, 'w') as ofile:
    
    361
    +                    yaml.dump(ghcup_metadata, ofile)
    
    362
    +            else:
    
    363
    +                print(yaml.dump(ghcup_metadata))
    
    362 364
     
    
    363 365
     
    
    364 366
     
    

  • changelog.d/T27705
    1
    +section: compiler
    
    2
    +synopsis: Fixed an issue that caused the specializer to sometimes loop on recursive dictionary superclasses.
    
    3
    +issues: #27705
    
    4
    +mrs: !16559
    
    5
    +

  • changelog.d/T27722-cbe-entry-block.md
    1
    +section: cmm
    
    2
    +issues: #27722
    
    3
    +mrs: !16592
    
    4
    +synopsis:
    
    5
    +  Fix common block elimination dropping entry block info table in hand written cmm.

  • compiler/GHC/Cmm/CommonBlockElim.hs
    ... ... @@ -26,6 +26,7 @@ import GHC.Types.Literal.Floating
    26 26
     import GHC.Types.Unique.FM
    
    27 27
     import GHC.Types.Unique
    
    28 28
     import GHC.Utils.Word64 (truncateWord64ToWord32)
    
    29
    +import GHC.Utils.Panic.Plain (assert)
    
    29 30
     import Control.Arrow (first, second)
    
    30 31
     import Data.List.NonEmpty (NonEmpty (..))
    
    31 32
     import qualified Data.List.NonEmpty as NE
    
    ... ... @@ -60,16 +61,31 @@ import qualified Data.List.NonEmpty as NE
    60 61
     
    
    61 62
     -- TODO: Use optimization fuel
    
    62 63
     elimCommonBlocks :: CmmGraph -> CmmGraph
    
    63
    -elimCommonBlocks g = replaceLabels env $ copyTicks env g
    
    64
    +elimCommonBlocks g =
    
    65
    +    assert (g_entry g == g_entry g') g'
    
    64 66
       where
    
    67
    +     g' = replaceLabels env $ copyTicks env g
    
    65 68
          env = iterate mapEmpty blocks_with_key
    
    66 69
          -- The order of blocks doesn't matter here. While we could use
    
    67 70
          -- revPostorder which drops unreachable blocks this is done in
    
    68 71
          -- ContFlowOpt already which runs before this pass. So we use
    
    69 72
          -- toBlockList since it is faster.
    
    70
    -     groups = groupByInt hash_block (toBlockList g) :: [[CmmBlock]]
    
    73
    +     -- One exception: The entry block most come first or we risk eliminating it
    
    74
    +     -- in favour of another block. See Note [Retain entry block during common block elimination.]
    
    75
    +     groups = groupByInt hash_block (toBlockListEntryFirst g) :: [[CmmBlock]]
    
    71 76
          blocks_with_key = [ [ (successors b, [b]) | b <- bs] | bs <- groups]
    
    72 77
     
    
    78
    +-- Note [Retain entry block during common block elimination.]
    
    79
    +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    80
    +-- At the stage we run common block elimination (CBE) we only have one info
    
    81
    +-- table for the entry label. Which means we can get away without applying the
    
    82
    +-- block label substitution to the info table *as long as we keep the first block*.
    
    83
    +-- When combining blocks the first block in the list of blocks is kept, and the later
    
    84
    +-- one eliminated, so we can achieve this by simply using toBlockListEntryFirst.
    
    85
    +--
    
    86
    +-- If we don't we end up with #27722 where the entry block was eliminated in favour
    
    87
    +-- of another block.
    
    88
    +
    
    73 89
     -- Invariant: The blocks in the list are pairwise distinct
    
    74 90
     -- (so avoid comparing them again)
    
    75 91
     type DistinctBlocks = [CmmBlock]
    

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -3120,8 +3120,8 @@ interestingDict :: SpecEnv -> CoreExpr -> Bool
    3120 3120
     -- This is a subtle and important function
    
    3121 3121
     -- See Note [Interesting dictionary arguments]
    
    3122 3122
     interestingDict env (Var v)  -- See (ID3) and (ID5)
    
    3123
    +  -- (ID6.a) Might fail for loop breaker dicts but that seems fine.
    
    3123 3124
       | Just rhs <- maybeUnfoldingTemplate (idUnfolding v)
    
    3124
    -  -- Might fail for loop breaker dicts but that seems fine.
    
    3125 3125
       = interestingDict env rhs
    
    3126 3126
     
    
    3127 3127
     interestingDict env arg  -- Main Plan: use exprIsConApp_maybe
    
    ... ... @@ -3136,9 +3136,9 @@ interestingDict env arg -- Main Plan: use exprIsConApp_maybe
    3136 3136
            , isIPClass cls      -- See (ID5)
    
    3137 3137
            -> False
    
    3138 3138
     
    
    3139
    -       -- Otherwise we are unwrapping a unary type class
    
    3139
    +       -- Shouldn't happen.
    
    3140 3140
            | otherwise
    
    3141
    -       -> exprIsHNF arg   -- See (ID7)
    
    3141
    +       -> pprTraceDebug "shouldn't happen anymore" (ppr arg) $ exprIsHNF arg -- See (ID7)
    
    3142 3142
     
    
    3143 3143
       | Just (_, _, data_con, _tys, args) <- exprIsConApp_maybe in_scope_env arg
    
    3144 3144
       , Just cls <- tyConClass_maybe (dataConTyCon data_con)
    
    ... ... @@ -3152,7 +3152,8 @@ interestingDict env arg -- Main Plan: use exprIsConApp_maybe
    3152 3152
       where
    
    3153 3153
         arg_ty                  = exprType arg
    
    3154 3154
         definitely_not_ip_like  = not (couldBeIPLike arg_ty)
    
    3155
    -    in_scope_env = ISE (substInScopeSet $ se_subst env) realIdUnfolding
    
    3155
    +    -- idUnfolding rather than realIdUnfolding: See (ID6.a)
    
    3156
    +    in_scope_env = ISE (substInScopeSet $ se_subst env) idUnfolding
    
    3156 3157
     
    
    3157 3158
     {- Note [Ticks on applications]
    
    3158 3159
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -3268,11 +3269,27 @@ case we can clearly specialise. But there are wrinkles:
    3268 3269
        (Remember: a constraint tuple is just a class with N superclasses and no methods.)
    
    3269 3270
        See discussion on #26831.
    
    3270 3271
     
    
    3271
    -(ID7) A unary (single-method) class is currently represented by (meth |> co).  We
    
    3272
    -   will unwrap the cast (see (ID5)) and then want to reply "yes" if the method
    
    3273
    -   has any struture.  We rather arbitrarily use `exprIsHNF` for this.  (We plan a
    
    3274
    -   new story for unary classes, see #23109, and this special case will become
    
    3275
    -   irrelevant.)
    
    3272
    +(ID6.a) If we deal with a recursive dictionary as in #27705 we want to avoid
    
    3273
    +    infinite recursion while recursing into superclasses.
    
    3274
    +
    
    3275
    +    For example we might have:
    
    3276
    +
    
    3277
    +    class D1 a => D2 a
    
    3278
    +    class D2 a => D1 a
    
    3279
    +
    
    3280
    +  The primary concern is that we want to avoid looping on recursive instances.
    
    3281
    +  We can achieve this by simply not looking through loop breakers by using idUnfolding
    
    3282
    +  rather than realIdUnfolding.
    
    3283
    +
    
    3284
    +  It's possible that this prevents specialization of edge cases that have loop breakers
    
    3285
    +  in their recursive loop. But even if we can find a dictionary like this the simplifier
    
    3286
    +  won't look through loopbreaker dictionaries either killing any potential benefit.
    
    3287
    +  So while we could handle this case via a already-seen set or fuel we simply don't bother
    
    3288
    +  for now.
    
    3289
    +
    
    3290
    +(ID7) A unary (single-method) class is currently handled by the same path as regular dicts
    
    3291
    +   since they are represented by faking a regular Dictionary.
    
    3292
    +   See Note [Unary class magic] for the details.
    
    3276 3293
     
    
    3277 3294
     (ID8) Sadly, if `exprIsConApp_maybe` says Nothing, we still want to treat a
    
    3278 3295
        non-trivial argument as interesting. In T19695 we have this:
    

  • hadrian/README.md
    ... ... @@ -55,10 +55,9 @@ changes. Build results are placed into `_build` by default.
    55 55
     There are many different ways to build a compiler, each way is called a flavour.
    
    56 56
     
    
    57 57
     * `--flavour=FLAVOUR`: choose a build flavour. The following settings are
    
    58
    -currently supported: `default`, `quick`, `quickest`, `perf`, `prof`, `devel1`
    
    59
    -and `devel2`. As an example, the `quickest` flavour adds `-O0` flag to all GHC
    
    60
    -invocations and builds libraries only in the `vanilla` way, which speeds up
    
    61
    -builds by 3-4x.
    
    58
    +currently supported: `default`, `quick`, `perf`, `prof`, `devel1`
    
    59
    +and `devel2`. As an example, the `quick` flavour builds the GHC binary with `-O0`
    
    60
    +which speeds up builds and rebuilds significantly.
    
    62 61
     
    
    63 62
     In addition to the overall build flavour there are also "flavour transformers"
    
    64 63
     which can slightly modify the build settings for a flavour. Some common flavour
    

  • hadrian/doc/cross-compile.md
    ... ... @@ -16,7 +16,7 @@ After all the dependencies are in place:
    16 16
     - `git submodule update --init`
    
    17 17
     - `./configure --target=arm-linux-gnueabihf`
    
    18 18
     - `cd hadrian`
    
    19
    -- Build the compiler by e.g. `./build.sh --flavour=quickest --integer-simple -V -j`
    
    19
    +- Build the compiler by e.g. `./build.sh --flavour=quick --integer-simple -V -j`
    
    20 20
     
    
    21 21
     After that, you should have built `inplace/bin/ghc-stage1` cross compiler. We will go to the next section to validate this.
    
    22 22
     
    

  • hadrian/doc/flavours.md
    ... ... @@ -82,18 +82,6 @@ when compiling the `compiler` library, and `hsGhc` when compiling/linking the GH
    82 82
         <td>-O</td>
    
    83 83
         <td>-debug (link)</td>
    
    84 84
       </tr>
    
    85
    -  <tr>
    
    86
    -    <th>quickest</td>
    
    87
    -    <td></td>
    
    88
    -    <td>-O0<br>+RTS<br>-O64M<br>-RTS</td>
    
    89
    -    <td>-O0<br>+RTS<br>-O64M<br>-RTS</td>
    
    90
    -    <td></td>
    
    91
    -    <td></td>
    
    92
    -    <td>-O</td>
    
    93
    -    <td></td>
    
    94
    -    <td>-O</td>
    
    95
    -    <td></td>
    
    96
    -  </tr>
    
    97 85
       <tr>
    
    98 86
         <th>perf</td>
    
    99 87
         <td> Yes (on supported platforms) </td>
    
    ... ... @@ -367,11 +355,4 @@ information. The following table lists ways that are built in different flavours
    367 355
         <td>debug<br>threaded<br>threadedDebug<br>debugDynamic<br>threadedDynamic<br>threadedDebugDynamic</td>
    
    368 356
         <td>debug<br>threaded<br>threadedDebug<br>debugDynamic<br>threadedDynamic<br>threadedDebugDynamic</td>
    
    369 357
     </tr>
    
    370
    -<tr>
    
    371
    -    <th>quickest</th>
    
    372
    -    <td>vanilla</td>
    
    373
    -    <td>vanilla</td>
    
    374
    -    <td>vanilla<br>threaded</td>
    
    375
    -    <td>vanilla<br>threaded</td>
    
    376
    -</tr>
    
    377 358
     </table>

  • hadrian/doc/make.md
    ... ... @@ -80,15 +80,15 @@ time you fire up a build. This is not possible with the Make build system.
    80 80
       build _build/stage1/lib/package.conf.d/text-1.2.3.0.conf # OR actual path
    
    81 81
       ```
    
    82 82
     
    
    83
    -- Building with a particular flavour (e.g `quickest`)
    
    83
    +- Building with a particular flavour (e.g `quick`)
    
    84 84
     
    
    85 85
       ``` sh
    
    86 86
       # Make
    
    87
    -  echo "BuildFlavour=quickest" >> mk/build.mk
    
    87
    +  echo "BuildFlavour=quick" >> mk/build.mk
    
    88 88
       make
    
    89 89
     
    
    90 90
       # Hadrian
    
    91
    -  build --flavour=quickest
    
    91
    +  build --flavour=quick
    
    92 92
       ```
    
    93 93
       See [flavours documentation](https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/flavours.md) for info on flavours.
    
    94 94
     
    

  • hadrian/doc/windows.md
    ... ... @@ -20,7 +20,7 @@ stack exec -- pacman -S autoconf automake-wrapper make patch python tar --noconf
    20 20
     stack build
    
    21 21
     
    
    22 22
     # Build GHC
    
    23
    -stack exec hadrian -- --directory ".." -j --flavour=quickest
    
    23
    +stack exec hadrian -- --directory ".." -j --flavour=quick
    
    24 24
     
    
    25 25
     # Test GHC
    
    26 26
     cd ..
    
    ... ... @@ -28,7 +28,7 @@ _build\stage1\bin\ghc -e 1+2
    28 28
     ```
    
    29 29
     
    
    30 30
     The entire process should take about 20 minutes. Note, this will build GHC
    
    31
    -without optimisations. If you need an optimised GHC, drop the `--flavour=quickest`
    
    31
    +without optimisations. If you need an optimised GHC, drop the `--flavour=quick`
    
    32 32
     flag from the build command line (this will slow down the build to about an hour).
    
    33 33
     
    
    34 34
     These are currently not the
    
    ... ... @@ -37,7 +37,7 @@ but are much simpler and may also be more robust.
    37 37
     
    
    38 38
     The `stack build` and `stack exec hadrian` commands can be replaced by an
    
    39 39
     invocation of Hadrian's Stack-based build script:
    
    40
    -`build-stack.bat -j --flavour=quickest`. Use this script if you plan to work on
    
    40
    +`build-stack.bat -j --flavour=quick`. Use this script if you plan to work on
    
    41 41
     Hadrian and/or rebuild GHC often.
    
    42 42
     
    
    43 43
     ## Prerequisites
    

  • hadrian/hadrian.cabal
    ... ... @@ -125,7 +125,6 @@ executable hadrian
    125 125
                            , Settings.Flavours.Performance
    
    126 126
                            , Settings.Flavours.Quick
    
    127 127
                            , Settings.Flavours.QuickCross
    
    128
    -                       , Settings.Flavours.Quickest
    
    129 128
                            , Settings.Flavours.Validate
    
    130 129
                            , Settings.Flavours.Release
    
    131 130
                            , Settings.Packages
    

  • hadrian/src/CommandLine.hs
    ... ... @@ -281,7 +281,7 @@ optDescrs =
    281 281
         , Option ['o'] ["build-root"] (ReqArg readBuildRoot "BUILD_ROOT")
    
    282 282
           "Where to store build artifacts. (Default _build)."
    
    283 283
         , Option [] ["flavour"] (OptArg readFlavour "FLAVOUR")
    
    284
    -      "Build flavour (Default, Devel1, Devel2, Perf, Prof, Quick or Quickest)."
    
    284
    +      "Build flavour (Default, Devel1, Devel2, Perf, Prof or Quick)."
    
    285 285
         , Option [] ["freeze1"] (NoArg readFreeze1)
    
    286 286
           "Freeze Stage1 GHC."
    
    287 287
         , Option [] ["freeze2"] (NoArg readFreeze2)
    

  • hadrian/src/Flavour.hs
    ... ... @@ -531,7 +531,7 @@ It now also offers a more "old-school" interface, in the form of
    531 531
     @foo.bar.baz = v@ or @foo.bar.baz += v@ expressions, that one can
    
    532 532
     pass on the command line that invokes hadrian:
    
    533 533
     
    
    534
    -> $ hadrian/build --flavour=quickest -j "stage1.ghc-bin.ghc.link.opts += -v3"
    
    534
    +> $ hadrian/build --flavour=quick -j "stage1.ghc-bin.ghc.link.opts += -v3"
    
    535 535
     
    
    536 536
     or in a file at <build root>/hadrian.settings, where <build root>
    
    537 537
     is the build root to be used for the build, which is _build by default.
    

  • hadrian/src/Settings.hs
    ... ... @@ -19,7 +19,6 @@ import Settings.Flavours.Development
    19 19
     import Settings.Flavours.GhcInGhci
    
    20 20
     import Settings.Flavours.Performance
    
    21 21
     import Settings.Flavours.Quick
    
    22
    -import Settings.Flavours.Quickest
    
    23 22
     import Settings.Flavours.QuickCross
    
    24 23
     import Settings.Flavours.Validate
    
    25 24
     import Settings.Flavours.Release
    
    ... ... @@ -55,7 +54,6 @@ hadrianFlavours =
    55 54
         , developmentFlavour Stage2, performanceFlavour
    
    56 55
         , releaseFlavour
    
    57 56
         , quickFlavour, quickValidateFlavour, quickDebugFlavour
    
    58
    -    , quickestFlavour
    
    59 57
         , quickCrossFlavour
    
    60 58
         , ghcInGhciFlavour, validateFlavour, slowValidateFlavour
    
    61 59
         ]
    
    ... ... @@ -69,6 +67,10 @@ hadrianFlavours =
    69 67
     flavour :: Action Flavour
    
    70 68
     flavour = do
    
    71 69
         flavourName <- fromMaybe userDefaultFlavour <$> cmdFlavour
    
    70
    +    when ("quickest" `isPrefixOf` flavourName) $
    
    71
    +      fail $ "The `quickest` flavour has been deprecated. Use `quick` instead.\n"
    
    72
    +          ++ "Skip building dynamic libraries with `quick+no_dynamic_libs`\n"
    
    73
    +          ++ "to get closer to the old quickest behaviour."
    
    72 74
         kvs <- userSetting ([] :: [KeyVal])
    
    73 75
         let flavours = hadrianFlavours ++ userFlavours
    
    74 76
             (settingErrs, tweak) = applySettings kvs
    

  • hadrian/src/Settings/Flavours/Quickest.hs deleted
    1
    -module Settings.Flavours.Quickest (quickestFlavour) where
    
    2
    -
    
    3
    -import Expression
    
    4
    -import Flavour
    
    5
    -import {-# SOURCE #-} Settings.Default
    
    6
    -
    
    7
    --- Please update doc/flavours.md when changing this file.
    
    8
    -quickestFlavour :: Flavour
    
    9
    -quickestFlavour = disableDynamicLibs $ disableProfiledLibs $ defaultFlavour
    
    10
    -    { name        = "quickest"
    
    11
    -    , extraArgs        = quickestArgs
    
    12
    -    }
    
    13
    -
    
    14
    -quickestArgs :: Args
    
    15
    -quickestArgs = sourceArgs SourceArgs
    
    16
    -    { hsDefault  = mconcat $
    
    17
    -        [ pure ["-O0", "+RTS", "-O64M", "-RTS"]
    
    18
    -        ]
    
    19
    -    , hsLibrary  = mempty
    
    20
    -    , hsCompiler = stage0 ? arg "-O"
    
    21
    -    , hsGhc      = stage0 ? arg "-O" }

  • testsuite/tests/perf/compiler/all.T
    ... ... @@ -192,7 +192,6 @@ test ('T13386',
    192 192
     # Performance test for lookups in the family application cache
    
    193 193
     test('FamAppCachePerf',
    
    194 194
          [ only_ways(['normal'])
    
    195
    -     , collect_compiler_residency(20)
    
    196 195
          , collect_compiler_stats('bytes allocated',2)
    
    197 196
          ],
    
    198 197
          compile,
    

  • testsuite/tests/simplCore/should_run/T27705.hs
    1
    +module Main where
    
    2
    +
    
    3
    +import T27705_Inst
    
    4
    +
    
    5
    +-- The dictionaries (D1/D2) are mutually recursive. We have to watch
    
    6
    +-- out for the specializer looping on them. This was first detected in #22802
    
    7
    +-- but no test was added, which caused it to break again #27705 :(
    
    8
    +main :: IO ()
    
    9
    +main = print (b (3 :: Int))

  • testsuite/tests/simplCore/should_run/T27705.stdout
    1
    +42

  • testsuite/tests/simplCore/should_run/T27705_Inst.hs
    1
    +{-# LANGUAGE UndecidableInstances, UndecidableSuperClasses, FlexibleInstances #-}
    
    2
    +module T27705_Inst where
    
    3
    +
    
    4
    +-- The two dictionaries are mutually recursive, and we have to ensure the specialiser
    
    5
    +-- doesn't loop when it's peaking through their unfoldings.
    
    6
    +class D2 a => D1 a
    
    7
    +class D1 a => D2 a
    
    8
    +instance D2 Int => D1 Int
    
    9
    +instance D1 Int => D2 Int
    
    10
    +
    
    11
    +{-# NOINLINE b #-}
    
    12
    +b :: D1 a => a -> Int
    
    13
    +b _ = 42

  • testsuite/tests/simplCore/should_run/all.T
    ... ... @@ -123,3 +123,5 @@ test('T24359b', normal, compile_and_run, ['-O'])
    123 123
     test('T23429', normal, compile_and_run, ['-O'])
    
    124 124
     test('T27071', normal, compile_and_run, ['-O -fworker-wrapper-cbv'])
    
    125 125
     test('T27005', [], multimod_compile_and_run, ['T27005', '-O'])
    
    126
    +test('T27705', [extra_hc_opts('+RTS -M500M -RTS')], multimod_compile_and_run,
    
    127
    +     ['T27705', '-O2 -fexpose-all-unfoldings'])

  • utils/ghc-toolchain/src/GHC/Toolchain/Target.hs
    ... ... @@ -199,7 +199,7 @@ tgtSupportsSMP Target{..} = do
    199 199
     -- 5. The testsuite driver will use dyn way for TH/ghci tests even
    
    200 200
     --    when host GHC is static.
    
    201 201
     -- 6. TH/ghci doesn't work if stage1 is built without shared libraries
    
    202
    ---    (e.g. quickest/fully_static).
    
    202
    +--    (e.g. no_dynamic_libs/fully_static).
    
    203 203
     tgtRTSLinkerOnlySupportsSharedLibs :: Target -> Bool
    
    204 204
     tgtRTSLinkerOnlySupportsSharedLibs Target{tgtArchOs} =
    
    205 205
       archOS_arch tgtArchOs `elem`