Sven Tennie pushed to branch wip/supersven/refactor-system-cxx-std-lib-hadrian-rules at Glasgow Haskell Compiler / GHC

Commits:

17 changed files:

Changes:

  • changelog.d/T27261
    1
    +section: compiler
    
    2
    +issues: #27261
    
    3
    +mrs: !16084
    
    4
    +synopsis:
    
    5
    +  Avoid a crash in ``mkDupableContWithDmds`` when given empty demands
    
    6
    +description:
    
    7
    +  The case of an empty list of remaining argument demands is now explicitly
    
    8
    +  handled by trimming the simplifier continuation, to avoid a compiler crash
    
    9
    +  of the form ``Non-exhaustive patterns in dmd : cont_dmds`` or ``expectNonEmpty``
    
    10
    +  in ``mkDupableContWithDmds``.

  • changelog.d/hadrian-system-cxx-std-lib-25303
    1
    +section: packaging
    
    2
    +synopsis: Fix Hadrian rules for system-cxx-std-lib package dependency
    
    3
    +issues: #25303
    
    4
    +mrs: !16013
    
    5
    +description: {
    
    6
    +  Hadrian's handling of the ``system-cxx-std-lib`` virtual package has been
    
    7
    +  fixed and made more uniform.
    
    8
    +
    
    9
    +  Previously, ``text`` had an ad-hoc rule outside of ``configurePackage`` to
    
    10
    +  declare a dependency on ``system-cxx-std-lib``, the dependency was not
    
    11
    +  discovered from cabal files, and the package database was not recached after
    
    12
    +  the ``.conf`` file was generated.
    
    13
    +
    
    14
    +  The dependency is now read from cabal files via a new
    
    15
    +  ``dependsOnSystemCxxStdLib`` field in ``PackageData``, and the ``.conf`` file
    
    16
    +  is needed inside ``configurePackage`` alongside all other package
    
    17
    +  dependencies, consistent with how every other package is handled.
    
    18
    +}

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -62,6 +62,7 @@ import GHC.Types.Var ( isTyCoVar )
    62 62
     import GHC.Builtin.Types.Prim( realWorldStatePrimTy )
    
    63 63
     import GHC.Builtin.Names( runRWKey, seqHashKey )
    
    64 64
     
    
    65
    +import qualified GHC.Data.List.Infinite as Inf
    
    65 66
     import GHC.Data.Maybe   ( isNothing, orElse, mapMaybe )
    
    66 67
     import GHC.Data.FastString
    
    67 68
     import GHC.Unit.Module ( moduleName )
    
    ... ... @@ -2444,24 +2445,9 @@ rebuildCall env arg_info _cont
    2444 2445
     
    
    2445 2446
     ---------- Bottoming applications --------------
    
    2446 2447
     rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont
    
    2447
    -  -- When we run out of strictness args, it means
    
    2448
    -  -- that the call is definitely bottom; see GHC.Core.Opt.Simplify.Utils.mkArgInfo
    
    2449
    -  -- Then we want to discard the entire strict continuation.  E.g.
    
    2450
    -  --    * case (error "hello") of { ... }
    
    2451
    -  --    * (error "Hello") arg
    
    2452
    -  --    * f (error "Hello") where f is strict
    
    2453
    -  --    etc
    
    2454
    -  -- Then, especially in the first of these cases, we'd like to discard
    
    2455
    -  -- the continuation, leaving just the bottoming expression.  But the
    
    2456
    -  -- type might not be right, so we may have to add a coerce.
    
    2457
    -  | not (contIsTrivial cont)     -- Only do this if there is a non-trivial
    
    2458
    -                                 -- continuation to discard, else we do it
    
    2459
    -                                 -- again and again!
    
    2460
    -  = seqType cont_ty `seq`        -- See Note [Avoiding space leaks in OutType]
    
    2461
    -    return (emptyFloats env, castBottomExpr res cont_ty)
    
    2462
    -  where
    
    2463
    -    res     = argInfoExpr fun rev_args
    
    2464
    -    cont_ty = contResultType cont
    
    2448
    +  -- When we run out of demands, it means that the call is definitely bottom.
    
    2449
    +  -- See (TC2) in Note [Trimming the continuation for bottoming functions]
    
    2450
    +  = rebuild env (argInfoExpr fun rev_args) (mkBottomCont cont)
    
    2465 2451
     
    
    2466 2452
     ---------- Simplify type applications --------------
    
    2467 2453
     rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont })
    
    ... ... @@ -4045,6 +4031,41 @@ When we have
    4045 4031
     then we can just duplicate those alts because the A and C cases
    
    4046 4032
     will disappear immediately.  This is more direct than creating
    
    4047 4033
     join points and inlining them away.  See #4930.
    
    4034
    +
    
    4035
    +Note [Trimming the continuation for bottoming functions]
    
    4036
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    4037
    +Suppose
    
    4038
    +   f :: Int -> Int -> Int
    
    4039
    +   f x = error "urk"
    
    4040
    +
    
    4041
    +   foo = f 3 4
    
    4042
    +
    
    4043
    +f's demand signature say "after one arg I return bottom".  We can drop
    
    4044
    +the remaining arguments, thus
    
    4045
    +
    
    4046
    +   foo = case f 3 of {}
    
    4047
    +
    
    4048
    +This trimming can also be done with other continuations:
    
    4049
    +   * case (error "hello") of { ... }
    
    4050
    +   * f (error "Hello") where f is strict
    
    4051
    +   etc
    
    4052
    +
    
    4053
    +We implement the trimming in three parts:
    
    4054
    +
    
    4055
    +(TC1) In `mkArgInfo`, for a bottoming function, we make a list of `RemainingArgDmds`
    
    4056
    +  with a finite list of elements (in the example above, just one).
    
    4057
    +
    
    4058
    +  For comparison, note that, for non-bottoming functions, the `RemainingArgDmds`
    
    4059
    +  always finishes with an infinite list of `topDmd`.
    
    4060
    +
    
    4061
    +(TC2) In `rebuildCall`, when we run out of `RemainingArgDmds` we discard the
    
    4062
    +  remaining continuation.
    
    4063
    +
    
    4064
    +  After discarding the continuation, the types might not match, in which case
    
    4065
    +  we leave behind a (case <hole> of {}) wrapper.  See the call to `mkBottomCont`.
    
    4066
    +
    
    4067
    +(TC3) In `mkDupableContWithDmds`, we similarly discard the continuation when
    
    4068
    +  we run out of `RemainingArgDmds`.
    
    4048 4069
     -}
    
    4049 4070
     
    
    4050 4071
     --------------------
    
    ... ... @@ -4079,10 +4100,10 @@ mkDupableCont env cont
    4079 4100
       = mkDupableContWithDmds (zapSubstEnv env) (repeat topDmd) cont
    
    4080 4101
     
    
    4081 4102
     mkDupableContWithDmds
    
    4082
    -   :: SimplEnvIS  -> [Demand]  -- Demands on arguments; always infinite
    
    4103
    +   :: SimplEnvIS -> RemainingArgDmds
    
    4083 4104
        -> SimplCont -> SimplM ( SimplFloats, SimplCont)
    
    4084 4105
     
    
    4085
    -mkDupableContWithDmds env _ cont
    
    4106
    +mkDupableContWithDmds env remaining_dmds cont
    
    4086 4107
       -- Check the invariant
    
    4087 4108
       | assertPpr (checkSimplEnvIS env) (pprBadSimplEnvIS env) False
    
    4088 4109
       = pprPanic "mkDupableContWithDmds" empty
    
    ... ... @@ -4090,6 +4111,13 @@ mkDupableContWithDmds env _ cont
    4090 4111
       | contIsDupable cont
    
    4091 4112
       = return (emptyFloats env, cont)
    
    4092 4113
     
    
    4114
    +  -- No more demands => function is definitely bottom
    
    4115
    +  --                 => simply trim the continuation
    
    4116
    +  -- c.f. the null-demands case in `rebuildCall`
    
    4117
    +  -- See (TC3) in Note [Trimming the continuation for bottoming functions]
    
    4118
    +  | null remaining_dmds
    
    4119
    +  = return (emptyFloats env, mkBottomCont cont)
    
    4120
    +
    
    4093 4121
     mkDupableContWithDmds _ _ (Stop {}) = panic "mkDupableCont"     -- Handled by previous eqn
    
    4094 4122
     
    
    4095 4123
     mkDupableContWithDmds env dmds (CastIt { sc_co = co, sc_opt = opt, sc_cont = cont })
    
    ... ... @@ -4134,7 +4162,8 @@ mkDupableContWithDmds env _
    4134 4162
       , thumbsUpPlanA cont
    
    4135 4163
       = -- Use Plan A of Note [Duplicating StrictArg]
    
    4136 4164
     --    pprTrace "Using plan A" (ppr (ai_fun fun) $$ text "args" <+> ppr (ai_args fun) $$ text "cont" <+> ppr cont) $
    
    4137
    -    do { let _ :| dmds = expectNonEmpty $ ai_dmds fun
    
    4165
    +    do { let _ :| dmds = expectNonEmpty (ai_dmds fun)   -- See Invariant of StrictArg;
    
    4166
    +                                                        -- ai_dmds is never empty
    
    4138 4167
            ; (floats1, cont')  <- mkDupableContWithDmds env dmds cont
    
    4139 4168
                                   -- Use the demands from the function to add the right
    
    4140 4169
                                   -- demand info on any bindings we make for further args
    
    ... ... @@ -4180,7 +4209,10 @@ mkDupableContWithDmds env dmds
    4180 4209
             --              let a = ...arg...
    
    4181 4210
             --              in [...hole...] a
    
    4182 4211
             -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable
    
    4183
    -    do  { let dmd:|cont_dmds = expectNonEmpty dmds
    
    4212
    +    do  { let dmd:|cont_dmds =
    
    4213
    +                -- We took care to handle an empty demand list at the start,
    
    4214
    +                -- ensuring this call to 'expectNonEmpty' does not panic (#27261).
    
    4215
    +                expectNonEmpty dmds
    
    4184 4216
             ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont
    
    4185 4217
             ; let env' = env `setInScopeFromF` floats1
    
    4186 4218
             ; arg' <- simplArg env' Nothing hole_ty se arg arg_mco
    
    ... ... @@ -4251,7 +4283,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty
    4251 4283
            ; let arg_info = ArgInfo { ai_fun   = join_bndr
    
    4252 4284
                                     , ai_rules = [], ai_args  = []
    
    4253 4285
                                     , ai_encl  = False, ai_dmds  = repeat topDmd
    
    4254
    -                                , ai_discs = repeat 0 }
    
    4286
    +                                , ai_discs = Inf.repeat 0 }
    
    4255 4287
            ; return ( addJoinFloats (emptyFloats env) $
    
    4256 4288
                       unitJoinFloat                   $
    
    4257 4289
                       NonRec join_bndr                $
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -25,13 +25,13 @@ module GHC.Core.Opt.Simplify.Utils (
    25 25
             StaticEnv(..),
    
    26 26
             isSimplified, contIsStop,
    
    27 27
             contIsDupable, contResultType, contHoleType, contHoleScaling,
    
    28
    -        contIsTrivial, contArgs, contIsRhs,
    
    28
    +        contIsTrivial, contArgs, contIsRhs, mkBottomCont,
    
    29 29
             hasArgs, countArgs, contOutArgs, dropContArgs,
    
    30 30
             mkBoringStop, mkRhsStop, mkLazyArgStop,
    
    31 31
             interestingCallContext,
    
    32 32
     
    
    33 33
             -- ArgInfo
    
    34
    -        ArgInfo(..), ArgSpec(..), mkArgInfo,
    
    34
    +        ArgInfo(..), ArgSpec(..), RemainingArgDmds, mkArgInfo,
    
    35 35
             addValArgTo, addTyArgTo,
    
    36 36
             argInfoExpr, argSpecArg,
    
    37 37
             pushOutArgs, pushArgSpecs,
    
    ... ... @@ -54,8 +54,10 @@ import GHC.Core.Opt.Stats ( Tick(..) )
    54 54
     import qualified GHC.Core.Subst
    
    55 55
     import GHC.Core.Ppr
    
    56 56
     import GHC.Core.TyCo.Ppr ( pprParendType )
    
    57
    +import GHC.Core.TyCo.Compare ( eqTypeIgnoringMultiplicity )
    
    57 58
     import GHC.Core.FVs
    
    58 59
     import GHC.Core.Utils
    
    60
    +import GHC.Core.Make( mkWildValBinder )
    
    59 61
     import GHC.Core.Opt.Arity
    
    60 62
     import GHC.Core.Unfold
    
    61 63
     import GHC.Core.Unfold.Make
    
    ... ... @@ -75,6 +77,8 @@ import GHC.Types.Var.Set
    75 77
     import GHC.Types.Basic
    
    76 78
     import GHC.Types.Name.Env
    
    77 79
     
    
    80
    +import GHC.Data.List.Infinite ( Infinite(..) )
    
    81
    +import qualified GHC.Data.List.Infinite as Inf
    
    78 82
     import GHC.Data.OrdList ( isNilOL )
    
    79 83
     import GHC.Data.FastString ( fsLit )
    
    80 84
     
    
    ... ... @@ -205,10 +209,10 @@ data SimplCont
    205 209
     
    
    206 210
       | StrictArg           -- (StrictArg (f e1 ..en) K)[e] = K[ f e1 .. en e ]
    
    207 211
           { sc_dup :: DupFlag
    
    208
    -      , sc_fun  :: ArgInfo     -- Specifies f, e1..en, Whether f has rules, etc
    
    212
    +      , sc_fun  :: ArgInfo     -- Specifies f, e1..en, whether f has rules, etc
    
    209 213
                                    --     plus demands and discount flags for *this* arg
    
    210 214
                                    --          and further args
    
    211
    -                               --     So ai_dmds and ai_discs are never empty
    
    215
    +                               --     Invariant: ai_dmds and ai_discs are never empty
    
    212 216
           , sc_fun_ty :: OutType   -- Type of the function (f e1 .. en),
    
    213 217
                                    -- presumably (arg_ty -> res_ty)
    
    214 218
                                    -- where res_ty is expected by sc_cont
    
    ... ... @@ -348,32 +352,41 @@ doesn't matter because we'll never compute them all.
    348 352
     
    
    349 353
     data ArgInfo
    
    350 354
       = ArgInfo {
    
    351
    -        ai_fun   :: OutId,      -- The function
    
    352
    -        ai_args  :: [ArgSpec],  -- ...applied to these args (which are in *reverse* order)
    
    355
    +        ai_fun   :: OutId,      -- ^ The function
    
    356
    +        ai_args  :: [ArgSpec],  -- ^ ...applied to these args (which are in *reverse* order)
    
    353 357
                                     -- NB: all these argumennts are already simplified
    
    354 358
     
    
    355
    -        ai_rules :: [CoreRule], -- Rules for this function
    
    356
    -        ai_encl  :: Bool,       -- Flag saying whether this function
    
    357
    -                                -- or an enclosing one has rules (recursively)
    
    358
    -                                --      True => be keener to inline in all args
    
    359
    +        ai_rules :: [CoreRule], -- ^ Rules for this function
    
    360
    +        ai_encl  :: Bool,
    
    361
    +          -- ^ Flag saying whether this function or an enclosing one has rules
    
    362
    +          -- (recursively)
    
    363
    +          --
    
    364
    +          -- @True@ means: be keener to inline in all args
    
    359 365
     
    
    360
    -        ai_dmds :: [Demand],    -- Demands on remaining value arguments (beyond ai_args)
    
    361
    -                                --   Usually infinite, but if it is finite it guarantees
    
    362
    -                                --   that the function diverges after being given
    
    363
    -                                --   that number of args
    
    366
    +        ai_dmds :: RemainingArgDmds,
    
    367
    +          -- ^ Demands on remaining value arguments (beyond 'ai_args')
    
    364 368
     
    
    365
    -        ai_discs :: [Int]       -- Discounts for remaining value arguments (beyond ai_args)
    
    366
    -                                --   non-zero => be keener to inline
    
    367
    -                                --   Always infinite
    
    369
    +        ai_discs :: Infinite Int
    
    370
    +          -- ^ Discounts for remaining value arguments (beyond 'ai_args')
    
    371
    +          --
    
    372
    +          -- A non-zero value means: be keener to inline
    
    368 373
         }
    
    369 374
     
    
    370
    -data ArgSpec
    
    371
    -  = ValArg { as_dmd  :: Demand        -- Demand placed on this argument
    
    372
    -           , as_arg  :: OutExpr       -- Apply to this (coercion or value); c.f. ApplyToVal
    
    373
    -           , as_hole_ty :: OutType }  -- Type of the function (presumably t1 -> t2)
    
    375
    +-- | 'RemainingArgDmds' gives the demands on any remaining value arguments.
    
    376
    +--
    
    377
    +-- It is usually infinite (with 'topDmd's in the tail), but if it is finite it
    
    378
    +-- guarantees that the function diverges after being applied to that number
    
    379
    +-- of arguments.
    
    380
    +type RemainingArgDmds = [Demand]
    
    374 381
     
    
    375
    -  | TyArg { as_arg_ty  :: OutType     -- Apply to this type; c.f. ApplyToTy
    
    376
    -          , as_hole_ty :: OutType }   -- Type of the function (presumably forall a. blah)
    
    382
    +data ArgSpec
    
    383
    +  -- | A value argument
    
    384
    +  = ValArg { as_dmd  :: Demand        -- ^ Demand placed on this argument
    
    385
    +           , as_arg  :: OutExpr       -- ^ Apply to this (coercion or value); c.f. 'ApplyToVal'
    
    386
    +           , as_hole_ty :: OutType }  -- ^ Type of the function (presumably @t1 -> t2@ for 'ValArg' or @forall a. blah@ for 'TyArg')
    
    387
    +  -- | A type argument
    
    388
    +  | TyArg { as_arg_ty  :: OutType     -- ^ Apply to this type; c.f. 'ApplyToTy'
    
    389
    +          , as_hole_ty :: OutType }   -- ^ Type of the function (presumably @t1 -> t2@ for 'ValArg' or @forall a. blah@ for 'TyArg')
    
    377 390
     
    
    378 391
     instance Outputable ArgInfo where
    
    379 392
       ppr (ArgInfo { ai_fun = fun, ai_args = args, ai_dmds = dmds, ai_rules = rules })
    
    ... ... @@ -389,7 +402,7 @@ instance Outputable ArgSpec where
    389 402
     
    
    390 403
     addValArgTo :: ArgInfo ->  OutExpr -> OutType -> ArgInfo
    
    391 404
     addValArgTo ai arg hole_ty
    
    392
    -  | ArgInfo { ai_dmds = dmd:dmds, ai_discs = _:discs } <- ai
    
    405
    +  | ArgInfo { ai_dmds = dmd:dmds, ai_discs = Inf _ discs } <- ai
    
    393 406
           -- Pop the top demand and and discounts off
    
    394 407
       , let arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty, as_dmd = dmd }
    
    395 408
       = ai { ai_args    = arg_spec : ai_args ai
    
    ... ... @@ -492,12 +505,23 @@ contIsDupable (TickIt _ k) = contIsDupable k
    492 505
     contIsTrivial :: SimplCont -> Bool
    
    493 506
     contIsTrivial (Stop {})                                         = True
    
    494 507
     contIsTrivial (ApplyToTy { sc_cont = k })                       = contIsTrivial k
    
    495
    --- This one doesn't look right.  A value application is not trivial
    
    496
    --- contIsTrivial (ApplyToVal { sc_arg = Coercion _, sc_cont = k }) = contIsTrivial k
    
    497 508
     contIsTrivial (CastIt { sc_cont = k })                          = contIsTrivial k
    
    498 509
     contIsTrivial _                                                 = False
    
    499 510
     
    
    500 511
     -------------------
    
    512
    +contStop :: SimplCont -> SimplCont
    
    513
    +-- ^ Get the 'Stop' at the tail of the continuation
    
    514
    +--
    
    515
    +-- Always returns a continuation of form @(Stop ...)@.
    
    516
    +contStop stop@(Stop {})               = stop
    
    517
    +contStop (CastIt { sc_cont = k })     = contStop k
    
    518
    +contStop (StrictBind { sc_cont = k }) = contStop k
    
    519
    +contStop (StrictArg { sc_cont = k })  = contStop k
    
    520
    +contStop (Select { sc_cont = k })     = contStop k
    
    521
    +contStop (ApplyToTy  { sc_cont = k }) = contStop k
    
    522
    +contStop (ApplyToVal { sc_cont = k }) = contStop k
    
    523
    +contStop (TickIt _ k)                 = contStop k
    
    524
    +
    
    501 525
     contResultType :: SimplCont -> OutType
    
    502 526
     contResultType (Stop ty _ _)                = ty
    
    503 527
     contResultType (CastIt { sc_cont = k })     = contResultType k
    
    ... ... @@ -651,6 +675,35 @@ contEvalContext bndrs cont = go cont
    651 675
         -- Perhaps reconstruct the demand on the scrutinee by looking at field
    
    652 676
         -- and case binder dmds, see addCaseBndrDmd. No priority right now.
    
    653 677
     
    
    678
    +-------------------
    
    679
    +mkBottomCont ::SimplCont -> SimplCont
    
    680
    +-- ^ Given a continuation `cont`, return a `cont` /of the same type/,
    
    681
    +-- looking like @(case \<hole\> of {})@.
    
    682
    +--
    
    683
    +-- This is used when we are going to fill in the @<hole>@ with bottom.
    
    684
    +-- See (TC2,3) in Note [Trimming the continuation for bottoming functions]
    
    685
    +--
    
    686
    +-- Don't bother to trim, making a @case <hole> of {}@, if we have only
    
    687
    +-- an essentially-trivial continuation; e.g. @(<hole> \@ty |> co)@.
    
    688
    +mkBottomCont cont = go cont
    
    689
    +  where
    
    690
    +    go k@(Stop {})                    = k
    
    691
    +    go (TickIt t k')                  = TickIt t (go k')
    
    692
    +    go k@(CastIt    { sc_cont = k' }) = k { sc_cont = go k' }
    
    693
    +    go k@(ApplyToTy { sc_cont = k' }) = k { sc_cont = go k' }
    
    694
    +    go k@(Select { sc_alts = [], sc_cont = Stop {} }) = k  -- Optimisation only
    
    695
    +    go k | Stop res_ty _ _ <- stop_cont
    
    696
    +         , hole_ty `eqTypeIgnoringMultiplicity` res_ty
    
    697
    +         = stop_cont
    
    698
    +         | otherwise
    
    699
    +         = Select { sc_alts = []
    
    700
    +                  , sc_bndr = mkWildValBinder OneTy hole_ty
    
    701
    +                  , sc_env  = Simplified OkDup
    
    702
    +                  , sc_cont = stop_cont }
    
    703
    +         where
    
    704
    +           hole_ty   = contHoleType k
    
    705
    +           stop_cont = contStop k
    
    706
    +
    
    654 707
     -------------------
    
    655 708
     mkArgInfo :: SimplEnv -> Id -> [CoreRule] -> SimplCont -> ArgInfo
    
    656 709
     mkArgInfo env fun rules_for_fun cont
    
    ... ... @@ -672,16 +725,17 @@ mkArgInfo env fun rules_for_fun cont
    672 725
     
    
    673 726
         fun_has_rules = not (null rules_for_fun)
    
    674 727
     
    
    675
    -    vanilla_discounts, arg_discounts :: [Int]
    
    676
    -    vanilla_discounts = repeat 0
    
    728
    +    vanilla_discounts, arg_discounts :: Infinite Int
    
    729
    +    vanilla_discounts = Inf.repeat 0
    
    677 730
         arg_discounts = case idUnfolding fun of
    
    678 731
                             CoreUnfolding {uf_guidance = UnfIfGoodArgs {ug_args = discounts}}
    
    679
    -                              -> discounts ++ vanilla_discounts
    
    732
    +                              -> discounts Inf.++ vanilla_discounts
    
    680 733
                             _     -> vanilla_discounts
    
    681 734
     
    
    682
    -    vanilla_dmds, arg_dmds :: [Demand]
    
    735
    +    vanilla_dmds :: RemainingArgDmds
    
    683 736
         vanilla_dmds  = repeat topDmd
    
    684 737
     
    
    738
    +    arg_dmds :: RemainingArgDmds
    
    685 739
         arg_dmds
    
    686 740
           | not (seInline env)
    
    687 741
           = vanilla_dmds -- See Note [Do not expose strictness if sm_inline=False]
    
    ... ... @@ -689,26 +743,22 @@ mkArgInfo env fun rules_for_fun cont
    689 743
           = -- add_type_str fun_ty $
    
    690 744
             case splitDmdSig (idDmdSig fun) of
    
    691 745
               (demands, result_info)
    
    692
    -                | not (demands `lengthExceeds` n_val_args)
    
    693
    -                ->      -- Enough args, use the strictness given.
    
    694
    -                        -- For bottoming functions we used to pretend that the arg
    
    695
    -                        -- is lazy, so that we don't treat the arg as an
    
    696
    -                        -- interesting context.  This avoids substituting
    
    697
    -                        -- top-level bindings for (say) strings into
    
    698
    -                        -- calls to error.  But now we are more careful about
    
    699
    -                        -- inlining lone variables, so its ok
    
    700
    -                        -- (see GHC.Core.Op.Simplify.Utils.analyseCont)
    
    701
    -                   if isDeadEndDiv result_info then
    
    702
    -                        demands  -- Finite => result is bottom
    
    703
    -                   else
    
    704
    -                        demands ++ vanilla_dmds
    
    746
    +               | not (demands `lengthExceeds` n_val_args)
    
    747
    +               -> remaining_dmds     -- Enough args, use the strictness given.
    
    705 748
                    | otherwise
    
    706 749
                    -> warnPprTrace True "More demands than arity" (ppr fun <+> ppr (idArity fun)
    
    707 750
                                     <+> ppr n_val_args <+> ppr demands) $
    
    708 751
                       vanilla_dmds      -- Not enough args, or no strictness
    
    709 752
     
    
    710
    -    add_type_strictness :: Type -> [Demand] -> [Demand]
    
    711
    -    -- If the function arg types are strict, record that in the 'strictness bits'
    
    753
    +                where
    
    754
    +                  remaining_dmds :: RemainingArgDmds
    
    755
    +                  -- isDeadEndDiv: if remaining_dmds is finite, result is bottom
    
    756
    +                  -- See (TC1) in Note [Trimming the continuation for bottoming functions]
    
    757
    +                  remaining_dmds | isDeadEndDiv result_info = demands
    
    758
    +                                 | otherwise                = demands ++ vanilla_dmds
    
    759
    +
    
    760
    +    add_type_strictness :: Type -> RemainingArgDmds -> RemainingArgDmds
    
    761
    +    -- If the function arg /types/ are strict, record that in the RemainingArgDmds
    
    712 762
         -- No need to instantiate because unboxed types (which dominate the strict
    
    713 763
         --   types) can't instantiate type variables.
    
    714 764
         -- add_type_strictness is done repeatedly (for each call);
    
    ... ... @@ -915,16 +965,16 @@ the incentive to disappear when we inline `f`!
    915 965
     lazyArgContext :: ArgInfo -> CallCtxt
    
    916 966
     -- Use this for lazy arguments
    
    917 967
     lazyArgContext (ArgInfo { ai_encl = encl_rules, ai_discs = discs })
    
    918
    -  | encl_rules                = RuleArgCtxt
    
    919
    -  | disc:_ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    920
    -  | otherwise                 = BoringCtxt   -- Nothing interesting
    
    968
    +  | encl_rules                    = RuleArgCtxt
    
    969
    +  | Inf disc _ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    970
    +  | otherwise                     = BoringCtxt   -- Nothing interesting
    
    921 971
     
    
    922 972
     strictArgContext :: ArgInfo -> CallCtxt
    
    923 973
     strictArgContext (ArgInfo { ai_encl = encl_rules, ai_discs = discs })
    
    924 974
     -- Use this for strict arguments
    
    925
    -  | encl_rules                = RuleArgCtxt
    
    926
    -  | disc:_ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    927
    -  | otherwise                 = RhsCtxt NonRecursive
    
    975
    +  | encl_rules                    = RuleArgCtxt
    
    976
    +  | Inf disc _ <- discs, disc > 0 = DiscArgCtxt  -- Be keener here
    
    977
    +  | otherwise                     = RhsCtxt NonRecursive
    
    928 978
           -- Why RhsCtxt?  if we see f (g x), and f is strict, we
    
    929 979
           -- want to be a bit more eager to inline g, because it may
    
    930 980
           -- expose an eval (on x perhaps) that can be eliminated or
    

  • hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
    ... ... @@ -81,10 +81,11 @@ parsePackageData pkg = do
    81 81
             sorted  = sort [ C.unPackageName p | C.Dependency p _ _ <- allDeps ]
    
    82 82
             deps    = nubOrd sorted \\ [name]
    
    83 83
             depPkgs = mapMaybe findPackageByName deps
    
    84
    +        cxxStdLib = elem "system-cxx-std-lib" deps
    
    84 85
         return $ PackageData name version
    
    85 86
                              (C.fromShortText (C.synopsis pd))
    
    86 87
                              (C.fromShortText (C.description pd))
    
    87
    -                         depPkgs gpd
    
    88
    +                         depPkgs cxxStdLib gpd
    
    88 89
       where
    
    89 90
         -- Collect an overapproximation of dependencies by ignoring conditionals
    
    90 91
         collectDeps :: Maybe (C.CondTree v [C.Dependency] a) -> [C.Dependency]
    
    ... ... @@ -138,7 +139,9 @@ configurePackage :: Context -> Action ()
    138 139
     configurePackage context@Context {..} = do
    
    139 140
         putProgressInfo $ "| Configure package " ++ quote (pkgName package)
    
    140 141
         gpd     <- pkgGenericDescription package
    
    141
    -    depPkgs <- packageDependencies <$> readPackageData package
    
    142
    +    pd <- readPackageData package
    
    143
    +    let depPkgs = packageDependencies pd
    
    144
    +        needSystemCxxStdLib = dependsOnSystemCxxStdLib pd
    
    142 145
     
    
    143 146
         -- Stage packages are those we have in this stage.
    
    144 147
         stagePkgs <- stagePackages stage
    
    ... ... @@ -157,7 +160,12 @@ configurePackage context@Context {..} = do
    157 160
         -- We'll need those packages in our package database.
    
    158 161
         deps <- sequence [ pkgConfFile (context { package = pkg, iplace = forceBaseAfterGhcInternal pkg })
    
    159 162
                          | pkg <- depPkgs, pkg `elem` stagePkgs ]
    
    160
    -    need $ extraPreConfigureDeps ++ deps
    
    163
    +    -- system-cxx-std-lib is magic.. it doesn't have a cabal file or source code, so we have
    
    164
    +    -- to treat it specially as `pkgConfFile` uses `readPackageData` to compute the version.
    
    165
    +    systemCxxStdLib <- sequence [ systemCxxStdLibConfPath (PackageDbLoc stage iplace) | needSystemCxxStdLib ]
    
    166
    +    need $ extraPreConfigureDeps
    
    167
    +            ++ deps
    
    168
    +            ++ systemCxxStdLib
    
    161 169
     
    
    162 170
         -- Figure out what hooks we need.
    
    163 171
         let configureFile = replaceFileName (pkgCabalFile package) "configure"
    

  • hadrian/src/Hadrian/Haskell/Cabal/Type.hs
    ... ... @@ -30,6 +30,7 @@ data PackageData = PackageData
    30 30
         , synopsis                  :: String
    
    31 31
         , description               :: String
    
    32 32
         , packageDependencies       :: [Package]
    
    33
    +    , dependsOnSystemCxxStdLib  :: Bool
    
    33 34
         , genericPackageDescription :: GenericPackageDescription
    
    34 35
         } deriving (Eq, Generic, Show)
    
    35 36
     
    

  • hadrian/src/Main.hs
    ... ... @@ -63,7 +63,13 @@ main = do
    63 63
         shakeColor <- shouldUseColor
    
    64 64
         let options :: ShakeOptions
    
    65 65
             options = shakeOptions
    
    66
    -            { shakeChange   = ChangeModtimeAndDigest
    
    66
    +            { -- Bump shakeVersion whenever a type stored in the Shake oracle
    
    67
    +              -- changes its Binary representation (e.g. fields added/removed
    
    68
    +              -- from PackageData or other oracle value types). This forces
    
    69
    +              -- Shake to wipe the stale database instead of crashing on
    
    70
    +              -- deserialisation.
    
    71
    +              shakeVersion  = "2"
    
    72
    +            , shakeChange   = ChangeModtimeAndDigest
    
    67 73
                 , shakeFiles    = buildRoot -/- Base.shakeFilesDir
    
    68 74
                 , shakeProgress = Progress.hadrianProgress cwd
    
    69 75
                 , shakeRebuild  = rebuild
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -242,9 +242,6 @@ copyRules = do
    242 242
             prefix -/- "html/**"           <~ return "utils/haddock/haddock-api/resources"
    
    243 243
             prefix -/- "latex/**"          <~ return "utils/haddock/haddock-api/resources"
    
    244 244
     
    
    245
    -        forM_ [Inplace, Final] $ \iplace ->
    
    246
    -          root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- systemCxxStdLibConf %> \file -> do
    
    247
    -            copyFile ("mk" -/- "system-cxx-std-lib-1.0.conf") file
    
    248 245
     
    
    249 246
     generateRules :: Rules ()
    
    250 247
     generateRules = do
    

  • hadrian/src/Rules/Register.hs
    ... ... @@ -6,7 +6,6 @@ module Rules.Register (
    6 6
     
    
    7 7
     import Base
    
    8 8
     import Context
    
    9
    -import Flavour
    
    10 9
     import Oracles.Setting
    
    11 10
     import Hadrian.BuildPath
    
    12 11
     import Hadrian.Expression
    
    ... ... @@ -48,14 +47,6 @@ configurePackageRules = do
    48 47
               isGmp <- (== "gmp") <$> interpretInContext ctx getBignumBackend
    
    49 48
               when isGmp $
    
    50 49
                 need [buildP -/- "include/ghc-gmp.h"]
    
    51
    -        when (pkg == text) $ do
    
    52
    -          simdutf <- textWithSIMDUTF <$> flavour
    
    53
    -          when simdutf $ do
    
    54
    -            -- This is required, otherwise you get Error: hadrian:
    
    55
    -            -- Encountered missing or private dependencies:
    
    56
    -            -- system-cxx-std-lib ==1.0
    
    57
    -            cxxStdLib <- systemCxxStdLibConfPath $ PackageDbLoc stage Inplace
    
    58
    -            need [cxxStdLib]
    
    59 50
             Cabal.configurePackage ctx
    
    60 51
     
    
    61 52
         root -/- "**/autogen/cabal_macros.h" %> \out -> do
    
    ... ... @@ -105,6 +96,12 @@ registerPackageRules rs stage iplace = do
    105 96
                 target (Context stage compiler vanilla iplace) (GhcPkg Recache stage) [] []
    
    106 97
             writeFileLines stamp []
    
    107 98
     
    
    99
    +    -- Special rule for registering system-cxx-std-lib
    
    100
    +    root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- systemCxxStdLibConf %> \file -> do
    
    101
    +        copyFile ("mk" -/- "system-cxx-std-lib-1.0.conf") file
    
    102
    +        buildWithResources rs $
    
    103
    +            target (Context stage compiler vanilla iplace) (GhcPkg Recache stage) [] []
    
    104
    +
    
    108 105
         -- Register a package.
    
    109 106
         root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- "*.conf" %> \conf -> do
    
    110 107
             historyDisable
    

  • libraries/ghc-boot/GHC/Data/ShortByteString.hs
    1
    +module GHC.Data.ShortByteString
    
    2
    +  ( newCStringFromSBS
    
    3
    +  ) where
    
    4
    +
    
    5
    +import Prelude
    
    6
    +
    
    7
    +import qualified Data.ByteString.Short as SBS
    
    8
    +import Foreign
    
    9
    +import Foreign.C
    
    10
    +
    
    11
    +newCStringFromSBS :: SBS.ShortByteString -> IO CString
    
    12
    +newCStringFromSBS sbs =
    
    13
    +  SBS.useAsCStringLen sbs $ \(src, len) -> do
    
    14
    +    dst <- mallocBytes (len + 1)
    
    15
    +    copyBytes dst src len
    
    16
    +    pokeByteOff dst len (0 :: Word8)
    
    17
    +    pure dst

  • libraries/ghc-boot/ghc-boot.cabal.in
    ... ... @@ -51,6 +51,7 @@ Library
    51 51
     
    
    52 52
         exposed-modules:
    
    53 53
                 GHC.BaseDir
    
    54
    +            GHC.Data.ShortByteString
    
    54 55
                 GHC.Data.ShortText
    
    55 56
                 GHC.Data.SizedSeq
    
    56 57
                 GHC.Data.SmallArray
    

  • libraries/ghci/GHCi/Coverage.hs
    ... ... @@ -9,9 +9,9 @@ import Prelude -- See note [Why do we import Prelude here?]
    9 9
     
    
    10 10
     import Control.Exception
    
    11 11
     import Data.ByteString.Short (ShortByteString)
    
    12
    -import qualified Data.ByteString.Short as SBS
    
    13 12
     import Data.Word
    
    14 13
     import Foreign
    
    14
    +import GHC.Data.ShortByteString
    
    15 15
     import GHC.Foreign (CString)
    
    16 16
     import GHC.Utils.Encoding.UTF8 (utf8DecodeShortByteString)
    
    17 17
     import GHCi.ObjLink (lookupSymbol)
    
    ... ... @@ -31,17 +31,19 @@ hpcAddModule ::
    31 31
       -- ^ Name of the ticks array found in the c-stub.
    
    32 32
       IO ()
    
    33 33
     hpcAddModule modlName ticks hash tickboxes = do
    
    34
    -  SBS.useAsCString modlName $ \modlNameLiteral -> do
    
    35
    -    -- we need to find the reference to the ticks array.
    
    36
    -    lookupSymbol tickboxes >>= \ case
    
    37
    -      Nothing -> do
    
    38
    -        -- the symbol is not found, this is a bug!
    
    39
    -        throwIO $ ErrorCall $ "hpcAddModule: failed to find symbol " <> utf8DecodeShortByteString tickboxes
    
    40
    -      Just tickBoxRef -> do
    
    41
    -        -- Calling 'hs_hpc_module' multiple times is safe, it will add the module only once.
    
    42
    -        hpc_register_module modlNameLiteral (fromIntegral ticks) (fromIntegral hash) (castPtr tickBoxRef)
    
    43
    -        -- calling 'hpc_startup' multiple times is safe, it will only be initialised once.
    
    44
    -        hpc_startup
    
    34
    +  -- we need to find the reference to the ticks array.
    
    35
    +  lookupSymbol tickboxes >>= \ case
    
    36
    +    Nothing -> do
    
    37
    +      -- the symbol is not found, this is a bug!
    
    38
    +      throwIO $ ErrorCall $ "hpcAddModule: failed to find symbol " <> utf8DecodeShortByteString tickboxes
    
    39
    +    Just tickBoxRef -> do
    
    40
    +      -- hs_hpc_module stores the module name pointer in the RTS hash table
    
    41
    +      -- until exitHpc, so pass a malloced C string.
    
    42
    +      modlNameLiteral <- newCStringFromSBS modlName
    
    43
    +      -- Calling 'hs_hpc_module' multiple times is safe, it will add the module only once.
    
    44
    +      hpc_register_module modlNameLiteral (fromIntegral ticks) (fromIntegral hash) (castPtr tickBoxRef)
    
    45
    +      -- calling 'hpc_startup' multiple times is safe, it will only be initialised once.
    
    46
    +      hpc_startup
    
    45 47
     
    
    46 48
     foreign import ccall unsafe "hs_hpc_module"
    
    47 49
         hpc_register_module :: CString -> Word32 -> Word32 -> Ptr Word64 -> IO ()
    

  • libraries/ghci/GHCi/Run.hs
    ... ... @@ -37,6 +37,9 @@ import Control.Monad
    37 37
     import Data.ByteString (ByteString)
    
    38 38
     import qualified Data.ByteString.Short.Internal as BS
    
    39 39
     import qualified Data.ByteString.Unsafe as B
    
    40
    +#if defined(PROFILING)
    
    41
    +import GHC.Data.ShortByteString
    
    42
    +#endif
    
    40 43
     import GHC.Exts
    
    41 44
     import qualified GHC.Exts.Heap as Heap
    
    42 45
     import GHC.Stack
    
    ... ... @@ -447,13 +450,6 @@ mkCostCentres mod ccs = do
    447 450
         c_srcspan <- newCStringFromSBS srcspan
    
    448 451
         toRemotePtr <$> c_mkCostCentre c_name c_module c_srcspan
    
    449 452
     
    
    450
    -  newCStringFromSBS sbs = do
    
    451
    -    let len = BS.length sbs
    
    452
    -    buf <- mallocBytes $ len + 1
    
    453
    -    BS.copyToPtr sbs 0 buf (fromIntegral len)
    
    454
    -    pokeByteOff buf len (0 :: Word8)
    
    455
    -    pure buf
    
    456
    -
    
    457 453
     foreign import ccall unsafe "mkCostCentre"
    
    458 454
       c_mkCostCentre :: Ptr CChar -> Ptr CChar -> Ptr CChar -> IO (Ptr CostCentre)
    
    459 455
     #else
    

  • testsuite/tests/perf/compiler/all.T
    ... ... @@ -678,7 +678,7 @@ test ('T18140',
    678 678
           ['-v0 -O'])
    
    679 679
     test('T10421',
    
    680 680
         [ only_ways(['normal']),
    
    681
    -      collect_compiler_runtime(1)
    
    681
    +      collect_compiler_runtime(2) # 1% tolerance was too small (#27289)
    
    682 682
         ],
    
    683 683
         multimod_compile,
    
    684 684
         ['T10421', '-v0 -O'])
    

  • testsuite/tests/simplCore/should_compile/T27261.hs
    1
    +{-# OPTIONS_GHC -fno-full-laziness #-}
    
    2
    +
    
    3
    +module T27261 (foo) where
    
    4
    +
    
    5
    +import T27261_aux (myError)
    
    6
    +
    
    7
    +foo :: [String] -> (() -> Int) -> Int
    
    8
    +foo cs =
    
    9
    +  \ k -> ( case bar of
    
    10
    +             Just str -> let cs2 = case cs of { [] -> cs; _ -> "stack entry" : cs }
    
    11
    +                         in myError cs2 str
    
    12
    +             Nothing -> \ c -> c () )
    
    13
    +         ( \ _ -> k () )
    
    14
    +
    
    15
    +bar :: Maybe String
    
    16
    +bar = Nothing
    
    17
    +{-# NOINLINE bar #-}

  • testsuite/tests/simplCore/should_compile/T27261_aux.hs
    1
    +{-# LANGUAGE BangPatterns #-}
    
    2
    +
    
    3
    +module T27261_aux (myError) where
    
    4
    +
    
    5
    +myError :: [String] -> String -> a
    
    6
    +myError !_ _ = undefined
    
    7
    +{-# NOINLINE myError #-}

  • testsuite/tests/simplCore/should_compile/all.T
    ... ... @@ -601,3 +601,4 @@ test('T25718a', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress
    601 601
     test('T25718b', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
    
    602 602
     test('T25718c', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
    
    603 603
     test('T19166', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all -dno-typeable-binds'])
    
    604
    +test('T27261', [extra_files(['T27261_aux.hs'])], multimod_compile, ['T27261', '-v0 -O'])