Simon Peyton Jones pushed to branch wip/T27737 at Glasgow Haskell Compiler / GHC

Commits:

2 changed files:

Changes:

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -45,7 +45,7 @@ module GHC.Core.Opt.Simplify.Env (
    45 45
     
    
    46 46
             -- * LetFloats
    
    47 47
             LetFloats, FloatEnable(..), letFloatBinds, emptyLetFloats, unitLetFloat,
    
    48
    -        addLetFlts,  mapLetFloats,
    
    48
    +        unitCaseFloat, addLetFlts,  mapLetFloats,
    
    49 49
     
    
    50 50
             -- * JoinFloats
    
    51 51
             JoinFloat, JoinFloats, emptyJoinFloats,
    
    ... ... @@ -65,7 +65,8 @@ import GHC.Core.Subst( substExprSC )
    65 65
     import GHC.Core.Unfold
    
    66 66
     import GHC.Core.TyCo.Subst (emptyIdSubstEnv, mkSubst)
    
    67 67
     import GHC.Core.Multiplicity( Scaled(..), mkMultMul )
    
    68
    -import GHC.Core.Make            ( mkWildValBinder, mkCoreLet )
    
    68
    +import GHC.Core.Make            ( mkWildValBinder )
    
    69
    +import qualified GHC.Core.Make
    
    69 70
     import GHC.Core.Type hiding     ( substTy, substTyVar, substTyVarBndr, substCo
    
    70 71
                                     , extendTvSubst, extendCvSubst )
    
    71 72
     import qualified GHC.Core.Coercion as Coercion
    
    ... ... @@ -760,10 +761,46 @@ Examples
    760 761
       NonRec x* (f y)       FltCareful  -- Strict binding; might fail or diverge
    
    761 762
       NonRec x# (a /# b)    FltCareful  -- Might fail; does not satisfy let-can-float invariant
    
    762 763
       NonRec x# (f y)       FltCareful  -- Might diverge; does not satisfy let-can-float invariant
    
    764
    +
    
    765
    +A binding that does not satisfy the let-can-float invariant (the last two
    
    766
    +examples above) is represented by a FloatCase, not a FloatLet:
    
    767
    +  FloatCase (a /# b) x# DEFAULT []
    
    768
    +That is done once and for all by `unitLetFloat`, so a FloatLet in a LetFloats
    
    769
    +is always a valid let-binding, and `wrapFloats` does not need to check.
    
    770
    +Such bindings can arise from `makeTrivial`, because an argument need not
    
    771
    +satisfy the let-can-float invariant.  They also arise because
    
    772
    +exprOkForSpeculation is conservative: e.g. it says False for (# s, x #)
    
    773
    +where x is lifted, because it checks the arguments against the
    
    774
    +(representation-polymorphic) type of the unboxed-tuple worker.
    
    775
    +
    
    776
    +However, a FloatLet can still be FltCareful: the first FltCareful example
    
    777
    +above, NonRec x* (f y), where x* is lifted but has a strict demand
    
    778
    +(isStrUsedDmd).  That is a perfectly valid (lazy) let-binding, but its demand
    
    779
    +info is valid only where it is.  If we floated it out of the RHS of a lazy
    
    780
    +binding
    
    781
    +     let v = let x* = f y in x*+1 in body
    
    782
    + ==> let x* = f y; v = x*+1 in body
    
    783
    +then x's demand info would be a lie, and CorePrep, which case-binds a let
    
    784
    +whose binder has a strict demand, would evaluate (f y) eagerly.  Hence
    
    785
    +FltCareful, which doFloatFromRhs allows to float only out of a strict binding.
    
    786
    +
    
    787
    +As well as let-bindings, a LetFloats can contain single-alternative case
    
    788
    +floats (FloatCase), for example
    
    789
    +  case e of b { (# a, c #) -> <hole> }
    
    790
    +These are classified just like a strict binding:
    
    791
    +
    
    792
    +  FloatCase (y +# 3) b DEFAULT []      FltOkSpec   -- Scrutinee ok-for-speculation
    
    793
    +  FloatCase (f y) b (# a,c #) [a,c]    FltCareful  -- Might fail or diverge
    
    794
    +
    
    795
    +Being strict they are never FltLifted, so they never float to top level or into
    
    796
    +a recursive group.
    
    797
    +
    
    798
    +Currently, we never put a FloatTick in a LetFloats.
    
    763 799
     -}
    
    764 800
     
    
    765
    -data LetFloats = LetFloats (OrdList OutBind) FloatFlag
    
    801
    +data LetFloats = LetFloats FloatBinds FloatFlag
    
    766 802
                      -- See Note [LetFloats]
    
    803
    +                 -- Contains only FloatLet and FloatCase; never FloatTick
    
    767 804
     
    
    768 805
     type JoinFloat  = OutBind
    
    769 806
     type JoinFloats = OrdList JoinFloat
    
    ... ... @@ -864,17 +901,35 @@ isEmptyJoinFloats = isNilOL
    864 901
     
    
    865 902
     unitLetFloat :: OutBind -> LetFloats
    
    866 903
     -- This key function constructs a singleton float with the right form
    
    904
    +-- If the binding does not satisfy the let-can-float invariant, it
    
    905
    +-- makes a FloatCase. See Note [LetFloats]
    
    867 906
     unitLetFloat bind = assert (all (not . isJoinId) (bindersOf bind)) $
    
    868
    -                    LetFloats (unitOL bind) (flag bind)
    
    907
    +                    mk_float bind
    
    869 908
       where
    
    870
    -    flag (Rec {})                = FltLifted
    
    871
    -    flag (NonRec bndr rhs)
    
    872
    -      | not (isStrictId bndr)    = FltLifted
    
    873
    -      | exprIsTickedString rhs   = FltLifted
    
    909
    +    mk_float bind@(Rec {})       = let_float FltLifted bind
    
    910
    +    mk_float bind@(NonRec bndr rhs)
    
    911
    +      | not (isStrictId bndr)    = let_float FltLifted bind
    
    912
    +      | exprIsTickedString rhs   = let_float FltLifted bind
    
    874 913
               -- String literals can be floated freely.
    
    875 914
               -- See Note [Core top-level string literals] in GHC.Core.
    
    876
    -      | exprOkForSpeculation rhs = FltOkSpec  -- Unlifted, and lifted but ok-for-spec (eg HNF)
    
    877
    -      | otherwise                = FltCareful
    
    915
    +      | exprOkForSpeculation rhs = let_float FltOkSpec bind  -- Unlifted, and lifted but ok-for-spec (eg HNF)
    
    916
    +      | needsCaseBinding (idType bndr) rhs
    
    917
    +      = pprTrace "TMP-unitLetFloat-case" (ppr bind) $
    
    918
    +        LetFloats (unitOL (FloatCase rhs bndr DEFAULT [])) FltCareful
    
    919
    +          -- Unlifted, and not ok-for-spec: does not satisfy let-can-float invariant
    
    920
    +      | otherwise                = let_float FltCareful bind
    
    921
    +
    
    922
    +    let_float flag bind = LetFloats (unitOL (FloatLet bind)) flag
    
    923
    +
    
    924
    +unitCaseFloat :: OutExpr -> OutId -> AltCon -> [OutVar] -> LetFloats
    
    925
    +-- Constructs a singleton single-alternative case float
    
    926
    +--   case scrut of bndr { con bndrs -> <hole> }
    
    927
    +-- See Note [LetFloats]
    
    928
    +unitCaseFloat scrut bndr con bndrs
    
    929
    +  = LetFloats (unitOL (FloatCase scrut bndr con bndrs)) flag
    
    930
    +  where
    
    931
    +    flag | exprOkForSpeculation scrut = FltOkSpec
    
    932
    +         | otherwise                  = FltCareful
    
    878 933
     
    
    879 934
     unitJoinFloat :: OutBind -> JoinFloats
    
    880 935
     unitJoinFloat bind = assert (all isJoinId (bindersOf bind)) $
    
    ... ... @@ -929,7 +984,11 @@ addLetFloats floats let_floats
    929 984
     
    
    930 985
     extendInScopeFromLF :: InScopeSet -> LetFloats -> InScopeSet
    
    931 986
     extendInScopeFromLF in_scope (LetFloats binds _)
    
    932
    -  = foldlOL extendInScopeSetBind in_scope binds
    
    987
    +  = foldlOL extend in_scope binds
    
    988
    +  where
    
    989
    +    extend in_scope (FloatLet bind)        = in_scope `extendInScopeSetBind` bind
    
    990
    +    extend in_scope (FloatCase _ b _ bs)   = in_scope `extendInScopeSetList` (b:bs)
    
    991
    +    extend in_scope (FloatTick {})         = in_scope
    
    933 992
     
    
    934 993
     addJoinFloats :: SimplFloats -> JoinFloats -> SimplFloats
    
    935 994
     addJoinFloats floats join_floats
    
    ... ... @@ -952,7 +1011,12 @@ addLetFlts (LetFloats bs1 l1) (LetFloats bs2 l2)
    952 1011
       = LetFloats (bs1 `appOL` bs2) (l1 `andFF` l2)
    
    953 1012
     
    
    954 1013
     letFloatBinds :: LetFloats -> [CoreBind]
    
    955
    -letFloatBinds (LetFloats bs _) = fromOL bs
    
    1014
    +-- Precondition: there are no case-floats
    
    1015
    +-- True, for example, if the FloatFlag is FltLifted
    
    1016
    +letFloatBinds (LetFloats bs _) = map get_bind (fromOL bs)
    
    1017
    +  where
    
    1018
    +    get_bind (FloatLet bind) = bind
    
    1019
    +    get_bind flt             = pprPanic "letFloatBinds" (ppr flt)
    
    956 1020
     
    
    957 1021
     addJoinFlts :: JoinFloats -> JoinFloats -> JoinFloats
    
    958 1022
     addJoinFlts = appOL
    
    ... ... @@ -960,7 +1024,7 @@ addJoinFlts = appOL
    960 1024
     mkRecFloats :: SimplFloats -> SimplFloats
    
    961 1025
     -- Flattens the floats into a single Rec group,
    
    962 1026
     -- They must either all be lifted LetFloats or all JoinFloats
    
    963
    -mkRecFloats floats@(SimplFloats { sfLetFloats  = LetFloats bs _ff
    
    1027
    +mkRecFloats floats@(SimplFloats { sfLetFloats  = lfs@(LetFloats bs _ff)
    
    964 1028
                                     , sfJoinFloats = jbs
    
    965 1029
                                     , sfInScope    = in_scope })
    
    966 1030
       = assertPpr (isNilOL bs || isNilOL jbs) (ppr floats) $
    
    ... ... @@ -970,20 +1034,19 @@ mkRecFloats floats@(SimplFloats { sfLetFloats = LetFloats bs _ff
    970 1034
       where
    
    971 1035
         -- See Note [Bangs in the Simplifier]
    
    972 1036
         !floats'  | isNilOL bs  = emptyLetFloats
    
    973
    -              | otherwise   = unitLetFloat (Rec (flattenBinds (fromOL bs)))
    
    1037
    +              | otherwise   = unitLetFloat (Rec (flattenBinds (letFloatBinds lfs)))
    
    974 1038
         !jfloats' | isNilOL jbs = emptyJoinFloats
    
    975 1039
                   | otherwise   = unitJoinFloat (Rec (flattenBinds (fromOL jbs)))
    
    976 1040
     
    
    977 1041
     wrapFloats :: SimplFloats -> OutExpr -> OutExpr
    
    978 1042
     -- Wrap the floats around the expression
    
    979
    -wrapFloats (SimplFloats { sfLetFloats  = LetFloats bs flag
    
    1043
    +wrapFloats (SimplFloats { sfLetFloats  = LetFloats bs _
    
    980 1044
                             , sfJoinFloats = jbs }) body
    
    981
    -  = foldrOL mk_let (wrapJoinFloats jbs body) bs
    
    1045
    +  = GHC.Core.Make.wrapFloats bs (wrapJoinFloats jbs body)
    
    982 1046
          -- Note: Always safe to put the joins on the inside
    
    983 1047
          -- since the values can't refer to them
    
    984
    -  where
    
    985
    -    mk_let | FltCareful <- flag = mkCoreLet -- need to enforce let-can-float-invariant
    
    986
    -           | otherwise          = Let       -- let-can-float invariant hold
    
    1048
    +     -- No need to worry about the let-can-float invariant: unitLetFloat
    
    1049
    +     -- has made a FloatCase for any binding that does not satisfy it
    
    987 1050
     
    
    988 1051
     wrapJoinFloatsX :: SimplFloats -> OutExpr -> (SimplFloats, OutExpr)
    
    989 1052
     -- Wrap the sfJoinFloats of the env around the expression,
    
    ... ... @@ -1009,8 +1072,10 @@ mapLetFloats :: LetFloats -> ((Id,CoreExpr) -> (Id,CoreExpr)) -> LetFloats
    1009 1072
     mapLetFloats (LetFloats fs ff) fun
    
    1010 1073
        = LetFloats fs1 ff
    
    1011 1074
        where
    
    1012
    -    app (NonRec b e) = case fun (b,e) of (b',e') -> NonRec b' e'
    
    1013
    -    app (Rec bs)     = Rec (strictMap fun bs)
    
    1075
    +    app (FloatLet (NonRec b e)) = case fun (b,e) of (b',e') -> FloatLet (NonRec b' e')
    
    1076
    +    app (FloatLet (Rec bs))     = FloatLet (Rec (strictMap fun bs))
    
    1077
    +    app (FloatCase e b con bs)  = case fun (b,e) of (b',e') -> FloatCase e' b' con bs
    
    1078
    +    app flt@(FloatTick {})      = pprPanic "mapLetFloats" (ppr flt)
    
    1014 1079
         !fs1 = (mapOL' app fs) -- See Note [Bangs in the Simplifier]
    
    1015 1080
     
    
    1016 1081
     {-
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -256,6 +256,8 @@ simplRecBind env0 bind_cxt pairs0
    256 256
             ; let new_bndrs = map sndOf3 triples
    
    257 257
             ; (rec_floats, env2) <- enterRecGroupRHSs env1 new_bndrs $ \env ->
    
    258 258
                                     go env triples
    
    259
    +
    
    260
    +           -- In rec_floats, all the `sfLetFloats` bindings are `FltLifted`
    
    259 261
             ; return (mkRecFloats rec_floats, env2) }
    
    260 262
       where
    
    261 263
         add_rules :: SimplEnv -> (InBndr,InExpr) -> SimplM (SimplEnv, (InBndr, OutBndr, InExpr))
    
    ... ... @@ -284,7 +286,8 @@ simplRecOrTopPair :: SimplEnv
    284 286
                       -> BindContext
    
    285 287
                       -> InId -> OutBndr -> InExpr  -- Binder and rhs
    
    286 288
                       -> SimplM (SimplFloats, SimplEnv)
    
    287
    -
    
    289
    +-- Invariant: in the returned SimplFloats,
    
    290
    +--            all the `sfLetFloats` bindings are `FltLifted`
    
    288 291
     simplRecOrTopPair env bind_cxt old_bndr new_bndr rhs
    
    289 292
       | Just env' <- preInlineUnconditionally env (bindContextLevel bind_cxt)
    
    290 293
                                               old_bndr (UnSimplified env) rhs MRefl
    
    ... ... @@ -3399,15 +3402,57 @@ doCaseToLet scrut case_bndr
    3399 3402
     
    
    3400 3403
     reallyRebuildCase (saf,env) scrut case_bndr alts cont
    
    3401 3404
       = do { (floats, env', cont') <- mkDupableCaseCont env alts cont
    
    3402
    -       ; case_expr <- simplAlts (saf,env') scrut
    
    3403
    -                                (scaleIdBy holeScaling case_bndr)
    
    3404
    -                                (scaleAltsBy holeScaling alts)
    
    3405
    -                                cont'
    
    3406
    -       ; return (floats, case_expr) }
    
    3405
    +       ; traceSmpl "reallyRebuildCase" (vcat [ ppr case_bndr
    
    3406
    +                                             , text "cont':" <+> ppr cont'
    
    3407
    +                                             , text "in_scope" <+> ppr (seInScope env') ])
    
    3408
    +       ; (alt_env, scrut', case_bndr', imposs_deflt_cons, in_alts)
    
    3409
    +             <- prepareCase (saf,env') scrut (scaleIdBy holeScaling case_bndr)
    
    3410
    +                                             (scaleAltsBy holeScaling alts)
    
    3411
    +       ; case in_alts of
    
    3412
    +           [in_alt] -> do { (alt_floats, alt') <- simplAlt (saf,alt_env) (Just scrut')
    
    3413
    +                                                     imposs_deflt_cons case_bndr'
    
    3414
    +                                                     bndr_swap cont' in_alt
    
    3415
    +                          ; (case_floats, res) <- rebuildSingleAltCase env' scrut' case_bndr'
    
    3416
    +                                                         cont' alt_floats alt'
    
    3417
    +                          ; return (floats `addFloats` case_floats, res) }
    
    3418
    +
    
    3419
    +           _ -> do { case_expr <- simplAlts (saf,alt_env) scrut' case_bndr'
    
    3420
    +                                            imposs_deflt_cons bndr_swap cont' in_alts
    
    3421
    +                   ; return (floats, case_expr) } }
    
    3407 3422
       where
    
    3408 3423
         holeScaling = contHoleScaling cont
    
    3409 3424
         -- Note [Scaling in case-of-case]
    
    3410 3425
     
    
    3426
    +    bndr_swap = scrutOkForBinderSwap scrut
    
    3427
    +
    
    3428
    +rebuildSingleAltCase :: SimplEnv -> OutExpr -> OutId -> SimplCont
    
    3429
    +                     -> SimplFloats -> OutAlt
    
    3430
    +                     -> SimplM (SimplFloats, OutExpr)
    
    3431
    +-- Build a single-alternative case; but return it as a FloatCase float, so that
    
    3432
    +-- the floats from its RHS are not trapped inside it.
    
    3433
    +-- See Note [Floating single-alternative cases]
    
    3434
    +rebuildSingleAltCase env scrut case_bndr cont alt_floats (Alt con bs rhs)
    
    3435
    +  = do { let alts_ty = contResultType cont
    
    3436
    +       -- See Note [Avoiding space leaks in OutType]
    
    3437
    +       ; case_expr <- seqType alts_ty `seq`
    
    3438
    +                      mkCase (seMode env) scrut case_bndr alts_ty
    
    3439
    +                             [Alt con bs (wrapFloats alt_floats rhs)]
    
    3440
    +                      -- wrapFloats: lazily; see (FSC1)
    
    3441
    +       ; case case_expr of
    
    3442
    +           Case scrut2 bndr2 _ [Alt con2 bs2 rhs2]
    
    3443
    +             | not (noFloats alt_floats)
    
    3444
    +             , bndr2 == case_bndr   -- mkCase has not changed the case; see (FSC1)
    
    3445
    +             -> return (case_float `addFloats` alt_floats, rhs)
    
    3446
    +             | otherwise
    
    3447
    +             -> return (case_float, rhs2)
    
    3448
    +             where
    
    3449
    +               case_float = emptyFloats env `addLetFloats`
    
    3450
    +                            unitCaseFloat scrut2 bndr2 con2 bs2
    
    3451
    +           _ -> return (emptyFloats env, case_expr) }
    
    3452
    +  where
    
    3453
    +    noFloats (SimplFloats { sfLetFloats = lfs, sfJoinFloats = jfs })
    
    3454
    +      = isEmptyLetFloats lfs && isEmptyJoinFloats jfs
    
    3455
    +
    
    3411 3456
     {-
    
    3412 3457
     simplCaseBinder checks whether the scrutinee is a variable, v.  If so,
    
    3413 3458
     try to eliminate uses of v in the RHSs in favour of case_bndr; that
    
    ... ... @@ -3540,17 +3585,16 @@ scale the entire case we are simplifying, by a scaling factor which can be
    3540 3585
     computed in the continuation (with function `contHoleScaling`).
    
    3541 3586
     -}
    
    3542 3587
     
    
    3543
    -simplAlts :: (SimplAltFlag, SimplEnv)
    
    3544
    -          -> OutExpr                       -- Scrutinee
    
    3545
    -          -> InId -> [InAlt]  -- Alts (non-empty)
    
    3546
    -          -> SimplCont
    
    3547
    -          -> SimplM OutExpr  -- Returns the complete simplified case expression
    
    3548
    -
    
    3549
    -simplAlts (saf,env0) scrut case_bndr alts cont'
    
    3550
    -  = do  { traceSmpl "simplAlts" (vcat [ ppr case_bndr
    
    3551
    -                                      , text "cont':" <+> ppr cont'
    
    3552
    -                                      , text "in_scope" <+> ppr (seInScope env0) ])
    
    3553
    -        ; (env1, case_bndr1) <- simplAltIdBinder (saf,env0) case_bndr
    
    3588
    +prepareCase :: (SimplAltFlag, SimplEnv)
    
    3589
    +            -> OutExpr          -- Scrutinee
    
    3590
    +            -> InId -> [InAlt]  -- Case binder and alts (non-empty)
    
    3591
    +            -> SimplM ( SimplEnv   -- For the alternatives
    
    3592
    +                      , OutExpr    -- Scrutinee, perhaps improved by improveSeq
    
    3593
    +                      , OutId      -- Case binder
    
    3594
    +                      , [AltCon]   -- Constructors impossible in the DEFAULT alt
    
    3595
    +                      , [InAlt] )  -- Alternatives, from prepareAlts
    
    3596
    +prepareCase (saf,env0) scrut case_bndr alts
    
    3597
    +  = do  { (env1, case_bndr1) <- simplAltIdBinder (saf,env0) case_bndr
    
    3554 3598
             ; let case_bndr2 = case_bndr1 `setIdUnfolding` evaldUnfolding
    
    3555 3599
                   env2       = modifyInScope env1 case_bndr2
    
    3556 3600
                   -- See Note [Case binder evaluated-ness]
    
    ... ... @@ -3565,16 +3609,61 @@ simplAlts (saf,env0) scrut case_bndr alts cont'
    3565 3609
               -- NB: pass case_bndr::InId, not case_bndr' :: OutId, to prepareAlts
    
    3566 3610
               --     See Note [Shadowing in prepareAlts] in GHC.Core.Opt.Simplify.Utils
    
    3567 3611
     
    
    3568
    -        ; alts' <- forM in_alts $
    
    3569
    -            simplAlt (saf,alt_env') (Just scrut') imposs_deflt_cons
    
    3570
    -                     case_bndr' (scrutOkForBinderSwap scrut) cont'
    
    3612
    +        ; return (alt_env', scrut', case_bndr', imposs_deflt_cons, in_alts) }
    
    3613
    +
    
    3614
    +simplAlts :: (SimplAltFlag, SimplEnv)
    
    3615
    +          -> OutExpr -> OutId       -- Scrutinee and case binder
    
    3616
    +          -> [AltCon]               -- Constructors impossible in the DEFAULT alt
    
    3617
    +          -> BinderSwapDecision
    
    3618
    +          -> SimplCont
    
    3619
    +          -> [InAlt]
    
    3620
    +          -> SimplM OutExpr  -- Returns the complete simplified case expression
    
    3621
    +-- The arguments are prepared by prepareCase
    
    3622
    +simplAlts (saf,env) scrut' case_bndr' imposs_deflt_cons bndr_swap cont' in_alts
    
    3623
    +  = do  { alts' <- forM in_alts $
    
    3624
    +            simplAltC (saf,env) (Just scrut') imposs_deflt_cons
    
    3625
    +                      case_bndr' bndr_swap cont'
    
    3571 3626
     
    
    3572 3627
             ; let alts_ty' = contResultType cont'
    
    3573 3628
             -- See Note [Avoiding space leaks in OutType]
    
    3574 3629
             ; seqType alts_ty' `seq`
    
    3575
    -          mkCase (seMode env0) scrut' case_bndr' alts_ty' alts' }
    
    3630
    +          mkCase (seMode env) scrut' case_bndr' alts_ty' alts' }
    
    3576 3631
     
    
    3577 3632
     
    
    3633
    +{- Note [Floating single-alternative cases]
    
    3634
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3635
    +When reallyRebuildCase finds a single-alternative case (after prepareAlts)
    
    3636
    +   case e of b { (# a, c #) -> let x1 = .. in ... let xn = .. in (# e1, e2 #) }
    
    3637
    +it does not return the case expression; instead it returns
    
    3638
    +  * floats:  [FloatCase e b (# a,c #) [a,c], x1 = .., ..., xn = ..]
    
    3639
    +  * result:  (# e1, e2 #)
    
    3640
    +This is done by rebuildSingleAltCase.  See Note [LetFloats] in GHC.Core.Opt.Simplify.Env.
    
    3641
    +
    
    3642
    +Why?  Because a caller (notably rebuildWithFloats, when case-of-case is
    
    3643
    +switched off) may want to do case-of-known-constructor on the result. If we
    
    3644
    +returned the whole case, exprIsConApp_maybe would have to walk all the way
    
    3645
    +down through the case and the lets, which can be quadratic (#27737, T18223).
    
    3646
    +
    
    3647
    +This is not restricted to the no-case-of-case path: when case-of-case is on,
    
    3648
    +the continuation has already been pushed into the alternative, and the
    
    3649
    +floats are simply wrapped around the result, or floated further out of a
    
    3650
    +strict let (which a StrictBind continuation would do anyway).  The
    
    3651
    +FloatFlag (FltCareful or FltOkSpec) stops a case-float from floating out of
    
    3652
    +a lazy let, or to top level; see doFloatFromRhs.
    
    3653
    +
    
    3654
    +Wrinkles:
    
    3655
    +
    
    3656
    +(FSC1) mkCase may transform the case, e.g. by case-merging, identity-case
    
    3657
    +  elimination, or caseRules (mkCase2), which renames the case binder and
    
    3658
    +  wraps (let b = ..) around the RHS.  So we call mkCase on the alternative
    
    3659
    +  with its floats wrapped (lazily: mkCase inspects only the top of the RHS),
    
    3660
    +  and then:
    
    3661
    +   - If the alternative has floats, and mkCase has left the case binder
    
    3662
    +     unchanged, mkCase cannot have done anything to the RHS (which starts
    
    3663
    +     with a let), so we return (case-float + alt-floats, unwrapped RHS).
    
    3664
    +   - Otherwise we return the case-float with whatever RHS mkCase produced.
    
    3665
    +-}
    
    3666
    +
    
    3578 3667
     ------------------------------------
    
    3579 3668
     improveSeq :: (FamInstEnv, FamInstEnv)
    
    3580 3669
                -> (SimplAltFlag, SimplEnv)
    
    ... ... @@ -3594,6 +3683,15 @@ improveSeq _ (_,env) scrut _ case_bndr1 _
    3594 3683
     
    
    3595 3684
     
    
    3596 3685
     ------------------------------------
    
    3686
    +simplAltC :: (SimplAltFlag, SimplEnv) -> Maybe OutExpr -> [AltCon] -> OutId
    
    3687
    +          -> BinderSwapDecision -> SimplCont -> InAlt
    
    3688
    +          -> SimplM OutAlt
    
    3689
    +-- Like simplAlt, but wraps the floats around the RHS
    
    3690
    +simplAltC env scrut' imposs_deflt_cons case_bndr' bndr_swap' cont' alt
    
    3691
    +  = do { (floats, Alt con bs rhs) <- simplAlt env scrut' imposs_deflt_cons
    
    3692
    +                                              case_bndr' bndr_swap' cont' alt
    
    3693
    +       ; return (Alt con bs (wrapFloats floats rhs)) }
    
    3694
    +
    
    3597 3695
     simplAlt :: (SimplAltFlag, SimplEnv)
    
    3598 3696
              -> Maybe OutExpr       -- The scrutinee
    
    3599 3697
              -> [AltCon]            -- These constructors can't be present when
    
    ... ... @@ -3603,19 +3701,21 @@ simplAlt :: (SimplAltFlag, SimplEnv)
    3603 3701
                                     --           add unfolding `v :-> bndr |> sym co`
    
    3604 3702
              -> SimplCont
    
    3605 3703
              -> InAlt
    
    3606
    -         -> SimplM OutAlt
    
    3704
    +         -> SimplM (SimplFloats, OutAlt)
    
    3705
    +         -- The floats scope over the RHS only, and may mention the
    
    3706
    +         -- binders of the alternative
    
    3607 3707
     
    
    3608 3708
     simplAlt (saf,env) _scrut' imposs_deflt_cons case_bndr' bndr_swap' cont' (Alt DEFAULT bndrs rhs)
    
    3609 3709
       = assert (null bndrs) $
    
    3610 3710
         do  { let env' = addDefaultUnfoldings env case_bndr' bndr_swap' imposs_deflt_cons
    
    3611
    -        ; rhs' <- simplAltExprC (saf,env') rhs cont'
    
    3612
    -        ; return (Alt DEFAULT [] rhs') }
    
    3711
    +        ; (floats, rhs') <- simplAltExprF (saf,env') rhs cont'
    
    3712
    +        ; return (floats, Alt DEFAULT [] rhs') }
    
    3613 3713
     
    
    3614 3714
     simplAlt (saf,env) _scrut' _ case_bndr' bndr_swap' cont' (Alt (LitAlt lit) bndrs rhs)
    
    3615 3715
       = assert (null bndrs) $
    
    3616 3716
         do  { let env' = addAltUnfoldings env case_bndr' bndr_swap' (Lit lit)
    
    3617
    -        ; rhs' <- simplAltExprC (saf,env') rhs cont'
    
    3618
    -        ; return (Alt (LitAlt lit) [] rhs') }
    
    3717
    +        ; (floats, rhs') <- simplAltExprF (saf,env') rhs cont'
    
    3718
    +        ; return (floats, Alt (LitAlt lit) [] rhs') }
    
    3619 3719
     
    
    3620 3720
     simplAlt (saf,env) scrut' _ case_bndr' bndr_swap' cont' (Alt (DataAlt con) vs rhs)
    
    3621 3721
       = do  { -- See Note [Adding evaluatedness info to pattern-bound variables]
    
    ... ... @@ -3633,8 +3733,8 @@ simplAlt (saf,env) scrut' _ case_bndr' bndr_swap' cont' (Alt (DataAlt con) vs rh
    3633 3733
                   con_app = mkConApp2 con inst_tys' vs'
    
    3634 3734
                   env''   = addAltUnfoldings env' case_bndr' bndr_swap' con_app
    
    3635 3735
     
    
    3636
    -        ; rhs' <- simplAltExprC (saf,env'') rhs cont'
    
    3637
    -        ; return (Alt (DataAlt con) vs' rhs') }
    
    3736
    +        ; (floats, rhs') <- simplAltExprF (saf,env'') rhs cont'
    
    3737
    +        ; return (floats, Alt (DataAlt con) vs' rhs') }
    
    3638 3738
     
    
    3639 3739
     {- Note [Adding evaluatedness info to pattern-bound variables]
    
    3640 3740
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -3815,11 +3915,6 @@ simplAltExprF (saf,env) expr cont
    3815 3915
           SAF_Out -> simplOutExpr env expr cont
    
    3816 3916
           SAF_In  -> simplExprF   env expr cont
    
    3817 3917
     
    
    3818
    -simplAltExprC :: (SimplAltFlag, SimplEnv) -> CoreExpr -> SimplCont -> SimplM OutExpr
    
    3819
    -simplAltExprC env expr cont
    
    3820
    -  = do { (floats, expr') <- simplAltExprF env expr cont
    
    3821
    -       ; return (wrapFloats floats expr') }
    
    3822
    -
    
    3823 3918
     
    
    3824 3919
     {- Note [Case binder evaluated-ness]
    
    3825 3920
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -4338,7 +4433,7 @@ mkDupableContWithDmds env _
    4338 4433
                                         scaleIdBy cont_scaling case_bndr
    
    4339 4434
     
    
    4340 4435
             ; alts' <- forM (scaleAltsBy cont_scaling alts) $
    
    4341
    -            simplAlt (saf,alt_env1) Nothing [] case_bndr' NoBinderSwap alt_cont
    
    4436
    +            simplAltC (saf,alt_env1) Nothing [] case_bndr' NoBinderSwap alt_cont
    
    4342 4437
                     -- Safe to say that there are no handled-cons for the DEFAULT case
    
    4343 4438
                     -- NB: simplBinder does not zap deadness occ-info, so
    
    4344 4439
                     -- a dead case_bndr' will still advertise its deadness