Magnus pushed to branch wip/mangoiv/ghc-9.12-bp at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -24,7 +24,7 @@ import GHC.Core.Opt.Simplify.Env
    24 24
     import GHC.Core.Opt.Simplify.Inline
    
    25 25
     import GHC.Core.Opt.Simplify.Utils
    
    26 26
     import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs, scrutOkForBinderSwap, BinderSwapDecision (..) )
    
    27
    -import GHC.Core.Make       ( FloatBind, mkImpossibleExpr, castBottomExpr )
    
    27
    +import GHC.Core.Make       ( FloatBind, mkImpossibleExpr )
    
    28 28
     import qualified GHC.Core.Make
    
    29 29
     import GHC.Core.Coercion hiding ( substCo, substCoVar )
    
    30 30
     import GHC.Core.Reduction
    
    ... ... @@ -2293,24 +2293,14 @@ rebuildCall :: SimplEnv -> ArgInfo -> SimplCont
    2293 2293
     
    
    2294 2294
     ---------- Bottoming applications --------------
    
    2295 2295
     rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_dmds = [] }) cont
    
    2296
    -  -- When we run out of strictness args, it means
    
    2297
    -  -- that the call is definitely bottom; see GHC.Core.Opt.Simplify.Utils.mkArgInfo
    
    2298
    -  -- Then we want to discard the entire strict continuation.  E.g.
    
    2299
    -  --    * case (error "hello") of { ... }
    
    2300
    -  --    * (error "Hello") arg
    
    2301
    -  --    * f (error "Hello") where f is strict
    
    2302
    -  --    etc
    
    2303
    -  -- Then, especially in the first of these cases, we'd like to discard
    
    2304
    -  -- the continuation, leaving just the bottoming expression.  But the
    
    2305
    -  -- type might not be right, so we may have to add a coerce.
    
    2306
    -  | not (contIsTrivial cont)     -- Only do this if there is a non-trivial
    
    2307
    -                                 -- continuation to discard, else we do it
    
    2308
    -                                 -- again and again!
    
    2309
    -  = seqType cont_ty `seq`        -- See Note [Avoiding space leaks in OutType]
    
    2310
    -    return (emptyFloats env, castBottomExpr res cont_ty)
    
    2311
    -  where
    
    2312
    -    res     = argInfoExpr fun rev_args
    
    2313
    -    cont_ty = contResultType cont
    
    2296
    +  -- When we run out of demands, it means that the call is definitely bottom.
    
    2297
    +  -- See (TC2) in Note [Trimming the continuation for bottoming functions]
    
    2298
    +  = rebuild env (argInfoExpr fun rev_args) (mkBottomCont env cont)
    
    2299
    +    -- NOTE(mangoiv): the env passed to mkBottomCont is only relevant for its static part
    
    2300
    +    -- and should not be looked at whatsoever, which is why it should be fine to pass it
    
    2301
    +    -- this way. The reason why we deviate from the original patch is that it was done
    
    2302
    +    -- after a significant refactor we cannot backport.
    
    2303
    +    -- The original patch should be included in `master` as 4a645683ee0bd4421a88cd6ec49b40c6046b041d
    
    2314 2304
     
    
    2315 2305
     ---------- Try inlining, if ai_rewrite = TryInlining --------
    
    2316 2306
     -- In the TryInlining case we try inlining immediately, before simplifying
    
    ... ... @@ -3813,6 +3803,41 @@ When we have
    3813 3803
     then we can just duplicate those alts because the A and C cases
    
    3814 3804
     will disappear immediately.  This is more direct than creating
    
    3815 3805
     join points and inlining them away.  See #4930.
    
    3806
    +
    
    3807
    +Note [Trimming the continuation for bottoming functions]
    
    3808
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3809
    +Suppose
    
    3810
    +   f :: Int -> Int -> Int
    
    3811
    +   f x = error "urk"
    
    3812
    +
    
    3813
    +   foo = f 3 4
    
    3814
    +
    
    3815
    +f's demand signature say "after one arg I return bottom".  We can drop
    
    3816
    +the remaining arguments, thus
    
    3817
    +
    
    3818
    +   foo = case f 3 of {}
    
    3819
    +
    
    3820
    +This trimming can also be done with other continuations:
    
    3821
    +   * case (error "hello") of { ... }
    
    3822
    +   * f (error "Hello") where f is strict
    
    3823
    +   etc
    
    3824
    +
    
    3825
    +We implement the trimming in three parts:
    
    3826
    +
    
    3827
    +(TC1) In `mkArgInfo`, for a bottoming function, we make a list of `RemainingArgDmds`
    
    3828
    +  with a finite list of elements (in the example above, just one).
    
    3829
    +
    
    3830
    +  For comparison, note that, for non-bottoming functions, the `RemainingArgDmds`
    
    3831
    +  always finishes with an infinite list of `topDmd`.
    
    3832
    +
    
    3833
    +(TC2) In `rebuildCall`, when we run out of `RemainingArgDmds` we discard the
    
    3834
    +  remaining continuation.
    
    3835
    +
    
    3836
    +  After discarding the continuation, the types might not match, in which case
    
    3837
    +  we leave behind a (case <hole> of {}) wrapper.  See the call to `mkBottomCont`.
    
    3838
    +
    
    3839
    +(TC3) In `mkDupableContWithDmds`, we similarly discard the continuation when
    
    3840
    +  we run out of `RemainingArgDmds`.
    
    3816 3841
     -}
    
    3817 3842
     
    
    3818 3843
     --------------------
    
    ... ... @@ -3931,7 +3956,7 @@ mkDupableContWithDmds env dmds
    3931 3956
             ; return (floats, ApplyToTy { sc_cont = cont'
    
    3932 3957
                                         , sc_arg_ty = arg_ty, sc_hole_ty = hole_ty }) }
    
    3933 3958
     
    
    3934
    -mkDupableContWithDmds env dmds
    
    3959
    +mkDupableContWithDmds env (dmd : cont_dmds)
    
    3935 3960
         (ApplyToVal { sc_arg = arg, sc_dup = dup, sc_env = se
    
    3936 3961
                     , sc_cont = cont, sc_hole_ty = hole_ty })
    
    3937 3962
       =     -- e.g.         [...hole...] (...arg...)
    
    ... ... @@ -3939,8 +3964,7 @@ mkDupableContWithDmds env dmds
    3939 3964
             --              let a = ...arg...
    
    3940 3965
             --              in [...hole...] a
    
    3941 3966
             -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable
    
    3942
    -    do  { let (dmd:cont_dmds) = dmds   -- Never fails
    
    3943
    -        ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont
    
    3967
    +    do  { (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont
    
    3944 3968
             ; let env' = env `setInScopeFromF` floats1
    
    3945 3969
             ; (_, se', arg') <- simplLazyArg env' dup hole_ty Nothing se arg
    
    3946 3970
             ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg'
    
    ... ... @@ -3954,6 +3978,12 @@ mkDupableContWithDmds env dmds
    3954 3978
                                              -- See Note [StaticEnv invariant] in GHC.Core.Opt.Simplify.Utils
    
    3955 3979
                                   , sc_dup = OkToDup, sc_cont = cont'
    
    3956 3980
                                   , sc_hole_ty = hole_ty }) }
    
    3981
    +mkDupableContWithDmds env dmds cont
    
    3982
    +  -- No more demands => function is definitely bottom
    
    3983
    +  --                 => simply trim the continuation
    
    3984
    +  -- c.f. the null-demands case in `rebuildCall`
    
    3985
    +  -- See (TC3) in Note [Trimming the continuation for bottoming functions]
    
    3986
    +  | [] <- dmds = return (emptyFloats env, mkBottomCont env cont)
    
    3957 3987
     
    
    3958 3988
     mkDupableContWithDmds env _
    
    3959 3989
         (Select { sc_bndr = case_bndr, sc_alts = alts, sc_env = se, sc_cont = cont })
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -24,7 +24,7 @@ module GHC.Core.Opt.Simplify.Utils (
    24 24
             SimplCont(..), DupFlag(..), FromWhat(..), StaticEnv,
    
    25 25
             isSimplified, contIsStop,
    
    26 26
             contIsDupable, contResultType, contHoleType, contHoleScaling,
    
    27
    -        contIsTrivial, contArgs, contIsRhs,
    
    27
    +        contIsTrivial, contArgs, contIsRhs, mkBottomCont,
    
    28 28
             countArgs,
    
    29 29
             mkBoringStop, mkRhsStop, mkLazyArgStop,
    
    30 30
             interestingCallContext,
    
    ... ... @@ -87,6 +87,8 @@ import Control.Monad ( guard, when )
    87 87
     import Data.List        ( sortBy )
    
    88 88
     import Data.Maybe
    
    89 89
     import Data.Graph
    
    90
    +import GHC.Core.TyCo.Compare (eqTypeIgnoringMultiplicity)
    
    91
    +import GHC.Core.Make (mkWildValBinder)
    
    90 92
     
    
    91 93
     {- *********************************************************************
    
    92 94
     *                                                                      *
    
    ... ... @@ -505,6 +507,20 @@ contIsTrivial (ApplyToTy { sc_cont = k }) = contIsTrivial
    505 507
     contIsTrivial (CastIt { sc_cont = k })                          = contIsTrivial k
    
    506 508
     contIsTrivial _                                                 = False
    
    507 509
     
    
    510
    +-------------------
    
    511
    +contStop :: SimplCont -> SimplCont
    
    512
    +-- ^ Get the 'Stop' at the tail of the continuation
    
    513
    +--
    
    514
    +-- Always returns a continuation of form @(Stop ...)@.
    
    515
    +contStop stop@(Stop {})               = stop
    
    516
    +contStop (CastIt { sc_cont = k })     = contStop k
    
    517
    +contStop (StrictBind { sc_cont = k }) = contStop k
    
    518
    +contStop (StrictArg { sc_cont = k })  = contStop k
    
    519
    +contStop (Select { sc_cont = k })     = contStop k
    
    520
    +contStop (ApplyToTy  { sc_cont = k }) = contStop k
    
    521
    +contStop (ApplyToVal { sc_cont = k }) = contStop k
    
    522
    +contStop (TickIt _ k)                 = contStop k
    
    523
    +
    
    508 524
     -------------------
    
    509 525
     contResultType :: SimplCont -> OutType
    
    510 526
     contResultType (Stop ty _ _)                = ty
    
    ... ... @@ -623,6 +639,37 @@ contEvalContext k = case k of
    623 639
         -- Perhaps reconstruct the demand on the scrutinee by looking at field
    
    624 640
         -- and case binder dmds, see addCaseBndrDmd. No priority right now.
    
    625 641
     
    
    642
    +-------------------
    
    643
    +mkBottomCont ::StaticEnv -> SimplCont -> SimplCont
    
    644
    +-- ^ Given a continuation `cont`, return a `cont` /of the same type/,
    
    645
    +-- looking like @(case \<hole\> of {})@.
    
    646
    +--
    
    647
    +-- This is used when we are going to fill in the @<hole>@ with bottom.
    
    648
    +-- See (TC2,3) in Note [Trimming the continuation for bottoming functions]
    
    649
    +--
    
    650
    +-- Don't bother to trim, making a @case <hole> of {}@, if we have only
    
    651
    +-- an essentially-trivial continuation; e.g. @(<hole> \@ty |> co)@.
    
    652
    +mkBottomCont se cont = go cont
    
    653
    +  where
    
    654
    +    go k@(Stop {})                    = k
    
    655
    +    go (TickIt t k')                  = TickIt t (go k')
    
    656
    +    go k@(CastIt    { sc_cont = k' }) = k { sc_cont = go k' }
    
    657
    +    go k@(ApplyToTy { sc_cont = k' }) = k { sc_cont = go k' }
    
    658
    +    go k@(Select { sc_alts = [], sc_cont = Stop {} }) = k  -- Optimisation only
    
    659
    +    go k | Stop res_ty _ _ <- stop_cont
    
    660
    +         , hole_ty `eqTypeIgnoringMultiplicity` res_ty
    
    661
    +         = stop_cont
    
    662
    +         | otherwise
    
    663
    +         = Select { sc_alts = []
    
    664
    +                  , sc_bndr = mkWildValBinder OneTy hole_ty
    
    665
    +                  , sc_dup  = OkToDup
    
    666
    +                  , sc_env  = se
    
    667
    +                  , sc_cont = stop_cont }
    
    668
    +         where
    
    669
    +           hole_ty   = contHoleType k
    
    670
    +           stop_cont = contStop k
    
    671
    +
    
    672
    +
    
    626 673
     -------------------
    
    627 674
     mkArgInfo :: SimplEnv -> RuleEnv -> Id -> SimplCont -> ArgInfo
    
    628 675
     
    

  • 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
    ... ... @@ -541,3 +541,4 @@ test('T25883d', [extra_files(['T25883d_import.hs'])], multimod_compile_filter, [
    541 541
     test('T26681',  normal, compile, ['-O'])
    
    542 542
     test('T26903', [grep_errmsg(r'reverse')], compile, ['-O -dno-typeable-binds -ddump-simpl -dsuppress-uniques -dsuppress-all'])
    
    543 543
     test('T26682',  normal, multimod_compile, ['T26682', '-O -v0'])
    
    544
    +test('T27261', [extra_files(['T27261_aux.hs'])], multimod_compile, ['T27261', '-v0 -O'])