| ... |
... |
@@ -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
|