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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -442,7 +442,7 @@ instance Outputable SimplFloats where
    442 442
                            , text "joins:" <+> ppr jf
    
    443 443
                            , text "in_scope:" <+> ppr is ])
    
    444 444
     
    
    445
    -emptyFloats :: SimplEnv -> SimplFloats
    
    445
    +emptyFloats :: SimplEnvIS -> SimplFloats
    
    446 446
     emptyFloats env
    
    447 447
       = SimplFloats { sfLetFloats  = emptyLetFloats
    
    448 448
                     , sfJoinFloats = emptyJoinFloats
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -283,7 +283,7 @@ simplRecOrTopPair :: SimplEnv
    283 283
     
    
    284 284
     simplRecOrTopPair env bind_cxt old_bndr new_bndr rhs
    
    285 285
       | Just env' <- preInlineUnconditionally env (bindContextLevel bind_cxt)
    
    286
    -                                          old_bndr NoDup rhs env
    
    286
    +                                          old_bndr rhs (UnSimplified env)
    
    287 287
       = {-#SCC "simplRecOrTopPair-pre-inline-uncond" #-}
    
    288 288
         simplTrace "SimplBindr:inline-uncond1" (ppr old_bndr) $
    
    289 289
         do { tick (PreInlineUnconditionally old_bndr)
    
    ... ... @@ -386,10 +386,9 @@ simplJoinBind is_rec cont (old_bndr, unf_se) (new_bndr, env) (rhs, rhs_se)
    386 386
             ; completeBind (BC_Join is_rec cont) (old_bndr, unf_se) (new_bndr, rhs', env) }
    
    387 387
     
    
    388 388
     --------------------------
    
    389
    -simplAuxBind :: String
    
    390
    -             -> SimplEnv
    
    391
    -             -> InId            -- Old binder; not a JoinId
    
    392
    -             -> OutExpr         -- Simplified RHS
    
    389
    +simplAuxBind :: (SimplAltFlag, SimplEnv)
    
    390
    +             -> Id            -- Binder; not a JoinId
    
    391
    +             -> OutExpr       -- Simplified RHS
    
    393 392
                  -> SimplM (SimplFloats, SimplEnv)
    
    394 393
     -- A specialised variant of completeBindX used to construct non-recursive
    
    395 394
     -- auxiliary bindings, notably in knownCon.
    
    ... ... @@ -399,7 +398,7 @@ simplAuxBind :: String
    399 398
     --
    
    400 399
     -- Precondition: rhs satisfies the let-can-float invariant
    
    401 400
     
    
    402
    -simplAuxBind _str env bndr new_rhs
    
    401
    +simplAuxBind (saf,env) bndr new_rhs
    
    403 402
       | assertPpr (isId bndr && not (isJoinId bndr)) (ppr bndr) $
    
    404 403
         isDeadBinder bndr   -- Not uncommon; e.g. case (a,b) of c { (p,q) -> p }
    
    405 404
       = return (emptyFloats env, env)    --  Here c is dead, and we avoid
    
    ... ... @@ -428,13 +427,14 @@ simplAuxBind _str env bndr new_rhs
    428 427
             ; let rhs_floats = emptyFloats env `addLetFloats` anf_floats
    
    429 428
     
    
    430 429
               -- Simplify the binder and complete the binding
    
    431
    -        ; (env1, new_bndr) <- simplBinder (env `setInScopeFromF` rhs_floats) bndr
    
    430
    +        ; (env1, new_bndr) <- simplAltIdBinder (saf, env `setInScopeFromF` rhs_floats) bndr
    
    432 431
             ; (bind_float, env2) <- completeBind (BC_Let NotTopLevel NonRecursive)
    
    433
    -                                             (bndr,env) (new_bndr, rhs1, env1)
    
    432
    +                                             (bndr, env) (new_bndr, rhs1, env1)
    
    434 433
     
    
    435 434
             ; return (rhs_floats `addFloats` bind_float, env2) }
    
    436 435
     
    
    437 436
     
    
    437
    +
    
    438 438
     {- *********************************************************************
    
    439 439
     *                                                                      *
    
    440 440
                Cast worker/wrapper
    
    ... ... @@ -772,7 +772,7 @@ That's what the 'go' loop in prepareRhs does
    772 772
     -}
    
    773 773
     
    
    774 774
     prepareRhs :: HasDebugCallStack
    
    775
    -           => SimplEnv -> TopLevelFlag
    
    775
    +           => SimplEnvIS -> TopLevelFlag
    
    776 776
                -> FastString    -- Base for any new variables
    
    777 777
                -> OutExpr
    
    778 778
                -> SimplM (LetFloats, OutExpr)
    
    ... ... @@ -832,7 +832,8 @@ prepareRhs env top_lvl occ rhs0
    832 832
     
    
    833 833
         anfise other = return (emptyLetFloats, other)
    
    834 834
     
    
    835
    -makeTrivialArg :: HasDebugCallStack => SimplEnv -> ArgSpec -> SimplM (LetFloats, ArgSpec)
    
    835
    +makeTrivialArg :: HasDebugCallStack => SimplEnvIS -> ArgSpec
    
    836
    +               -> SimplM (LetFloats, ArgSpec)
    
    836 837
     makeTrivialArg env arg@(ValArg { as_arg = e, as_dmd = dmd })
    
    837 838
       = do { (floats, e') <- makeTrivial env NotTopLevel dmd (fsLit "arg") e
    
    838 839
            ; return (floats, arg { as_arg = e' }) }
    
    ... ... @@ -840,7 +841,7 @@ makeTrivialArg _ arg@(TyArg {})
    840 841
       = return (emptyLetFloats, arg)
    
    841 842
     
    
    842 843
     makeTrivial :: HasDebugCallStack
    
    843
    -            => SimplEnv -> TopLevelFlag -> Demand
    
    844
    +            => SimplEnvIS -> TopLevelFlag -> Demand
    
    844 845
                 -> FastString  -- ^ A "friendly name" to build the new binder from
    
    845 846
                 -> OutExpr
    
    846 847
                 -> SimplM (LetFloats, OutExpr)
    
    ... ... @@ -1260,9 +1261,9 @@ simplExprF1 env (App fun arg) cont
    1260 1261
               -- observed the quadratic behavior, so this extra entanglement
    
    1261 1262
               -- seems not worthwhile.
    
    1262 1263
             simplExprF env fun $
    
    1263
    -        ApplyToVal { sc_arg = arg, sc_env = env
    
    1264
    +        ApplyToVal { sc_arg = arg, sc_env = UnSimplified env
    
    1264 1265
                        , sc_hole_ty = substTy env (exprType fun)
    
    1265
    -                   , sc_dup = NoDup, sc_cont = cont }
    
    1266
    +                   , sc_cont = cont }
    
    1266 1267
     
    
    1267 1268
     simplExprF1 env expr@(Lam {}) cont
    
    1268 1269
       = {-#SCC "simplExprF1-Lam" #-}
    
    ... ... @@ -1280,9 +1281,8 @@ simplExprF1 env expr@(Lam {}) cont
    1280 1281
     
    
    1281 1282
     simplExprF1 env (Case scrut bndr _ alts) cont
    
    1282 1283
       = {-#SCC "simplExprF1-Case" #-}
    
    1283
    -    simplExprF env scrut (Select { sc_dup = NoDup, sc_bndr = bndr
    
    1284
    -                                 , sc_alts = alts
    
    1285
    -                                 , sc_env = env, sc_cont = cont })
    
    1284
    +    simplExprF env scrut (Select { sc_bndr = bndr, sc_alts = alts
    
    1285
    +                                 , sc_env = UnSimplified env, sc_cont = cont })
    
    1286 1286
     
    
    1287 1287
     simplExprF1 env (Let (Rec pairs) body) cont
    
    1288 1288
       | Just pairs' <- joinPointBindings_maybe pairs
    
    ... ... @@ -1298,7 +1298,7 @@ simplExprF1 env (Let (NonRec bndr rhs) body) cont
    1298 1298
         do { ty' <- simplType env ty
    
    1299 1299
            ; simplExprF (extendTvSubst env bndr ty') body cont }
    
    1300 1300
     
    
    1301
    -  | Just env' <- preInlineUnconditionally env NotTopLevel bndr NoDup rhs env
    
    1301
    +  | Just env' <- preInlineUnconditionally env NotTopLevel bndr rhs (UnSimplified env)
    
    1302 1302
         -- Because of the let-can-float invariant, it's ok to
    
    1303 1303
         -- inline freely, or to drop the binding if it is dead.
    
    1304 1304
       = do { simplTrace "SimplBindr:inline-uncond2" (ppr bndr) $
    
    ... ... @@ -1570,7 +1570,8 @@ simplTick env tickish expr cont
    1570 1570
     rebuild :: SimplEnv -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)
    
    1571 1571
     rebuild env expr cont = rebuild_go (zapSubstEnv env) expr cont
    
    1572 1572
     
    
    1573
    -rebuild_go :: SimplEnvIS -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)
    
    1573
    +rebuild_go :: HasDebugCallStack
    
    1574
    +           => SimplEnvIS -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)
    
    1574 1575
     -- SimplEnvIS: at this point the substitution in the SimplEnv is irrelevant;
    
    1575 1576
     -- only the in-scope set matters, plus the flags.
    
    1576 1577
     rebuild_go env expr cont
    
    ... ... @@ -1589,22 +1590,26 @@ rebuild_go env expr cont
    1589 1590
               co' = optOutCoercion env co opt
    
    1590 1591
     
    
    1591 1592
           Select { sc_bndr = bndr, sc_alts = alts, sc_env = se, sc_cont = cont }
    
    1592
    -        -> rebuildCase (se `setInScopeFromE` env) expr bndr alts cont
    
    1593
    +        -> rebuildCase (mkAltEnv env se) expr bndr alts cont
    
    1593 1594
     
    
    1594 1595
           StrictArg { sc_fun = fun, sc_cont = cont, sc_fun_ty = fun_ty }
    
    1595 1596
             -> rebuildCall env (addValArgTo fun expr fun_ty) cont
    
    1596 1597
     
    
    1597 1598
           StrictBind { sc_bndr = b, sc_body = body, sc_env = se
    
    1598 1599
                      , sc_cont = cont, sc_from = from_what }
    
    1599
    -        -> completeBindX (se `setInScopeFromE` env) from_what b expr body cont
    
    1600
    +        -> completeBindX body_env from_what b expr body cont
    
    1601
    +        where
    
    1602
    +          (_saf, body_env) = mkAltEnv env se
    
    1603
    +          -- In the Simplified case, it's always a OkDup, so we accept that
    
    1604
    +          -- `completeBindX` may re-simplify `body`
    
    1600 1605
     
    
    1601 1606
           ApplyToTy  { sc_arg_ty = ty, sc_cont = cont}
    
    1602 1607
             -> rebuild_go env (App expr (Type ty)) cont
    
    1603 1608
     
    
    1604
    -      ApplyToVal { sc_arg = arg, sc_env = se, sc_dup = dup_flag
    
    1609
    +      ApplyToVal { sc_arg = arg, sc_env = se
    
    1605 1610
                      , sc_cont = cont, sc_hole_ty = fun_ty }
    
    1606 1611
             -- See Note [Avoid redundant simplification]
    
    1607
    -        -> do { (_, _, arg') <- simplLazyArg env dup_flag fun_ty Nothing se arg
    
    1612
    +        -> do { (_, arg') <- simplArg env fun_ty Nothing se arg
    
    1608 1613
                   ; rebuild_go env (App expr arg') cont }
    
    1609 1614
     
    
    1610 1615
     completeBindX :: SimplEnv
    
    ... ... @@ -1748,7 +1753,7 @@ pushCast env co cont
    1748 1753
         --         co1 :: t1 ~ s1
    
    1749 1754
         --         co2 :: s2 ~ t2
    
    1750 1755
         go co co_is_opt cont@(ApplyToVal { sc_arg = arg, sc_env = arg_se
    
    1751
    -                                     , sc_dup = dup, sc_cont = tail
    
    1756
    +                                     , sc_cont = tail
    
    1752 1757
                                          , sc_hole_ty = fun_ty })
    
    1753 1758
           | not co_is_opt
    
    1754 1759
           = -- pushCoValArg duplicates the coercion, so optimise first
    
    ... ... @@ -1763,7 +1768,7 @@ pushCast env co cont
    1763 1768
                       -- See Note [Avoiding simplifying repeatedly]
    
    1764 1769
     
    
    1765 1770
                    MCo co1 ->
    
    1766
    -        do { (dup', arg_se', arg') <- simplLazyArg env dup fun_ty Nothing arg_se arg
    
    1771
    +        do { (arg_se', arg') <- simplArg env fun_ty Nothing arg_se arg
    
    1767 1772
                     -- When we build the ApplyTo we can't mix the OutCoercion
    
    1768 1773
                     -- 'co' with the InExpr 'arg', so we simplify
    
    1769 1774
                     -- to make it all consistent.  It's a bit messy.
    
    ... ... @@ -1771,7 +1776,6 @@ pushCast env co cont
    1771 1776
                     -- Example of use: #995
    
    1772 1777
                ; return (ApplyToVal { sc_arg  = mkCast arg' co1
    
    1773 1778
                                     , sc_env  = arg_se'
    
    1774
    -                                , sc_dup  = dup'
    
    1775 1779
                                     , sc_cont = tail'
    
    1776 1780
                                     , sc_hole_ty = coercionLKind co }) } } }
    
    1777 1781
     
    
    ... ... @@ -1788,26 +1792,24 @@ pushCast env co cont
    1788 1792
         go_mco MRefl    _   cont = return cont
    
    1789 1793
         go_mco (MCo co) opt cont = go co opt cont
    
    1790 1794
     
    
    1791
    -simplLazyArg :: SimplEnvIS              -- ^ Used only for its InScopeSet
    
    1792
    -             -> DupFlag
    
    1793
    -             -> OutType                 -- ^ Type of the function applied to this arg
    
    1794
    -             -> Maybe ArgInfo           -- ^ Just <=> This arg `ai` occurs in an app
    
    1795
    -                                        --   `f a1 ... an` where we have ArgInfo on
    
    1796
    -                                        --   how `f` uses `ai`, affecting the Stop
    
    1797
    -                                        --   continuation passed to 'simplExprC'
    
    1798
    -             -> StaticEnv -> CoreExpr   -- ^ Expression with its static envt
    
    1799
    -             -> SimplM (DupFlag, StaticEnv, OutExpr)
    
    1800
    -simplLazyArg env dup_flag fun_ty mb_arg_info arg_env arg
    
    1801
    -  | isSimplified dup_flag
    
    1802
    -  = return (dup_flag, arg_env, arg)
    
    1803
    -  | otherwise
    
    1804
    -  = do { let arg_env' = arg_env `setInScopeFromE` env
    
    1805
    -       ; let arg_ty = funArgTy fun_ty
    
    1806
    -       ; let stop = case mb_arg_info of
    
    1795
    +simplArg :: SimplEnvIS              -- ^ Used only for its InScopeSet
    
    1796
    +         -> OutType                 -- ^ Type of the function applied to this arg
    
    1797
    +         -> Maybe ArgInfo           -- ^ Just <=> This arg `ai` occurs in an app
    
    1798
    +                                    --   `f a1 ... an` where we have ArgInfo on
    
    1799
    +                                    --   how `f` uses `ai`, affecting the Stop
    
    1800
    +                                    --   continuation passed to 'simplExprC'
    
    1801
    +         -> StaticEnv -> CoreExpr   -- ^ Expression with its static envt
    
    1802
    +         -> SimplM (StaticEnv, OutExpr)
    
    1803
    +simplArg _ _ _ se@(Simplified {}) arg
    
    1804
    +  = return (se, arg)
    
    1805
    +simplArg env fun_ty mb_arg_info (UnSimplified arg_se) arg
    
    1806
    +  = do { let arg_env' = arg_se `setInScopeFromE` env
    
    1807
    +             arg_ty   = funArgTy fun_ty
    
    1808
    +             stop     = case mb_arg_info of
    
    1807 1809
                    Nothing -> mkBoringStop arg_ty
    
    1808 1810
                    Just ai -> mkLazyArgStop arg_ty ai
    
    1809 1811
            ; arg' <- simplExprC arg_env' arg stop
    
    1810
    -       ; return (Simplified, zapSubstEnv arg_env', arg') }
    
    1812
    +       ; return (Simplified NoDup, arg') }
    
    1811 1813
              -- Return a StaticEnv that includes the in-scope set from 'env',
    
    1812 1814
              -- because arg' may well mention those variables (#20639)
    
    1813 1815
     
    
    ... ... @@ -1847,13 +1849,15 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = Coercion arg_co, sc_env = arg_se
    1847 1849
                                         , sc_cont = cont })
    
    1848 1850
       = assertPpr (isCoVar bndr) (ppr bndr) $
    
    1849 1851
         do { tick (BetaReduction bndr)
    
    1850
    -       ; let arg_co' = substCo (arg_se `setInScopeFromE` env) arg_co
    
    1852
    +       ; let arg_co' = case arg_se of
    
    1853
    +                          Simplified {}       -> arg_co
    
    1854
    +                          UnSimplified arg_se -> substCo (arg_se `setInScopeFromE` env) arg_co
    
    1851 1855
            ; simplLam (extendCvSubst env bndr arg_co') body cont }
    
    1852 1856
     
    
    1853 1857
     -- Value beta-reduction
    
    1854 1858
     -- This works for /coercion/ lambdas too
    
    1855 1859
     simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se
    
    1856
    -                                    , sc_cont = cont, sc_dup = dup
    
    1860
    +                                    , sc_cont = cont
    
    1857 1861
                                         , sc_hole_ty = fun_ty})
    
    1858 1862
       = do { tick (BetaReduction bndr)
    
    1859 1863
            ; let from_what = FromBeta arg_levity
    
    ... ... @@ -1869,7 +1873,7 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se
    1869 1873
                  --      It's wrong to err in either direction
    
    1870 1874
                  --      But fun_ty is an OutType, so is fully substituted
    
    1871 1875
     
    
    1872
    -       ; if | Just env' <- preInlineUnconditionally env NotTopLevel bndr dup arg arg_se
    
    1876
    +       ; if | Just env' <- preInlineUnconditionally env NotTopLevel bndr arg arg_se
    
    1873 1877
                 , not (needsCaseBindingL arg_levity arg)
    
    1874 1878
                   -- Ok to test arg::InExpr in needsCaseBinding because
    
    1875 1879
                   -- exprOkForSpeculation is stable under simplification
    
    ... ... @@ -1877,13 +1881,17 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se
    1877 1881
                         tick (PreInlineUnconditionally bndr)
    
    1878 1882
                       ; simplLam env' body cont }
    
    1879 1883
     
    
    1880
    -            | isSimplified dup  -- Don't re-simplify if we've simplified it once
    
    1881
    -                                -- Including don't preInlineUnconditionally
    
    1882
    -                                -- See Note [Avoiding simplifying repeatedly]
    
    1883
    -            -> completeBindX env from_what bndr arg body cont
    
    1884
    -
    
    1885 1884
                 | otherwise
    
    1886
    -            -> simplNonRecE env from_what bndr (arg, arg_se) body cont }
    
    1885
    +            -> case arg_se of
    
    1886
    +                  Simplified {}
    
    1887
    +                    -- Don't re-simplify if we've simplified it once
    
    1888
    +                    -- Including don't preInlineUnconditionally
    
    1889
    +                    -- See Note [Avoiding simplifying repeatedly]
    
    1890
    +                    -> completeBindX env from_what bndr arg body cont
    
    1891
    +
    
    1892
    +                  UnSimplified arg_env
    
    1893
    +                    -> simplNonRecE env from_what bndr (arg, arg_env) body cont
    
    1894
    +       }
    
    1887 1895
     
    
    1888 1896
     -- Discard a non-counting tick on a lambda.  This may change the
    
    1889 1897
     -- cost attribution slightly (moving the allocation of the
    
    ... ... @@ -1945,7 +1953,7 @@ simplNonRecE env from_what bndr (rhs, rhs_se) body cont
    1945 1953
       = -- Evaluate RHS strictly
    
    1946 1954
         simplExprF (rhs_se `setInScopeFromE` env) rhs
    
    1947 1955
                    (StrictBind { sc_bndr = bndr, sc_body = body, sc_from = from_what
    
    1948
    -                           , sc_env = env, sc_cont = cont, sc_dup = NoDup })
    
    1956
    +                           , sc_env = UnSimplified env, sc_cont = cont })
    
    1949 1957
     
    
    1950 1958
       | otherwise  -- Evaluate RHS lazily
    
    1951 1959
       = do { (env1, bndr1)    <- simplNonRecBndr env bndr
    
    ... ... @@ -2278,7 +2286,7 @@ simplInId :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr)
    2278 2286
     simplInId env var cont
    
    2279 2287
       | Just dc <- isDataConWorkId_maybe var
    
    2280 2288
       , isLazyDataConRep dc                    -- See Note [Fast path for lazy data constructors]
    
    2281
    -  = rebuild_go zapped_env (Var var) cont
    
    2289
    +  = rebuild env (Var var) cont
    
    2282 2290
       | otherwise
    
    2283 2291
       = case substId env var of
    
    2284 2292
           ContEx tvs cvs ids e -> simplExprF env' e cont
    
    ... ... @@ -2299,13 +2307,18 @@ simplInId env var cont
    2299 2307
     
    
    2300 2308
     
    
    2301 2309
     ---------------------------------------------------------
    
    2302
    -simplOutExpr :: SimplEnvIS -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)
    
    2310
    +simplOutExpr :: HasDebugCallStack
    
    2311
    +             => SimplEnvIS -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)
    
    2303 2312
     -- A teeny-tiny simplifier for an OutExpr, which parsimonously avoids re-simplifying
    
    2304 2313
     -- the entire things all over again
    
    2305 2314
     --
    
    2306 2315
     -- What if expr = (K x y) and cont is `Select`?  That is handled by rebuild.
    
    2307 2316
     --   (Why?  That's a bit inconsistent with beta.)
    
    2308 2317
     simplOutExpr env expr cont
    
    2318
    +  | assertPpr (checkSimplEnvIS env) (pprBadSimplEnvIS env) $
    
    2319
    +    False  -- Just checks the assertion!
    
    2320
    +  = panic "simplOutExpr"
    
    2321
    +
    
    2309 2322
       | Lam {} <- expr
    
    2310 2323
       , cont_has_args
    
    2311 2324
       = simplLam env (occurAnalyseExpr expr) cont
    
    ... ... @@ -2326,7 +2339,7 @@ simplOutExpr env expr cont
    2326 2339
         -- pprTrace "simplOutExpr" (vcat [ ppr v <+> dcolon <+> ppr (idType v)
    
    2327 2340
         --                              , text "args:" <+> ppr args
    
    2328 2341
         --                              , text "cont:" <+> ppr cont ]) $
    
    2329
    -    simplOutId env v (pushArgs env (idType v) args cont)
    
    2342
    +    simplOutId env v (pushArgs (idType v) args cont)
    
    2330 2343
     
    
    2331 2344
       | otherwise
    
    2332 2345
       = rebuild_go env expr cont
    
    ... ... @@ -2349,7 +2362,7 @@ simplOutId env fun cont
    2349 2362
                    , sc_env = arg_se, sc_hole_ty = fun_ty } <- cont2
    
    2350 2363
       -- Do this even if (contIsStop cont), or if seCaseCase is off.
    
    2351 2364
       -- See Note [No eta-expansion in runRW#]
    
    2352
    -  = do { let arg_env = arg_se `setInScopeFromE` env
    
    2365
    +  = do { let (_saf,arg_env) = mkAltEnv env arg_se
    
    2353 2366
     
    
    2354 2367
                  overall_res_ty = contResultType cont3
    
    2355 2368
                  -- hole_ty is the type of the current runRW# application
    
    ... ... @@ -2374,8 +2387,8 @@ simplOutId env fun cont
    2374 2387
                _ -> do { s' <- newId (fsLit "s") ManyTy realWorldStatePrimTy
    
    2375 2388
                        ; let (m,_,_) = splitFunTy fun_ty
    
    2376 2389
                              env'  = arg_env `addNewInScopeIds` [s']
    
    2377
    -                         cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s'
    
    2378
    -                                            , sc_env = env', sc_cont = inner_cont
    
    2390
    +                         cont' = ApplyToVal { sc_arg = Var s'
    
    2391
    +                                            , sc_env = Simplified OkDup, sc_cont = inner_cont
    
    2379 2392
                                                 , sc_hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty }
    
    2380 2393
                                     -- cont' applies to s', then K
    
    2381 2394
                        ; body' <- simplExprC env' arg cont'
    
    ... ... @@ -2460,30 +2473,23 @@ rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_c
    2460 2473
     ---------- Simplify value arguments --------------------
    
    2461 2474
     rebuildCall env fun_info
    
    2462 2475
                 (ApplyToVal { sc_arg = arg, sc_env = arg_se
    
    2463
    -                        , sc_dup = dup_flag, sc_hole_ty = fun_ty
    
    2464
    -                        , sc_cont = cont })
    
    2465
    -  -- Argument is already simplified
    
    2466
    -  | isSimplified dup_flag     -- See Note [Avoid redundant simplification]
    
    2467
    -  = rebuildCall env (addValArgTo fun_info arg fun_ty) cont
    
    2468
    -
    
    2469
    -  -- Strict arguments
    
    2470
    -  | isStrictArgInfo fun_info
    
    2471
    -  , seCaseCase env    -- Only when case-of-case is on. See GHC.Driver.Config.Core.Opt.Simplify
    
    2472
    -                      --    Note [Case-of-case and full laziness]
    
    2473
    -  = -- pprTrace "Strict Arg" (ppr arg $$ ppr (seIdSubst env) $$ ppr (seInScope env)) $
    
    2474
    -    simplExprF (arg_se `setInScopeFromE` env) arg
    
    2476
    +                        , sc_hole_ty = fun_ty, sc_cont = cont })
    
    2477
    +  | UnSimplified arg_env <- arg_se
    
    2478
    +  , isStrictArgInfo fun_info  -- Strict arguments
    
    2479
    +  , seCaseCase env            -- But only when case-of-case is on.
    
    2480
    +                              -- See Note [Case-of-case and full laziness]
    
    2481
    +  = simplExprF (arg_env `setInScopeFromE` env) arg
    
    2475 2482
                    (StrictArg { sc_fun = fun_info, sc_fun_ty = fun_ty
    
    2476
    -                          , sc_dup = Simplified
    
    2483
    +                          , sc_dup = NoDup
    
    2477 2484
                               , sc_cont = cont })
    
    2478 2485
                     -- Note [Shadowing in the Simplifier]
    
    2479 2486
     
    
    2480
    -  -- Lazy arguments
    
    2481
    -  | otherwise
    
    2482
    -        -- DO NOT float anything outside, hence simplExprC
    
    2483
    -        -- There is no benefit (unlike in a let-binding), and we'd
    
    2484
    -        -- have to be very careful about bogus strictness through
    
    2485
    -        -- floating a demanded let.
    
    2486
    -  = do  { (_, _, arg') <- simplLazyArg env dup_flag fun_ty (Just fun_info) arg_se arg
    
    2487
    +  | otherwise      -- Lazy, or already simplified arguments
    
    2488
    +  -- DO NOT float anything outside, hence simplExprC
    
    2489
    +  -- There is no benefit (unlike in a let-binding), and we'd
    
    2490
    +  -- have to be very careful about bogus strictness through
    
    2491
    +  -- floating a demanded let.
    
    2492
    +  = do  { (_, arg') <- simplArg env fun_ty (Just fun_info) arg_se arg
    
    2487 2493
             ; rebuildCall env (addValArgTo fun_info  arg' fun_ty) cont }
    
    2488 2494
     
    
    2489 2495
     ---------- No further useful info, revert to generic rebuild ------------
    
    ... ... @@ -2508,7 +2514,7 @@ tryInlining env logger var cont
    2508 2514
       = return Nothing
    
    2509 2515
     
    
    2510 2516
       where
    
    2511
    -    (lone_variable, arg_infos, call_cont) = contArgs cont
    
    2517
    +    (lone_variable, arg_infos, call_cont) = contArgs env cont
    
    2512 2518
         interesting_cont = interestingCallContext env call_cont
    
    2513 2519
     
    
    2514 2520
         log_inlining doc
    
    ... ... @@ -2685,8 +2691,8 @@ fireRuleAFTER env rule_match arg_specs cont
    2685 2691
            , rm_binds = wrap, rm_bndrs = bndrs } <- rule_match
    
    2686 2692
       = do { let env' = env `addNewInScopeIds` bndrs
    
    2687 2693
            ; (floats, e') <- simplExprF env' rhs $
    
    2688
    -                         pushArgs env' (exprType rhs) rhs_args $
    
    2689
    -                         pushArgSpecs env' (drop (ruleArity rule) arg_specs) cont
    
    2694
    +                         pushArgs (exprType rhs) rhs_args $
    
    2695
    +                         pushArgSpecs (drop (ruleArity rule) arg_specs) cont
    
    2690 2696
            ; return $
    
    2691 2697
              if isEmptyBindWrapper wrap  -- Not very pretty
    
    2692 2698
              then (floats, e')
    
    ... ... @@ -2797,9 +2803,8 @@ trySeqRules in_env scrut rhs cont
    2797 2803
                      , ValArg { as_arg = no_cast_scrut
    
    2798 2804
                               , as_dmd = seqDmd
    
    2799 2805
                               , as_hole_ty = res3_ty } ]
    
    2800
    -    rule_cont = ApplyToVal { sc_dup = NoDup, sc_arg = rhs
    
    2801
    -                           , sc_env = in_env, sc_cont = cont
    
    2802
    -                           , sc_hole_ty = res4_ty }
    
    2806
    +    rule_cont = ApplyToVal { sc_env = UnSimplified in_env, sc_arg = rhs
    
    2807
    +                           , sc_cont = cont, sc_hole_ty = res4_ty }
    
    2803 2808
     
    
    2804 2809
         out_args = [Type rhs_rep, Type scrut_ty, Type rhs_ty, no_cast_scrut]
    
    2805 2810
                    -- Cheaper than (map argSpecArg out_arg_specs)
    
    ... ... @@ -3143,7 +3148,7 @@ We want to bind x' to x, and not to a duplicated (a,b)).
    3143 3148
     --      Eliminate the case if possible
    
    3144 3149
     
    
    3145 3150
     rebuildCase, reallyRebuildCase
    
    3146
    -   :: SimplEnv
    
    3151
    +   :: (SimplAltFlag, SimplEnv)
    
    3147 3152
        -> OutExpr          -- Scrutinee
    
    3148 3153
        -> InId             -- Case binder
    
    3149 3154
        -> [InAlt]          -- Alternatives (increasing order)
    
    ... ... @@ -3154,14 +3159,14 @@ rebuildCase, reallyRebuildCase
    3154 3159
     --      1. Eliminate the case if there's a known constructor
    
    3155 3160
     --------------------------------------------------
    
    3156 3161
     
    
    3157
    -rebuildCase env scrut case_bndr alts cont
    
    3162
    +rebuildCase (saf,env) scrut case_bndr alts cont
    
    3158 3163
       | Lit lit <- scrut    -- No need for same treatment as constructors
    
    3159 3164
                             -- because literals are inlined more vigorously
    
    3160 3165
       , not (litIsLifted lit)
    
    3161 3166
       = do  { tick (KnownBranch case_bndr)
    
    3162 3167
             ; case findAlt (LitAlt lit) alts of
    
    3163 3168
                 Nothing             -> missingAlt env case_bndr alts cont
    
    3164
    -            Just (Alt _ bs rhs) -> simple_rhs env scrut bs rhs }
    
    3169
    +            Just (Alt _ bs rhs) -> simpl_rhs env scrut bs rhs }
    
    3165 3170
     
    
    3166 3171
       | Just (in_scope', wfloats, con, ty_args, other_args)
    
    3167 3172
           <- exprIsConApp_maybe (getUnfoldingInRuleMatch env) scrut
    
    ... ... @@ -3177,24 +3182,24 @@ rebuildCase env scrut case_bndr alts cont
    3177 3182
             ; wrapDataConFloats env wfloats case_bndr cont $
    
    3178 3183
               case findAlt (DataAlt con) alts of
    
    3179 3184
                 Nothing                   -> missingAlt env0 case_bndr alts cont
    
    3180
    -            Just (Alt DEFAULT bs rhs) -> simple_rhs env0 case_bndr_rhs bs rhs
    
    3181
    -            Just (Alt _       bs rhs) -> knownCon env0 scrut con
    
    3182
    -                                                  other_args case_bndr bs rhs cont
    
    3185
    +            Just (Alt DEFAULT bs rhs) -> simpl_rhs env0 case_bndr_rhs bs rhs
    
    3186
    +            Just (Alt _       bs rhs) -> knownCon env0 scrut con other_args
    
    3187
    +                                                  case_bndr bs rhs cont
    
    3183 3188
             }
    
    3184 3189
       where
    
    3185
    -    simple_rhs env case_bndr_rhs bs rhs =
    
    3186
    -      assert (null bs) $
    
    3187
    -      do { (floats1, env') <- simplAuxBind "rebuildCase" env case_bndr case_bndr_rhs
    
    3188
    -             -- scrut is a constructor application,
    
    3189
    -             -- hence satisfies let-can-float invariant
    
    3190
    -         ; (floats2, expr') <- simplExprF env' rhs cont
    
    3191
    -         ; return (floats1 `addFloats` floats2, expr') }
    
    3190
    +    simpl_rhs env case_bndr_rhs bs rhs
    
    3191
    +      = assert (null bs) $
    
    3192
    +        do { (floats1, env') <- simplAuxBind (saf,env) case_bndr case_bndr_rhs
    
    3193
    +               -- scrut is a constructor application,
    
    3194
    +               -- hence satisfies let-can-float invariant
    
    3195
    +           ; (floats2, expr') <- simplExprF env' rhs cont
    
    3196
    +           ; return (floats1 `addFloats` floats2, expr') }
    
    3192 3197
     
    
    3193 3198
     --------------------------------------------------
    
    3194 3199
     --      2. Eliminate the case if scrutinee is evaluated
    
    3195 3200
     --------------------------------------------------
    
    3196 3201
     
    
    3197
    -rebuildCase env scrut case_bndr alts@[Alt _ bndrs rhs] cont
    
    3202
    +rebuildCase (saf,env) scrut case_bndr alts@[Alt _ bndrs rhs] cont
    
    3198 3203
       -- See if we can get rid of the case altogether
    
    3199 3204
       -- See Note [Case elimination]
    
    3200 3205
       -- mkCase made sure that if all the alternatives are equal,
    
    ... ... @@ -3218,7 +3223,9 @@ rebuildCase env scrut case_bndr alts@[Alt _ bndrs rhs] cont
    3218 3223
       | all_dead_bndrs
    
    3219 3224
       , doCaseToLet scrut case_bndr
    
    3220 3225
       = do { tick (CaseElim case_bndr)
    
    3221
    -       ; (floats1, env')  <- simplAuxBind "rebuildCaseAlt1" env case_bndr scrut
    
    3226
    +       ; (floats1, env')  <- simplAuxBind (saf,env) case_bndr scrut
    
    3227
    +         -- simplAuxBind can create a substitution for case_bndr,
    
    3228
    +         -- so we must re-simpify `rhs` regardless of `saf`
    
    3222 3229
            ; (floats2, expr') <- simplExprF env' rhs cont
    
    3223 3230
            ; return (floats1 `addFloats` floats2, expr') }
    
    3224 3231
     
    
    ... ... @@ -3230,22 +3237,22 @@ rebuildCase env scrut case_bndr alts@[Alt _ bndrs rhs] cont
    3230 3237
       = do { mb_rule <- trySeqRules env scrut rhs cont
    
    3231 3238
            ; case mb_rule of
    
    3232 3239
                Just (rm, ass, rcont) -> fireRuleAFTER env rm ass rcont
    
    3233
    -           Nothing               -> reallyRebuildCase env scrut case_bndr alts cont }
    
    3240
    +           Nothing               -> reallyRebuildCase (saf,env) scrut case_bndr alts cont }
    
    3234 3241
     
    
    3235 3242
       where
    
    3236 3243
         all_dead_bndrs = all isDeadBinder bndrs       -- bndrs are [InId]
    
    3237 3244
         is_plain_seq   = all_dead_bndrs && isDeadBinder case_bndr -- Evaluation *only* for effect
    
    3238 3245
     
    
    3239
    -rebuildCase env scrut case_bndr alts cont
    
    3246
    +rebuildCase (saf,env) scrut case_bndr alts cont
    
    3240 3247
     --------------------------------------------------
    
    3241 3248
     --      3. Primop-related case-rules
    
    3242 3249
     --------------------------------------------------
    
    3243 3250
     
    
    3244 3251
       | Just (scrut', case_bndr', alts') <- caseRules2 (sePlatform env) scrut case_bndr alts
    
    3245
    -  = reallyRebuildCase env scrut' case_bndr' alts' cont
    
    3252
    +  = reallyRebuildCase (saf,env) scrut' case_bndr' alts' cont
    
    3246 3253
     
    
    3247 3254
       | otherwise
    
    3248
    -  = reallyRebuildCase env scrut case_bndr alts cont
    
    3255
    +  = reallyRebuildCase (saf,env) scrut case_bndr alts cont
    
    3249 3256
     
    
    3250 3257
     doCaseToLet :: OutExpr          -- Scrutinee
    
    3251 3258
                 -> InId             -- Case binder
    
    ... ... @@ -3276,17 +3283,17 @@ doCaseToLet scrut case_bndr
    3276 3283
     --      3. Catch-all case
    
    3277 3284
     --------------------------------------------------
    
    3278 3285
     
    
    3279
    -reallyRebuildCase env scrut case_bndr alts cont
    
    3286
    +reallyRebuildCase (saf,env) scrut case_bndr alts cont
    
    3280 3287
       | not (seCaseCase env)    -- Only when case-of-case is on.
    
    3281 3288
                                 -- See GHC.Driver.Config.Core.Opt.Simplify
    
    3282 3289
                                 --    Note [Case-of-case and full laziness]
    
    3283
    -  = do { case_expr <- simplAlts env scrut case_bndr alts
    
    3290
    +  = do { case_expr <- simplAlts (saf,env) scrut case_bndr alts
    
    3284 3291
                                     (mkBoringStop (contHoleType cont))
    
    3285 3292
            ; rebuild env case_expr cont }
    
    3286 3293
     
    
    3287 3294
       | otherwise
    
    3288 3295
       = do { (floats, env', cont') <- mkDupableCaseCont env alts cont
    
    3289
    -       ; case_expr <- simplAlts env' scrut
    
    3296
    +       ; case_expr <- simplAlts (saf,env') scrut
    
    3290 3297
                                     (scaleIdBy holeScaling case_bndr)
    
    3291 3298
                                     (scaleAltsBy holeScaling alts)
    
    3292 3299
                                     cont'
    
    ... ... @@ -3427,24 +3434,23 @@ scale the entire case we are simplifying, by a scaling factor which can be
    3427 3434
     computed in the continuation (with function `contHoleScaling`).
    
    3428 3435
     -}
    
    3429 3436
     
    
    3430
    -simplAlts :: SimplEnv
    
    3431
    -          -> OutExpr         -- Scrutinee
    
    3432
    -          -> InId            -- Case binder
    
    3433
    -          -> [InAlt]         -- Non-empty
    
    3437
    +simplAlts :: (SimplAltFlag, SimplEnv)
    
    3438
    +          -> OutExpr                       -- Scrutinee
    
    3439
    +          -> InId -> [InAlt]  -- Alts (non-empty)
    
    3434 3440
               -> SimplCont
    
    3435 3441
               -> SimplM OutExpr  -- Returns the complete simplified case expression
    
    3436 3442
     
    
    3437
    -simplAlts env0 scrut case_bndr alts cont'
    
    3443
    +simplAlts (saf,env0) scrut case_bndr alts cont'
    
    3438 3444
       = do  { traceSmpl "simplAlts" (vcat [ ppr case_bndr
    
    3439 3445
                                           , text "cont':" <+> ppr cont'
    
    3440 3446
                                           , text "in_scope" <+> ppr (seInScope env0) ])
    
    3441
    -        ; (env1, case_bndr1) <- simplBinder env0 case_bndr
    
    3447
    +        ; (env1, case_bndr1) <- simplAltIdBinder (saf,env0) case_bndr
    
    3442 3448
             ; let case_bndr2 = case_bndr1 `setIdUnfolding` evaldUnfolding
    
    3443 3449
                   env2       = modifyInScope env1 case_bndr2
    
    3444 3450
                   -- See Note [Case binder evaluated-ness]
    
    3445 3451
                   fam_envs   = seFamEnvs env0
    
    3446 3452
     
    
    3447
    -        ; (alt_env', scrut', case_bndr') <- improveSeq fam_envs env2 scrut
    
    3453
    +        ; (alt_env', scrut', case_bndr') <- improveSeq fam_envs (saf,env2) scrut
    
    3448 3454
                                                            case_bndr case_bndr2 alts
    
    3449 3455
     
    
    3450 3456
             ; (imposs_deflt_cons, in_alts) <- prepareAlts scrut' case_bndr alts
    
    ... ... @@ -3454,7 +3460,7 @@ simplAlts env0 scrut case_bndr alts cont'
    3454 3460
               --     See Note [Shadowing in prepareAlts] in GHC.Core.Opt.Simplify.Utils
    
    3455 3461
     
    
    3456 3462
             ; alts' <- forM in_alts $
    
    3457
    -            simplAlt alt_env' (Just scrut') imposs_deflt_cons
    
    3463
    +            simplAlt (saf,alt_env') (Just scrut') imposs_deflt_cons
    
    3458 3464
                          case_bndr' (scrutOkForBinderSwap scrut) cont'
    
    3459 3465
     
    
    3460 3466
             ; let alts_ty' = contResultType cont'
    
    ... ... @@ -3464,23 +3470,25 @@ simplAlts env0 scrut case_bndr alts cont'
    3464 3470
     
    
    3465 3471
     
    
    3466 3472
     ------------------------------------
    
    3467
    -improveSeq :: (FamInstEnv, FamInstEnv) -> SimplEnv
    
    3473
    +improveSeq :: (FamInstEnv, FamInstEnv)
    
    3474
    +           -> (SimplAltFlag, SimplEnv)
    
    3468 3475
                -> OutExpr -> InId -> OutId -> [InAlt]
    
    3469 3476
                -> SimplM (SimplEnv, OutExpr, OutId)
    
    3470 3477
     -- Note [Improving seq]
    
    3471
    -improveSeq fam_envs env scrut case_bndr case_bndr1 [Alt DEFAULT _ _]
    
    3472
    -  | Just (Reduction co ty2) <- topNormaliseType_maybe fam_envs (idType case_bndr1)
    
    3478
    +improveSeq fam_envs (saf,env) scrut case_bndr case_bndr1 [Alt DEFAULT _ _]
    
    3479
    +  | SAF_In <- saf  -- improveSeq extends the substitution; not allowed for SAF_Out
    
    3480
    +  , Just (Reduction co ty2) <- topNormaliseType_maybe fam_envs (idType case_bndr1)
    
    3473 3481
       = do { case_bndr2 <- newId (fsLit "nt") ManyTy ty2
    
    3474 3482
             ; let rhs  = DoneEx (Var case_bndr2 `Cast` mkSymCo co) NotJoinPoint
    
    3475 3483
                   env2 = extendIdSubst env case_bndr rhs
    
    3476 3484
             ; return (env2, scrut `Cast` co, case_bndr2) }
    
    3477 3485
     
    
    3478
    -improveSeq _ env scrut _ case_bndr1 _
    
    3486
    +improveSeq _ (_,env) scrut _ case_bndr1 _
    
    3479 3487
       = return (env, scrut, case_bndr1)
    
    3480 3488
     
    
    3481 3489
     
    
    3482 3490
     ------------------------------------
    
    3483
    -simplAlt :: SimplEnv
    
    3491
    +simplAlt :: (SimplAltFlag, SimplEnv)
    
    3484 3492
              -> Maybe OutExpr       -- The scrutinee
    
    3485 3493
              -> [AltCon]            -- These constructors can't be present when
    
    3486 3494
                                     -- matching the DEFAULT alternative
    
    ... ... @@ -3491,26 +3499,27 @@ simplAlt :: SimplEnv
    3491 3499
              -> InAlt
    
    3492 3500
              -> SimplM OutAlt
    
    3493 3501
     
    
    3494
    -simplAlt env _scrut' imposs_deflt_cons case_bndr' bndr_swap' cont' (Alt DEFAULT bndrs rhs)
    
    3502
    +simplAlt (saf,env) _scrut' imposs_deflt_cons case_bndr' bndr_swap' cont' (Alt DEFAULT bndrs rhs)
    
    3495 3503
       = assert (null bndrs) $
    
    3496 3504
         do  { let env' = addDefaultUnfoldings env case_bndr' bndr_swap' imposs_deflt_cons
    
    3497
    -        ; rhs' <- simplExprC env' rhs cont'
    
    3505
    +        ; rhs' <- simplAltExprC (saf,env') rhs cont'
    
    3498 3506
             ; return (Alt DEFAULT [] rhs') }
    
    3499 3507
     
    
    3500
    -simplAlt env _scrut' _ case_bndr' bndr_swap' cont' (Alt (LitAlt lit) bndrs rhs)
    
    3508
    +simplAlt (saf,env) _scrut' _ case_bndr' bndr_swap' cont' (Alt (LitAlt lit) bndrs rhs)
    
    3501 3509
       = assert (null bndrs) $
    
    3502 3510
         do  { let env' = addAltUnfoldings env case_bndr' bndr_swap' (Lit lit)
    
    3503
    -        ; rhs' <- simplExprC env' rhs cont'
    
    3511
    +        ; rhs' <- simplAltExprC (saf,env') rhs cont'
    
    3504 3512
             ; return (Alt (LitAlt lit) [] rhs') }
    
    3505 3513
     
    
    3506
    -simplAlt env scrut' _ case_bndr' bndr_swap' cont' (Alt (DataAlt con) vs rhs)
    
    3514
    +simplAlt (saf,env) scrut' _ case_bndr' bndr_swap' cont' (Alt (DataAlt con) vs rhs)
    
    3507 3515
       = do  { -- See Note [Adding evaluatedness info to pattern-bound variables]
    
    3508 3516
               -- and Note [DataAlt occ info]
    
    3509 3517
             ; let vs_with_info = adjustFieldsIdInfo scrut' case_bndr' bndr_swap' con vs
    
    3510 3518
               -- Adjust evaluated-ness and occ-info flags before `simplBinders`
    
    3511 3519
               -- because the latter extends the in-scope set, which propagates this
    
    3512 3520
               -- adjusted info to use sites.
    
    3513
    -        ; (env', vs') <- simplBinders env vs_with_info
    
    3521
    +
    
    3522
    +        ; (env', vs') <- simplAltBinders (saf,env) vs_with_info
    
    3514 3523
     
    
    3515 3524
                     -- Bind the case-binder to (con args)
    
    3516 3525
             ; let inst_tys' = tyConAppArgs (idType case_bndr')
    
    ... ... @@ -3518,7 +3527,7 @@ simplAlt env scrut' _ case_bndr' bndr_swap' cont' (Alt (DataAlt con) vs rhs)
    3518 3527
                   con_app = mkConApp2 con inst_tys' vs'
    
    3519 3528
                   env''   = addAltUnfoldings env' case_bndr' bndr_swap' con_app
    
    3520 3529
     
    
    3521
    -        ; rhs' <- simplExprC env'' rhs cont'
    
    3530
    +        ; rhs' <- simplAltExprC (saf,env'') rhs cont'
    
    3522 3531
             ; return (Alt (DataAlt con) vs' rhs') }
    
    3523 3532
     
    
    3524 3533
     {- Note [Adding evaluatedness info to pattern-bound variables]
    
    ... ... @@ -3665,6 +3674,40 @@ zapBndrOccInfo keep_occ_info pat_id
    3665 3674
       | keep_occ_info = pat_id
    
    3666 3675
       | otherwise     = zapIdOccInfo pat_id
    
    3667 3676
     
    
    3677
    +
    
    3678
    +data SimplAltFlag = SAF_In   -- Must run the simplifier, or at least substitution
    
    3679
    +                  | SAF_Out  -- No need to run the simplifier; substitution is empty
    
    3680
    +
    
    3681
    +mkAltEnv :: SimplEnvIS -> StaticEnv -> (SimplAltFlag, SimplEnv)
    
    3682
    +mkAltEnv env (Simplified {})   = (SAF_Out, env)
    
    3683
    +mkAltEnv env (UnSimplified se) = (SAF_In,  se`setInScopeFromE` env)
    
    3684
    +
    
    3685
    +simplAltBinders :: (SimplAltFlag, SimplEnv) -> [Var] -> SimplM (SimplEnv, [OutVar])
    
    3686
    +simplAltBinders (saf,env) bs
    
    3687
    +  = case saf of
    
    3688
    +      SAF_Out -> return (env, bs)
    
    3689
    +      SAF_In  -> simplBinders env bs
    
    3690
    +
    
    3691
    +simplAltIdBinder :: (SimplAltFlag, SimplEnv) -> Id -> SimplM (SimplEnv, OutId)
    
    3692
    +simplAltIdBinder (saf,env) bndr
    
    3693
    +  = case saf of
    
    3694
    +      SAF_Out -> return (env, bndr)
    
    3695
    +      SAF_In ->  simplNonRecBndr env bndr
    
    3696
    +
    
    3697
    +simplAltExprF :: HasDebugCallStack
    
    3698
    +              => (SimplAltFlag, SimplEnv) -> CoreExpr -> SimplCont
    
    3699
    +              -> SimplM (SimplFloats, OutExpr)
    
    3700
    +simplAltExprF (saf,env) expr cont
    
    3701
    +  = case saf of
    
    3702
    +      SAF_Out -> simplOutExpr env expr cont
    
    3703
    +      SAF_In  -> simplExprF   env expr cont
    
    3704
    +
    
    3705
    +simplAltExprC :: (SimplAltFlag, SimplEnv) -> CoreExpr -> SimplCont -> SimplM OutExpr
    
    3706
    +simplAltExprC env expr cont
    
    3707
    +  = do { (floats, expr') <- simplAltExprF env expr cont
    
    3708
    +       ; return (wrapFloats floats expr') }
    
    3709
    +
    
    3710
    +
    
    3668 3711
     {- Note [Case binder evaluated-ness]
    
    3669 3712
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3670 3713
     We pin on a (OtherCon []) unfolding to the case-binder of a Case,
    
    ... ... @@ -3799,12 +3842,13 @@ wrapDataConFloats env wfloats case_bndr cont thing_inside
    3799 3842
     
    
    3800 3843
     
    
    3801 3844
     knownCon :: SimplEnv
    
    3802
    -         -> OutExpr                            -- The scrutinee
    
    3803
    -         -> DataCon -> [OutExpr]               -- The scrutinee (in pieces)
    
    3804
    -         -> InId -> [InBndr] -> InExpr         -- The alternative
    
    3845
    +         -> OutExpr                                  -- The scrutinee
    
    3846
    +         -> DataCon -> [OutExpr]                     -- The scrutinee (in pieces)
    
    3847
    +         -> InId -> [InBndr] -> InExpr  -- The alternative
    
    3805 3848
              -> SimplCont
    
    3806 3849
              -> SimplM (SimplFloats, OutExpr)
    
    3807
    -
    
    3850
    +-- We do not pass SimplAltFlag to knownCon because we really do want
    
    3851
    +-- to simplify the RHS, with the new knowledge about the case-simplification
    
    3808 3852
     knownCon env scrut dc dc_args case_bndr alt_bndrs rhs cont
    
    3809 3853
       = do  { (floats1, env1)  <- bind_args env alt_bndrs dc_args
    
    3810 3854
             ; (floats2, env2)  <- bind_case_bndr env1
    
    ... ... @@ -3831,7 +3875,8 @@ knownCon env scrut dc dc_args case_bndr alt_bndrs rhs cont
    3831 3875
                  -- occur in the RHS; and simplAuxBind may therefore discard it.
    
    3832 3876
                  -- Nevertheless we must keep it if the case-binder is alive,
    
    3833 3877
                  -- because it may be used in the con_app.  See Note [knownCon occ info]
    
    3834
    -           ; (floats1, env2) <- simplAuxBind "knownCon" env' b' arg  -- arg satisfies let-can-float invariant
    
    3878
    +           ; (floats1, env2) <- simplAuxBind (SAF_In,env') b' arg
    
    3879
    +                                -- arg satisfies let-can-float invariant
    
    3835 3880
                ; (floats2, env3) <- bind_args env2 bs' args
    
    3836 3881
                ; return (floats1 `addFloats` floats2, env3) }
    
    3837 3882
     
    
    ... ... @@ -3855,11 +3900,11 @@ knownCon env scrut dc dc_args case_bndr alt_bndrs rhs cont
    3855 3900
             return ( emptyFloats env
    
    3856 3901
                    , extendIdSubst env case_bndr (DoneEx scrut NotJoinPoint))
    
    3857 3902
     
    
    3858
    -      | Just env' <- preInlineUnconditionally env NotTopLevel case_bndr NoDup con_app env
    
    3903
    +      | Just env' <- preInlineUnconditionally env NotTopLevel case_bndr con_app (UnSimplified env)
    
    3859 3904
           = return (emptyFloats env', env')
    
    3860 3905
     
    
    3861 3906
           | otherwise
    
    3862
    -      = do { (env1, case_bndr1)    <- simplNonRecBndr env case_bndr
    
    3907
    +      = do { (env1, case_bndr1) <- simplAltIdBinder (SAF_In,env) case_bndr
    
    3863 3908
                ; simplLazyBind NotTopLevel NonRecursive
    
    3864 3909
                                (case_bndr,env) (case_bndr1,env1) (con_app,env) }
    
    3865 3910
     
    
    ... ... @@ -3918,9 +3963,9 @@ join points and inlining them away. See #4930.
    3918 3963
     -}
    
    3919 3964
     
    
    3920 3965
     --------------------
    
    3921
    -mkDupableCaseCont :: SimplEnv -> [InAlt] -> SimplCont
    
    3966
    +mkDupableCaseCont :: SimplEnvIS -> [InAlt] -> SimplCont
    
    3922 3967
                       -> SimplM ( SimplFloats  -- Join points (if any)
    
    3923
    -                            , SimplEnv     -- Use this for the alts
    
    3968
    +                            , SimplEnvIS   -- Use this for the alts
    
    3924 3969
                                 , SimplCont)
    
    3925 3970
     mkDupableCaseCont env alts cont
    
    3926 3971
       | altsWouldDup alts = do { (floats, cont) <- mkDupableCont env cont
    
    ... ... @@ -3940,7 +3985,7 @@ altsWouldDup (alt:alts)
    3940 3985
         is_bot_alt (Alt _ _ rhs) = exprIsDeadEnd rhs
    
    3941 3986
     
    
    3942 3987
     -------------------------
    
    3943
    -mkDupableCont :: SimplEnv
    
    3988
    +mkDupableCont :: SimplEnvIS
    
    3944 3989
                   -> SimplCont
    
    3945 3990
                   -> SimplM ( SimplFloats  -- Incoming SimplEnv augmented with
    
    3946 3991
                                            --   extra let/join-floats and in-scope variables
    
    ... ... @@ -3974,12 +4019,17 @@ mkDupableContWithDmds env dmds (TickIt t cont)
    3974 4019
             ; return (floats, TickIt t cont') }
    
    3975 4020
     
    
    3976 4021
     mkDupableContWithDmds env _
    
    3977
    -     (StrictBind { sc_bndr = bndr, sc_body = body, sc_from = from_what
    
    3978
    -                 , sc_env = se, sc_cont = cont})
    
    4022
    +     cont1@(StrictBind { sc_bndr = bndr, sc_body = body, sc_from = from_what
    
    4023
    +                       , sc_env = se, sc_cont = cont})
    
    3979 4024
     -- See Note [Duplicating StrictBind]
    
    3980 4025
     -- K[ let x = <> in b ]  -->   join j x = K[ b ]
    
    3981 4026
     --                             j <>
    
    3982
    -  = do { let sb_env = se `setInScopeFromE` env
    
    4027
    +  = do { let sb_env = case se of
    
    4028
    +                         UnSimplified static_env -> static_env `setInScopeFromE` env
    
    4029
    +                         Simplified {} -> pprPanic "mkDupableContWithDmds" (ppr se $$ ppr cont1)
    
    4030
    +                            -- The contIsDupable caught the OkDup case, and
    
    4031
    +                            -- we never build a StrictBind with a NoDup in it.
    
    4032
    +
    
    3983 4033
            ; (sb_env1, bndr')      <- simplBinder sb_env bndr
    
    3984 4034
            ; (floats1, join_inner) <- simplNonRecBody sb_env1 from_what body cont
    
    3985 4035
               -- No need to use mkDupableCont before simplNonRecBody; we
    
    ... ... @@ -4009,7 +4059,7 @@ mkDupableContWithDmds env _
    4009 4059
                     , StrictArg { sc_fun = fun { ai_args = args' }
    
    4010 4060
                                 , sc_cont = cont'
    
    4011 4061
                                 , sc_fun_ty = fun_ty
    
    4012
    -                            , sc_dup = OkToDup} ) }
    
    4062
    +                            , sc_dup = OkDup} ) }
    
    4013 4063
     
    
    4014 4064
       | otherwise
    
    4015 4065
       = -- Use Plan B of Note [Duplicating StrictArg]
    
    ... ... @@ -4038,7 +4088,7 @@ mkDupableContWithDmds env dmds
    4038 4088
                                         , sc_arg_ty = arg_ty, sc_hole_ty = hole_ty }) }
    
    4039 4089
     
    
    4040 4090
     mkDupableContWithDmds env dmds
    
    4041
    -    (ApplyToVal { sc_arg = arg, sc_dup = dup, sc_env = se
    
    4091
    +    (ApplyToVal { sc_arg = arg, sc_env = se
    
    4042 4092
                     , sc_cont = cont, sc_hole_ty = hole_ty })
    
    4043 4093
       =     -- e.g.         [...hole...] (...arg...)
    
    4044 4094
             --      ==>
    
    ... ... @@ -4048,18 +4098,12 @@ mkDupableContWithDmds env dmds
    4048 4098
         do  { let dmd:|cont_dmds = expectNonEmpty dmds
    
    4049 4099
             ; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont
    
    4050 4100
             ; let env' = env `setInScopeFromF` floats1
    
    4051
    -        ; (_, se', arg') <- simplLazyArg env' dup hole_ty Nothing se arg
    
    4052
    -        ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg'
    
    4101
    +        ; (_, arg') <- simplArg env' hole_ty Nothing se arg
    
    4102
    +        ; (let_floats2, triv_arg) <- makeTrivial env' NotTopLevel dmd (fsLit "karg") arg'
    
    4053 4103
             ; let all_floats = floats1 `addLetFloats` let_floats2
    
    4054 4104
             ; return ( all_floats
    
    4055
    -                 , ApplyToVal { sc_arg = arg''
    
    4056
    -                              , sc_env = se' `setInScopeFromF` all_floats
    
    4057
    -                                         -- Ensure that sc_env includes the free vars of
    
    4058
    -                                         -- arg'' in its in-scope set, even if makeTrivial
    
    4059
    -                                         -- has turned arg'' into a fresh variable
    
    4060
    -                                         -- See Note [StaticEnv invariant] in GHC.Core.Opt.Simplify.Utils
    
    4061
    -                              , sc_dup = OkToDup, sc_cont = cont'
    
    4062
    -                              , sc_hole_ty = hole_ty }) }
    
    4105
    +                 , ApplyToVal { sc_arg = triv_arg, sc_env = Simplified OkDup
    
    4106
    +                              , sc_cont = cont', sc_hole_ty = hole_ty }) }
    
    4063 4107
     
    
    4064 4108
     mkDupableContWithDmds env _
    
    4065 4109
         (Select { sc_bndr = case_bndr, sc_alts = alts, sc_env = se, sc_cont = cont })
    
    ... ... @@ -4069,16 +4113,20 @@ mkDupableContWithDmds env _
    4069 4113
             --              in case [...hole...] of { pi -> ji xij }
    
    4070 4114
             -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable
    
    4071 4115
         do  { tick (CaseOfCase case_bndr)
    
    4072
    -        ; (floats, alt_env, alt_cont) <- mkDupableCaseCont (se `setInScopeFromE` env) alts cont
    
    4116
    +        ; (floats, env1, alt_cont) <- mkDupableCaseCont env alts cont
    
    4073 4117
                     -- NB: We call mkDupableCaseCont here to make cont duplicable
    
    4074 4118
                     --     (if necessary, depending on the number of alts)
    
    4075 4119
                     -- And this is important: see Note [Fusing case continuations]
    
    4076 4120
     
    
    4077 4121
             ; let cont_scaling = contHoleScaling cont
    
    4122
    +              (saf, alt_env) = mkAltEnv env1 se
    
    4123
    +
    
    4078 4124
               -- See Note [Scaling in case-of-case]
    
    4079
    -        ; (alt_env', case_bndr') <- simplBinder alt_env (scaleIdBy cont_scaling case_bndr)
    
    4125
    +        ; (alt_env1, case_bndr') <- simplAltIdBinder (saf,alt_env) $
    
    4126
    +                                    scaleIdBy cont_scaling case_bndr
    
    4127
    +
    
    4080 4128
             ; alts' <- forM (scaleAltsBy cont_scaling alts) $
    
    4081
    -            simplAlt alt_env' Nothing [] case_bndr' NoBinderSwap alt_cont
    
    4129
    +            simplAlt (saf,alt_env1) Nothing [] case_bndr' NoBinderSwap alt_cont
    
    4082 4130
                     -- Safe to say that there are no handled-cons for the DEFAULT case
    
    4083 4131
                     -- NB: simplBinder does not zap deadness occ-info, so
    
    4084 4132
                     -- a dead case_bndr' will still advertise its deadness
    
    ... ... @@ -4097,11 +4145,8 @@ mkDupableContWithDmds env _
    4097 4145
             ; let all_floats = floats `addJoinFloats` join_floats
    
    4098 4146
                                -- Note [Duplicated env]
    
    4099 4147
             ; return (all_floats
    
    4100
    -                 , Select { sc_dup  = OkToDup
    
    4101
    -                          , sc_bndr = case_bndr'
    
    4102
    -                          , sc_alts = alts''
    
    4103
    -                          , sc_env  = zapSubstEnv se `setInScopeFromF` all_floats
    
    4104
    -                                      -- See Note [StaticEnv invariant] in GHC.Core.Opt.Simplify.Utils
    
    4148
    +                 , Select { sc_bndr = case_bndr', sc_alts = alts''
    
    4149
    +                          , sc_env  = Simplified OkDup
    
    4105 4150
                               , sc_cont = mkBoringStop (contResultType cont) } ) }
    
    4106 4151
     
    
    4107 4152
     mkDupableStrictBind :: SimplEnv -> OutId -> OutExpr -> OutType
    
    ... ... @@ -4112,10 +4157,9 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty
    4112 4157
       = return (emptyFloats env
    
    4113 4158
                , StrictBind { sc_bndr = arg_bndr
    
    4114 4159
                             , sc_body = join_rhs
    
    4115
    -                        , sc_env  = zapSubstEnv env
    
    4160
    +                        , sc_env  = Simplified OkDup
    
    4161
    +                          -- See Note [StaticEnv] in GHC.Core.Opt.Simplify.Utils
    
    4116 4162
                             , sc_from = FromLet
    
    4117
    -                          -- See Note [StaticEnv invariant] in GHC.Core.Opt.Simplify.Utils
    
    4118
    -                        , sc_dup  = OkToDup
    
    4119 4163
                             , sc_cont = mkBoringStop res_ty } )
    
    4120 4164
       | otherwise
    
    4121 4165
       = do { join_bndr <- newJoinId [arg_bndr] res_ty
    
    ... ... @@ -4127,7 +4171,7 @@ mkDupableStrictBind env arg_bndr join_rhs res_ty
    4127 4171
                       unitJoinFloat                   $
    
    4128 4172
                       NonRec join_bndr                $
    
    4129 4173
                       Lam (setOneShotLambda arg_bndr) join_rhs
    
    4130
    -                , StrictArg { sc_dup    = OkToDup
    
    4174
    +                , StrictArg { sc_dup    = OkDup
    
    4131 4175
                                 , sc_fun    = arg_info
    
    4132 4176
                                 , sc_fun_ty = idType join_bndr
    
    4133 4177
                                 , sc_cont   = mkBoringStop res_ty
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -21,7 +21,8 @@ module GHC.Core.Opt.Simplify.Utils (
    21 21
             BindContext(..), bindContextLevel,
    
    22 22
     
    
    23 23
             -- The continuation type
    
    24
    -        SimplCont(..), DupFlag(..), FromWhat(..), StaticEnv,
    
    24
    +        SimplCont(..), DupFlag(..), FromWhat(..),
    
    25
    +        StaticEnv(..),
    
    25 26
             isSimplified, contIsStop,
    
    26 27
             contIsDupable, contResultType, contHoleType, contHoleScaling,
    
    27 28
             contIsTrivial, contArgs, contIsRhs,
    
    ... ... @@ -171,11 +172,10 @@ data SimplCont
    171 172
           , sc_cont :: SimplCont }
    
    172 173
     
    
    173 174
       | ApplyToVal         -- (ApplyToVal arg K)[e] = K[ e arg ]
    
    174
    -      { sc_dup     :: DupFlag   -- See Note [DupFlag invariants]
    
    175
    -      , sc_hole_ty :: OutType   -- Type of the function, presumably (forall a. blah)
    
    175
    +      { sc_hole_ty :: OutType   -- Type of the function, presumably (forall a. blah)
    
    176 176
                                     -- See Note [The hole type in ApplyToTy]
    
    177
    -      , sc_arg  :: InExpr       -- The argument,
    
    178
    -      , sc_env  :: StaticEnv    -- see Note [StaticEnv invariant]
    
    177
    +      , sc_env  :: StaticEnv    -- See Note [StaticEnv]
    
    178
    +      , sc_arg  :: CoreExpr     -- The argument,
    
    179 179
           , sc_cont :: SimplCont }
    
    180 180
     
    
    181 181
       | ApplyToTy          -- (ApplyToTy ty K)[e] = K[ e ty ]
    
    ... ... @@ -185,25 +185,24 @@ data SimplCont
    185 185
           , sc_cont    :: SimplCont }
    
    186 186
     
    
    187 187
       | Select             -- (Select alts K)[e] = K[ case e of alts ]
    
    188
    -      { sc_dup  :: DupFlag        -- See Note [DupFlag invariants]
    
    189
    -      , sc_bndr :: InId           -- case binder
    
    190
    -      , sc_alts :: [InAlt]        -- Alternatives
    
    191
    -      , sc_env  :: StaticEnv      -- See Note [StaticEnv invariant]
    
    188
    +      { sc_env  :: StaticEnv      -- See Note [StaticEnv]
    
    189
    +      , sc_bndr :: Id             -- Case binder
    
    190
    +      , sc_alts :: [CoreAlt]      -- Alternatives
    
    192 191
           , sc_cont :: SimplCont }
    
    193 192
     
    
    194 193
       -- The two strict forms have no DupFlag, because we never duplicate them
    
    195 194
       | StrictBind          -- (StrictBind x b K)[e] = let x = e in K[b]
    
    196 195
                             --       or, equivalently,  = K[ (\x.b) e ]
    
    197
    -      { sc_dup   :: DupFlag        -- See Note [DupFlag invariants]
    
    198
    -      , sc_from  :: FromWhat
    
    199
    -      , sc_bndr  :: InId
    
    200
    -      , sc_body  :: InExpr
    
    201
    -      , sc_env   :: StaticEnv      -- Static env for both sc_bndr (stable unfolding thereof)
    
    202
    -                                   -- and sc_body.  Also see Note [StaticEnv invariant]
    
    196
    +      { sc_from  :: FromWhat
    
    197
    +      , sc_env   :: StaticEnv  -- See Note [StaticEnv]
    
    198
    +                               -- The sc_env in StrictBind is never (Simplified NoDup)
    
    199
    +      , sc_bndr  :: Id
    
    200
    +      , sc_body  :: CoreExpr
    
    201
    +
    
    203 202
           , sc_cont  :: SimplCont }
    
    204 203
     
    
    205 204
       | StrictArg           -- (StrictArg (f e1 ..en) K)[e] = K[ f e1 .. en e ]
    
    206
    -      { sc_dup  :: DupFlag     -- Always Simplified or OkToDup
    
    205
    +      { sc_dup :: DupFlag
    
    207 206
           , sc_fun  :: ArgInfo     -- Specifies f, e1..en, Whether f has rules, etc
    
    208 207
                                    --     plus demands and discount flags for *this* arg
    
    209 208
                                    --          and further args
    
    ... ... @@ -217,60 +216,82 @@ data SimplCont
    217 216
             CoreTickish     -- Tick tickish <hole>
    
    218 217
             SimplCont
    
    219 218
     
    
    220
    -type StaticEnv = SimplEnv       -- Just the static part is relevant
    
    219
    +data StaticEnv  -- See Note [StaticEnv]
    
    220
    +  = Simplified DupFlag       -- No static env needed
    
    221
    +  | UnSimplified SimplEnv    -- Just the static part is relevant
    
    221 222
     
    
    222 223
     data FromWhat = FromLet | FromBeta Levity
    
    223 224
     
    
    224
    --- See Note [DupFlag invariants]
    
    225
    -data DupFlag = NoDup       -- Unsimplified, might be big
    
    226
    -             | Simplified  -- Simplified
    
    227
    -             | OkToDup     -- Simplified and small
    
    228
    -
    
    229
    -isSimplified :: DupFlag -> Bool
    
    230
    -isSimplified NoDup = False
    
    231
    -isSimplified _     = True       -- Invariant: the subst-env is empty
    
    232
    -
    
    233
    -perhapsSubstTy :: DupFlag -> StaticEnv -> Type -> Type
    
    234
    -perhapsSubstTy dup env ty
    
    235
    -  | isSimplified dup = ty
    
    236
    -  | otherwise        = substTy env ty
    
    237
    -
    
    238
    -{- Note [StaticEnv invariant]
    
    239
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    240
    -We pair up an InExpr or InAlts with a StaticEnv, which establishes the
    
    241
    -lexical scope for that InExpr.
    
    242
    -
    
    243
    -When we simplify that InExpr/InAlts, we use
    
    244
    -  - Its captured StaticEnv
    
    245
    -  - Overriding its InScopeSet with the larger one at the
    
    246
    -    simplification point.
    
    247
    -
    
    248
    -Why override the InScopeSet?  Example:
    
    249
    -      (let y = ey in f) ex
    
    250
    -By the time we simplify ex, 'y' will be in scope.
    
    251
    -
    
    252
    -However the InScopeSet in the StaticEnv is not irrelevant: it should
    
    253
    -include all the free vars of applying the substitution to the InExpr.
    
    254
    -Reason: contHoleType uses perhapsSubstTy to apply the substitution to
    
    255
    -the expression, and that (rightly) gives ASSERT failures if the InScopeSet
    
    256
    -isn't big enough.
    
    257
    -
    
    258
    -Note [DupFlag invariants]
    
    259
    -~~~~~~~~~~~~~~~~~~~~~~~~~
    
    260
    -In both ApplyToVal { se_dup = dup, se_env = env, se_cont = k}
    
    261
    -   and  Select { se_dup = dup, se_env = env, se_cont = k}
    
    262
    -the following invariants hold
    
    263
    -
    
    264
    -  (a) if dup = OkToDup, then continuation k is also ok-to-dup
    
    265
    -  (b) if dup = OkToDup or Simplified, the subst-env is empty,
    
    266
    -               or at least is always ignored; the payload is
    
    267
    -               already an OutThing
    
    225
    +data DupFlag = NoDup     -- Too big (or unknown) to dup
    
    226
    +             | OkDup     -- Small enough to dup
    
    227
    +
    
    228
    +okToDup :: DupFlag -> Bool
    
    229
    +okToDup NoDup = False
    
    230
    +okToDup OkDup = True
    
    231
    +
    
    232
    +okToDupSE :: StaticEnv -> Bool
    
    233
    +okToDupSE (Simplified dup)  = okToDup dup
    
    234
    +okToDupSE (UnSimplified {}) = False
    
    235
    +
    
    236
    +isSimplified :: StaticEnv -> Bool
    
    237
    +isSimplified (Simplified {})   = True
    
    238
    +isSimplified (UnSimplified {}) = False
    
    239
    +
    
    240
    +perhapsSubstTy :: StaticEnv -> Type -> Type
    
    241
    +perhapsSubstTy (Simplified {})    ty = ty
    
    242
    +perhapsSubstTy (UnSimplified env) ty = substTy env ty
    
    243
    +
    
    244
    +
    
    245
    +{- Note [StaticEnv]
    
    246
    +~~~~~~~~~~~~~~~~~~~
    
    247
    +Consider ApplyToVal, which has
    
    248
    +    sc_env :: StaticEnv
    
    249
    +    sc_arg :: CoreExpr
    
    250
    +Initially, `sc_arg` is an un-simplified InExpr, and `sc_env` is (UnSimplified env),
    
    251
    +where `env` gives meaning to the free variables of `sc_arg`; in particular, `env`
    
    252
    +may have substitutions that must apply to the argument.
    
    253
    +
    
    254
    +But sometimes we simplify the argument, and in that case, `sc_arg` is an OutExpr,
    
    255
    +the simplified argument, and `sc_env` is (Simplified NoDup) or (Simplified OkDup).
    
    256
    +The former is the safe, conservative option, but in `mkDupableCont` we want to make
    
    257
    +the continuation duplicable, so we make the argument small and tag it with
    
    258
    +(Simplified OkDup).
    
    259
    +
    
    260
    +We later simplify the argument, e.g. in `simplArg`.  Then
    
    261
    +  * If sc_env is Simplified, it's a no-op
    
    262
    +  * If sc_env is (UnSimplified arg_env) we simplify `sc_arg` with
    
    263
    +     - Its captured envt `arg_env`
    
    264
    +     - but overriding its InScopeSet with the larger one at the
    
    265
    +       simplification point.
    
    266
    +    Why override the InScopeSet?  Example:
    
    267
    +          (let y = ey in f) ex
    
    268
    +    By the time we simplify ex, 'y' will be in scope.
    
    269
    +  All this is done in `simplArg`.
    
    270
    +
    
    271
    +Note that:
    
    272
    +
    
    273
    +* In the Simplified case there is no environment, because the substitution has
    
    274
    +  already been applied.
    
    275
    +
    
    276
    +* We say sc_arg :: CoreExpr, rather than sc_arg :: InExpr or sc_arg :: OutExpr,
    
    277
    +  because whether it is InExpr or OutExpr depends on `sc_env`
    
    278
    +
    
    279
    +* Same deal for Select, and StrictBind, but the StaticEnv scopes over
    
    280
    +    * sc_bndr and sc_alts (for Select)
    
    281
    +    * sc_bndr and sc_body (for StrictBind)
    
    282
    +
    
    283
    +* Even though the InScopeSet of an (UnSimplified se) is overridden in `simplArg`,
    
    284
    +  that InScopeSet is not irrelevant: it should include all the free vars of
    
    285
    +  applying the substitution to the InExpr. Reason: contHoleType uses perhapsSubstTy
    
    286
    +  to apply the substitution to the expression, and that (rightly) gives ASSERT
    
    287
    +  failures if the InScopeSet isn't big enough.
    
    288
    +
    
    289
    +(SE1) If dup = OkToDup, then continuation k is also ok-to-dup
    
    268 290
     -}
    
    269 291
     
    
    270 292
     instance Outputable DupFlag where
    
    271
    -  ppr OkToDup    = text "ok"
    
    272
    -  ppr NoDup      = text "nodup"
    
    273
    -  ppr Simplified = text "simpl"
    
    293
    +  ppr OkDup = text "okdup"
    
    294
    +  ppr NoDup = text "nodup"
    
    274 295
     
    
    275 296
     instance Outputable SimplCont where
    
    276 297
       ppr (Stop ty interesting eval_sd)
    
    ... ... @@ -283,18 +304,21 @@ instance Outputable SimplCont where
    283 304
         = (text "TickIt" <+> ppr t) $$ ppr cont
    
    284 305
       ppr (ApplyToTy  { sc_arg_ty = ty, sc_cont = cont })
    
    285 306
         = (text "ApplyToTy" <+> pprParendType ty) $$ ppr cont
    
    286
    -  ppr (ApplyToVal { sc_arg = arg, sc_dup = dup, sc_cont = cont, sc_hole_ty = hole_ty })
    
    287
    -    = (hang (text "ApplyToVal" <+> ppr dup <+> text "hole-ty:" <+> pprParendType hole_ty)
    
    307
    +  ppr (ApplyToVal { sc_arg = arg, sc_env = env, sc_cont = cont, sc_hole_ty = hole_ty })
    
    308
    +    = (hang (text "ApplyToVal" <> braces (ppr env) <+> text "hole-ty:" <+> pprParendType hole_ty)
    
    288 309
               2 (pprParendExpr arg))
    
    289 310
           $$ ppr cont
    
    290 311
       ppr (StrictBind { sc_bndr = b, sc_cont = cont })
    
    291 312
         = (text "StrictBind" <+> ppr b) $$ ppr cont
    
    292 313
       ppr (StrictArg { sc_fun = ai, sc_cont = cont })
    
    293 314
         = (text "StrictArg" <+> ppr (ai_fun ai)) $$ ppr cont
    
    294
    -  ppr (Select { sc_dup = dup, sc_bndr = bndr, sc_alts = alts, sc_cont = cont })
    
    295
    -    = (text "Select" <+> ppr dup <+> ppr bndr) $$
    
    315
    +  ppr (Select { sc_env = env, sc_bndr = bndr, sc_alts = alts, sc_cont = cont })
    
    316
    +    = (text "Select" <> braces (ppr env) <+> ppr bndr) $$
    
    296 317
           whenPprDebug (nest 2 $ ppr alts) $$ ppr cont
    
    297 318
     
    
    319
    +instance Outputable StaticEnv where
    
    320
    +  ppr (Simplified dup)    = ppr dup
    
    321
    +  ppr (UnSimplified _env) = text "in"  -- For InExpr etc
    
    298 322
     
    
    299 323
     {- Note [The hole type in ApplyToTy]
    
    300 324
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -384,30 +408,27 @@ isStrictArgInfo (ArgInfo { ai_dmds = dmds })
    384 408
       | dmd:_ <- dmds = isStrUsedDmd dmd
    
    385 409
       | otherwise     = False
    
    386 410
     
    
    387
    -pushArgs :: SimplEnvIS -> Type -> [OutExpr] -> SimplCont -> SimplCont
    
    388
    -pushArgs _env _fun_ty [] cont
    
    411
    +pushArgs :: Type -> [OutExpr] -> SimplCont -> SimplCont
    
    412
    +pushArgs _fun_ty [] cont
    
    389 413
       = cont
    
    390
    -pushArgs env fun_ty (arg:args) cont
    
    414
    +pushArgs fun_ty (arg:args) cont
    
    391 415
       | Type ty <- arg
    
    392 416
       = ApplyToTy { sc_hole_ty = fun_ty, sc_arg_ty = ty
    
    393
    -              , sc_cont = pushArgs env (piResultTy fun_ty ty) args cont }
    
    417
    +              , sc_cont = pushArgs (piResultTy fun_ty ty) args cont }
    
    394 418
       | otherwise
    
    395
    -  = ApplyToVal { sc_dup = Simplified, sc_hole_ty = fun_ty
    
    396
    -               , sc_arg = arg, sc_env = env
    
    397
    -               , sc_cont = pushArgs env (funResultTy fun_ty) args  cont}
    
    419
    +  = ApplyToVal { sc_hole_ty = fun_ty
    
    420
    +               , sc_arg = arg, sc_env = Simplified NoDup
    
    421
    +               , sc_cont = pushArgs (funResultTy fun_ty) args  cont}
    
    398 422
     
    
    399
    -pushArgSpecs :: SimplEnvIS  -- Barely needed, since sc_dup = Simplified
    
    400
    -             -> [ArgSpec]   -- In normal, forward order
    
    423
    +pushArgSpecs :: [ArgSpec]   -- In normal, forward order
    
    401 424
                  -> SimplCont -> SimplCont
    
    402
    -pushArgSpecs env args cont = foldr (pushArgSpec env) cont args
    
    403
    --- pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args
    
    425
    +pushArgSpecs args cont = foldr pushArgSpec cont args
    
    404 426
     
    
    405
    -pushArgSpec :: SimplEnvIS -> ArgSpec -> SimplCont -> SimplCont
    
    406
    -pushArgSpec _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont
    
    427
    +pushArgSpec :: ArgSpec -> SimplCont -> SimplCont
    
    428
    +pushArgSpec (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont
    
    407 429
       = ApplyToTy  { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont }
    
    408
    -pushArgSpec env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont
    
    409
    -  = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified
    
    410
    -                 -- The SubstEnv will be ignored since sc_dup=Simplified
    
    430
    +pushArgSpec (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont
    
    431
    +  = ApplyToVal { sc_arg = arg, sc_env = Simplified NoDup
    
    411 432
                    , sc_hole_ty = hole_ty, sc_cont = cont }
    
    412 433
     
    
    413 434
     argSpecArg :: ArgSpec -> OutExpr
    
    ... ... @@ -456,13 +477,14 @@ contIsStop (Stop {}) = True
    456 477
     contIsStop _         = False
    
    457 478
     
    
    458 479
     contIsDupable :: SimplCont -> Bool
    
    459
    -contIsDupable (Stop {})                         = True
    
    460
    -contIsDupable (ApplyToTy  { sc_cont = k })      = contIsDupable k
    
    461
    -contIsDupable (ApplyToVal { sc_dup = OkToDup }) = True -- See Note [DupFlag invariants]
    
    462
    -contIsDupable (Select { sc_dup = OkToDup })     = True -- ...ditto...
    
    463
    -contIsDupable (StrictArg { sc_dup = OkToDup })  = True -- ...ditto...
    
    464
    -contIsDupable (CastIt { sc_cont = k })          = contIsDupable k
    
    465
    -contIsDupable _                                 = False
    
    480
    +contIsDupable (Stop {})                    = True
    
    481
    +contIsDupable (ApplyToTy  { sc_cont = k }) = contIsDupable k
    
    482
    +contIsDupable (ApplyToVal { sc_env = se }) = okToDupSE se -- See (SE1) in Note [StaticEnv]
    
    483
    +contIsDupable (Select { sc_env = se })     = okToDupSE se -- ...ditto...
    
    484
    +contIsDupable (StrictBind { sc_env = se }) = okToDupSE se -- ...ditto...
    
    485
    +contIsDupable (StrictArg { sc_dup = dup }) = okToDup dup  -- ...ditto...
    
    486
    +contIsDupable (CastIt { sc_cont = k })     = contIsDupable k
    
    487
    +contIsDupable (TickIt _ k)                 = contIsDupable k
    
    466 488
     
    
    467 489
     -------------------
    
    468 490
     contIsTrivial :: SimplCont -> Bool
    
    ... ... @@ -488,13 +510,11 @@ contHoleType :: SimplCont -> OutType
    488 510
     contHoleType (Stop ty _ _)                    = ty
    
    489 511
     contHoleType (TickIt _ k)                     = contHoleType k
    
    490 512
     contHoleType (CastIt { sc_co = co })          = coercionLKind co
    
    491
    -contHoleType (StrictBind { sc_bndr = b, sc_dup = dup, sc_env = se })
    
    492
    -  = perhapsSubstTy dup se (idType b)
    
    513
    +contHoleType (StrictBind { sc_bndr = b, sc_env = se }) = perhapsSubstTy se (idType b)
    
    493 514
     contHoleType (StrictArg  { sc_fun_ty = ty })  = funArgTy ty
    
    494 515
     contHoleType (ApplyToTy  { sc_hole_ty = ty }) = ty  -- See Note [The hole type in ApplyToTy]
    
    495 516
     contHoleType (ApplyToVal { sc_hole_ty = ty }) = ty  -- See Note [The hole type in ApplyToTy]
    
    496
    -contHoleType (Select { sc_dup = d, sc_bndr =  b, sc_env = se })
    
    497
    -  = perhapsSubstTy d se (idType b)
    
    517
    +contHoleType (Select { sc_bndr =  b, sc_env = se }) = perhapsSubstTy se (idType b)
    
    498 518
     
    
    499 519
     
    
    500 520
     -- Computes the multiplicity scaling factor at the hole. That is, in (case [] of
    
    ... ... @@ -544,11 +564,11 @@ countValArgs (CastIt { sc_cont = cont }) = countValArgs cont
    544 564
     countValArgs _                               = 0
    
    545 565
     
    
    546 566
     -------------------
    
    547
    -contArgs :: SimplCont -> (Bool, [ArgSummary], SimplCont)
    
    567
    +contArgs :: SimplEnv -> SimplCont -> (Bool, [ArgSummary], SimplCont)
    
    548 568
     -- Summarises value args, discards type args and coercions
    
    549 569
     -- The returned continuation of the call is only used to
    
    550 570
     -- answer questions like "are you interesting?"
    
    551
    -contArgs cont
    
    571
    +contArgs env cont
    
    552 572
       | lone cont = (True, [], cont)
    
    553 573
       | otherwise = go [] cont
    
    554 574
       where
    
    ... ... @@ -558,15 +578,11 @@ contArgs cont
    558 578
         lone _               = True
    
    559 579
     
    
    560 580
         go args (ApplyToVal { sc_arg = arg, sc_env = se, sc_cont = k })
    
    561
    -                                        = go (is_interesting arg se : args) k
    
    581
    +                                        = go (interestingArg env se arg : args) k
    
    562 582
         go args (ApplyToTy { sc_cont = k }) = go args k
    
    563 583
         go args (CastIt { sc_cont = k })    = go args k
    
    564 584
         go args k                           = (False, reverse args, k)
    
    565 585
     
    
    566
    -    is_interesting arg se = interestingArg se arg
    
    567
    -                   -- Do *not* use short-cutting substitution here
    
    568
    -                   -- because we want to get as much IdInfo as possible
    
    569
    -
    
    570 586
     contOutArgs :: SimplEnv -> SimplCont -> [OutExpr]
    
    571 587
     -- Get the leading arguments from the `SimplCont`, as /OutExprs/
    
    572 588
     contOutArgs env cont
    
    ... ... @@ -577,9 +593,10 @@ contOutArgs env cont
    577 593
         go (ApplyToTy { sc_arg_ty = ty, sc_cont = cont })
    
    578 594
           = Type ty : go cont
    
    579 595
     
    
    580
    -    go (ApplyToVal { sc_dup = dup, sc_arg = arg, sc_env = env, sc_cont = cont })
    
    581
    -      | isSimplified dup = arg : go cont
    
    582
    -      | otherwise        = GHC.Core.Subst.substExpr (getFullSubst in_scope env) arg : go cont
    
    596
    +    go (ApplyToVal { sc_arg = arg, sc_env = se, sc_cont = cont })
    
    597
    +      = case se of
    
    598
    +          Simplified {}    -> arg : go cont
    
    599
    +          UnSimplified env -> GHC.Core.Subst.substExpr (getFullSubst in_scope env) arg : go cont
    
    583 600
             -- Make sure we apply the static environment `sc_env` as a substitution
    
    584 601
             --   to get an OutExpr.  See (BF1) in Note [tryRules: plan (BEFORE)]
    
    585 602
             --   in GHC.Core.Opt.Simplify.Iteration
    
    ... ... @@ -1055,9 +1072,12 @@ Wrinkles:
    1055 1072
     
    
    1056 1073
     -}
    
    1057 1074
     
    
    1058
    -interestingArg :: SimplEnv -> CoreExpr -> ArgSummary
    
    1075
    +interestingArg :: SimplEnv -> StaticEnv -> CoreExpr -> ArgSummary
    
    1059 1076
     -- See Note [Interesting arguments]
    
    1060
    -interestingArg env e = go env 0 e
    
    1077
    +interestingArg env se e
    
    1078
    +  = case se of
    
    1079
    +      Simplified {}           -> go env                                0 e
    
    1080
    +      UnSimplified static_env -> go (static_env `setInScopeFromE` env) 0 e
    
    1061 1081
       where
    
    1062 1082
         -- n is # value args to which the expression is applied
    
    1063 1083
         go env n (Var v)
    
    ... ... @@ -1565,13 +1585,13 @@ the former.
    1565 1585
     
    
    1566 1586
     preInlineUnconditionally
    
    1567 1587
         :: SimplEnv -> TopLevelFlag -> InId
    
    1568
    -    -> DupFlag -> InExpr -> StaticEnv  -- These three go together
    
    1588
    +    -> InExpr -> StaticEnv  -- These two go together
    
    1569 1589
         -> Maybe SimplEnv       -- Returned env has extended substitution
    
    1570 1590
     -- Precondition: rhs satisfies the let-can-float invariant
    
    1571 1591
     -- See Note [Core let-can-float invariant] in GHC.Core
    
    1572 1592
     -- Reason: we don't want to inline single uses, or discard dead bindings,
    
    1573 1593
     --         for unlifted, side-effect-ful bindings
    
    1574
    -preInlineUnconditionally env top_lvl bndr dup rhs rhs_env
    
    1594
    +preInlineUnconditionally env top_lvl bndr rhs rhs_se
    
    1575 1595
       | not pre_inline_unconditionally           = Nothing
    
    1576 1596
       | not active                               = Nothing
    
    1577 1597
       | isTopLevel top_lvl && isDeadEndId bndr   = Nothing -- Note [Top-level bottoming Ids]
    
    ... ... @@ -1593,8 +1613,9 @@ preInlineUnconditionally env top_lvl bndr dup rhs rhs_env
    1593 1613
         -- If not then ContEx
    
    1594 1614
         -- ToDo: flesh this note out
    
    1595 1615
         extend_subst_with inl_rhs
    
    1596
    -      | isSimplified dup = extendIdSubst env bndr $! DoneEx inl_rhs NotJoinPoint
    
    1597
    -      | otherwise        = extendIdSubst env bndr $! mkContEx rhs_env inl_rhs
    
    1616
    +      = case rhs_se of
    
    1617
    +          Simplified _         -> extendIdSubst env bndr $! DoneEx inl_rhs NotJoinPoint
    
    1618
    +          UnSimplified rhs_env -> extendIdSubst env bndr $! mkContEx rhs_env inl_rhs
    
    1598 1619
     
    
    1599 1620
         one_occ IAmDead = True -- Happens in ((\x.1) v)
    
    1600 1621
         one_occ OneOcc{ occ_n_br   = 1