| ... |
... |
@@ -31,7 +31,6 @@ import GHC.Core.Coercion.Opt ( optCoercion ) |
|
31
|
31
|
import GHC.Core.FamInstEnv ( FamInstEnv, topNormaliseType_maybe )
|
|
32
|
32
|
import GHC.Core.DataCon
|
|
33
|
33
|
import GHC.Core.Opt.Stats ( Tick(..) )
|
|
34
|
|
-import GHC.Core.Ppr ( pprCoreExpr )
|
|
35
|
34
|
import GHC.Core.Unfold
|
|
36
|
35
|
import GHC.Core.Unfold.Make
|
|
37
|
36
|
import GHC.Core.Utils
|
| ... |
... |
@@ -1551,7 +1550,7 @@ rebuild_go env expr cont |
|
1551
|
1550
|
|
|
1552
|
1551
|
ApplyToVal { sc_arg = arg_clo, sc_cont = cont, sc_hole_ty = fun_ty }
|
|
1553
|
1552
|
-- See Note [Avoid redundant simplification]
|
|
1554
|
|
- -> do { arg' <- simplClo env fun_ty Nothing arg_clo
|
|
|
1553
|
+ -> do { arg' <- simplCloArg env fun_ty Nothing arg_clo
|
|
1555
|
1554
|
; rebuild_go env (App expr arg') cont }
|
|
1556
|
1555
|
|
|
1557
|
1556
|
completeBindX :: SimplEnv
|
| ... |
... |
@@ -1709,8 +1708,7 @@ simplCast env body co0 cont0 |
|
1709
|
1708
|
-- co1 :: t1 ~ s1
|
|
1710
|
1709
|
-- co2 :: s2 ~ t2
|
|
1711
|
1710
|
addCoerce co co_is_opt cont@(ApplyToVal { sc_arg = arg_clo
|
|
1712
|
|
- , sc_dup = dup, sc_cont = tail
|
|
1713
|
|
- , sc_hole_ty = fun_ty })
|
|
|
1711
|
+ , sc_dup = dup, sc_cont = tail })
|
|
1714
|
1712
|
| not co_is_opt -- pushCoValArg duplicates the coercion, so optimise first
|
|
1715
|
1713
|
= addCoerce (optOutCoercion (zapSubstEnv env) co co_is_opt) True cont
|
|
1716
|
1714
|
|
| ... |
... |
@@ -1739,25 +1737,6 @@ simplCast env body co0 cont0 |
|
1739
|
1737
|
-- See Note [Optimising reflexivity]
|
|
1740
|
1738
|
| otherwise = return (CastIt { sc_co = co, sc_opt = co_is_opt, sc_cont = cont })
|
|
1741
|
1739
|
|
|
1742
|
|
-simplClo :: SimplEnvIS -- ^ Used only for its InScopeSet
|
|
1743
|
|
- -> OutType -- ^ Type of the function applied to this arg
|
|
1744
|
|
- -> Maybe ArgInfo -- ^ Just <=> This arg `ai` occurs in an app
|
|
1745
|
|
- -- `f a1 ... an` where we have ArgInfo on
|
|
1746
|
|
- -- how `f` uses `ai`, affecting the Stop
|
|
1747
|
|
- -- continuation passed to 'simplExprC'
|
|
1748
|
|
- -> SimplClo
|
|
1749
|
|
- -> SimplM OutExpr
|
|
1750
|
|
-simplClo env fun_ty mb_arg_info (ContEx arg_se arg mco)
|
|
1751
|
|
- = simplExprC arg_env arg stop
|
|
1752
|
|
- where
|
|
1753
|
|
- arg_env = arg_se `setInScopeFromE` env
|
|
1754
|
|
- arg_ty = funArgTy fun_ty
|
|
1755
|
|
- stop = case mb_arg_info of
|
|
1756
|
|
- Nothing -> mkBoringStop arg_ty
|
|
1757
|
|
- Just ai -> mkLazyArgStop arg_ty ai
|
|
1758
|
|
-
|
|
1759
|
|
-simplClo _ _ _ (DoneEx e _) = return e
|
|
1760
|
|
-simplClo _ _ _ (DoneId v) = return (Var v)
|
|
1761
|
1740
|
|
|
1762
|
1741
|
{-
|
|
1763
|
1742
|
************************************************************************
|
| ... |
... |
@@ -1800,8 +1779,7 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg_clo, sc_cont = cont }) |
|
1800
|
1779
|
-- Value beta-reduction
|
|
1801
|
1780
|
-- This works for /coercion/ lambdas too
|
|
1802
|
1781
|
simpl_lam env bndr body (ApplyToVal { sc_arg = arg_clo
|
|
1803
|
|
- , sc_cont = cont, sc_dup = dup
|
|
1804
|
|
- , sc_hole_ty = fun_ty})
|
|
|
1782
|
+ , sc_cont = cont, sc_hole_ty = fun_ty})
|
|
1805
|
1783
|
= do { tick (BetaReduction bndr)
|
|
1806
|
1784
|
; let from_what = FromBeta arg_levity
|
|
1807
|
1785
|
arg_levity
|
| ... |
... |
@@ -1817,7 +1795,7 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg_clo |
|
1817
|
1795
|
-- But fun_ty is an OutType, so is fully substituted
|
|
1818
|
1796
|
|
|
1819
|
1797
|
; if | Just env' <- preInlineBetaUnconditionally env arg_levity bndr arg_clo
|
|
1820
|
|
- -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr) $
|
|
|
1798
|
+ -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr $$ ppr arg_clo) $
|
|
1821
|
1799
|
tick (PreInlineUnconditionally bndr)
|
|
1822
|
1800
|
; simplLam env' body cont }
|
|
1823
|
1801
|
|
| ... |
... |
@@ -1889,7 +1867,8 @@ simplNonRecE env from_what bndr (ContEx rhs_se rhs mco) body cont |
|
1889
|
1867
|
is_strict_bind
|
|
1890
|
1868
|
= -- Evaluate RHS strictly
|
|
1891
|
1869
|
simplExprF (rhs_se `setInScopeFromE` env) rhs
|
|
1892
|
|
- (StrictBind { sc_bndr = bndr, sc_body = body, sc_from = from_what
|
|
|
1870
|
+ (pushCastCont mco $
|
|
|
1871
|
+ StrictBind { sc_bndr = bndr, sc_body = body, sc_from = from_what
|
|
1893
|
1872
|
, sc_env = env, sc_cont = cont, sc_dup = NoDup })
|
|
1894
|
1873
|
|
|
1895
|
1874
|
| otherwise -- Evaluate RHS lazily
|
| ... |
... |
@@ -2085,15 +2064,14 @@ wrapJoinCont env cont thing_inside |
|
2085
|
2064
|
|
|
2086
|
2065
|
|
|
2087
|
2066
|
--------------------
|
|
2088
|
|
-trimJoinCont :: Id -- Used only in error message
|
|
2089
|
|
- -> JoinPointHood
|
|
|
2067
|
+trimJoinCont :: JoinPointHood
|
|
2090
|
2068
|
-> SimplCont -> SimplCont
|
|
2091
|
2069
|
-- Drop outer context from join point invocation (jump)
|
|
2092
|
2070
|
-- See Note [Join points and case-of-case]
|
|
2093
|
2071
|
|
|
2094
|
|
-trimJoinCont _ NotJoinPoint cont
|
|
|
2072
|
+trimJoinCont NotJoinPoint cont
|
|
2095
|
2073
|
= cont -- Not a jump
|
|
2096
|
|
-trimJoinCont var (JoinPoint arity) cont
|
|
|
2074
|
+trimJoinCont (JoinPoint arity) cont
|
|
2097
|
2075
|
= trim arity cont
|
|
2098
|
2076
|
where
|
|
2099
|
2077
|
trim 0 cont@(Stop {})
|
| ... |
... |
@@ -2105,7 +2083,7 @@ trimJoinCont var (JoinPoint arity) cont |
|
2105
|
2083
|
trim n cont@(ApplyToTy { sc_cont = k })
|
|
2106
|
2084
|
= cont { sc_cont = trim (n-1) k } -- join arity counts types!
|
|
2107
|
2085
|
trim _ cont
|
|
2108
|
|
- = pprPanic "completeCall" $ ppr var $$ ppr cont
|
|
|
2086
|
+ = pprPanic "trimJoinCont" $ ppr cont
|
|
2109
|
2087
|
|
|
2110
|
2088
|
|
|
2111
|
2089
|
{- Note [Join points and case-of-case]
|
| ... |
... |
@@ -2234,22 +2212,49 @@ simplInId :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr) |
|
2234
|
2212
|
simplInId env var cont
|
|
2235
|
2213
|
| Just dc <- isDataConWorkId_maybe var
|
|
2236
|
2214
|
, isLazyDataConRep dc -- See Note [Fast path for lazy data constructors]
|
|
2237
|
|
- = rebuild zapped_env (Var var) cont
|
|
|
2215
|
+ = rebuild (zapSubstEnv env) (Var var) cont
|
|
2238
|
2216
|
| otherwise
|
|
2239
|
|
- = case substId env var of
|
|
2240
|
|
- ContEx se e mco -> do { e' <- simplExprF (se `setInScopeFromE` env) e cont
|
|
2241
|
|
- ; return (mkCastMCo e' mco) }
|
|
|
2217
|
+ = simplClo env (substId env var) cont
|
|
|
2218
|
+
|
|
|
2219
|
+simplClo :: SimplEnv
|
|
|
2220
|
+ -> SimplClo
|
|
|
2221
|
+ -> SimplCont
|
|
|
2222
|
+ -> SimplM (SimplFloats, OutExpr)
|
|
|
2223
|
+simplClo env clo cont
|
|
|
2224
|
+ = case clo of
|
|
|
2225
|
+ ContEx se e mco -> simplExprF (se `setInScopeFromE` env) e $
|
|
|
2226
|
+ pushCastCont mco cont
|
|
2242
|
2227
|
-- Don't trimJoinCont; we haven't already simplified e,
|
|
2243
|
2228
|
-- so the cont is not embodied in e
|
|
2244
|
2229
|
|
|
2245
|
2230
|
DoneId out_id -> simplOutId zapped_env out_id $
|
|
2246
|
|
- trimJoinCont out_id (idJoinPointHood out_id) cont
|
|
|
2231
|
+ trimJoinCont (idJoinPointHood out_id) cont
|
|
2247
|
2232
|
|
|
2248
|
2233
|
DoneEx e mb_join -> simplExprF zapped_env e $
|
|
2249
|
|
- trimJoinCont var mb_join cont
|
|
|
2234
|
+ trimJoinCont mb_join cont
|
|
2250
|
2235
|
where
|
|
2251
|
2236
|
zapped_env = zapSubstEnv env -- See Note [zapSubstEnv]
|
|
2252
|
2237
|
|
|
|
2238
|
+simplCloArg :: SimplEnvIS -- ^ Used only for its InScopeSet
|
|
|
2239
|
+ -> OutType -- ^ Type of the function applied to this arg
|
|
|
2240
|
+ -> Maybe ArgInfo -- ^ Just <=> This arg `ai` occurs in an app
|
|
|
2241
|
+ -- `f a1 ... an` where we have ArgInfo on
|
|
|
2242
|
+ -- how `f` uses `ai`, affecting the Stop
|
|
|
2243
|
+ -- continuation passed to 'simplExprC'
|
|
|
2244
|
+ -> SimplClo
|
|
|
2245
|
+ -> SimplM OutExpr
|
|
|
2246
|
+simplCloArg env fun_ty mb_arg_info clo@(ContEx arg_se arg mco)
|
|
|
2247
|
+ = simplExprC arg_env arg (pushCastCont mco stop)
|
|
|
2248
|
+ where
|
|
|
2249
|
+ arg_env = arg_se `setInScopeFromE` env
|
|
|
2250
|
+ arg_ty = funArgTy fun_ty
|
|
|
2251
|
+ stop = case mb_arg_info of
|
|
|
2252
|
+ Nothing -> mkBoringStop arg_ty
|
|
|
2253
|
+ Just ai -> mkLazyArgStop arg_ty ai
|
|
|
2254
|
+
|
|
|
2255
|
+simplCloArg _ _ _ (DoneEx e _) = return e
|
|
|
2256
|
+simplCloArg _ _ _ (DoneId v) = return (Var v)
|
|
|
2257
|
+
|
|
2253
|
2258
|
---------------------------------------------------------
|
|
2254
|
2259
|
simplOutId :: SimplEnvIS -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr)
|
|
2255
|
2260
|
|
| ... |
... |
@@ -2266,9 +2271,7 @@ simplOutId env fun cont |
|
2266
|
2271
|
, sc_hole_ty = fun_ty } <- cont2
|
|
2267
|
2272
|
-- Do this even if (contIsStop cont), or if seCaseCase is off.
|
|
2268
|
2273
|
-- See Note [No eta-expansion in runRW#]
|
|
2269
|
|
- = do { let arg_env = arg_se `setInScopeFromE` env
|
|
2270
|
|
-
|
|
2271
|
|
- overall_res_ty = contResultType cont3
|
|
|
2274
|
+ = do { let overall_res_ty = contResultType cont3
|
|
2272
|
2275
|
-- hole_ty is the type of the current runRW# application
|
|
2273
|
2276
|
(outer_cont, new_runrw_res_ty, inner_cont)
|
|
2274
|
2277
|
| seCaseCase env = (mkBoringStop overall_res_ty, overall_res_ty, cont3)
|
| ... |
... |
@@ -2281,26 +2284,32 @@ simplOutId env fun cont |
|
2281
|
2284
|
-- * If we don't do this we get a beta-redex every time, so the
|
|
2282
|
2285
|
-- simplifier keeps doing more iterations.
|
|
2283
|
2286
|
-- * Even more important: see Note [No eta-expansion in runRW#]
|
|
2284
|
|
- ; arg' <- case arg of
|
|
2285
|
|
- Lam s body -> do { (env', s') <- simplBinder arg_env s
|
|
2286
|
|
- ; body' <- simplExprC env' body inner_cont
|
|
2287
|
|
- ; return (Lam s' body') }
|
|
|
2287
|
+ ; arg' <- case get_arg arg_clo of
|
|
|
2288
|
+ Just (arg_env, s, body)
|
|
|
2289
|
+ -> do { (env', s') <- simplBinder arg_env s
|
|
|
2290
|
+ ; body' <- simplExprC env' body inner_cont
|
|
|
2291
|
+ ; return (Lam s' body') }
|
|
2288
|
2292
|
-- Important: do not try to eta-expand this lambda
|
|
2289
|
2293
|
-- See Note [No eta-expansion in runRW#]
|
|
2290
|
2294
|
|
|
2291
|
2295
|
_ -> do { s' <- newId (fsLit "s") ManyTy realWorldStatePrimTy
|
|
2292
|
|
- ; let (m,_,_) = splitFunTy fun_ty
|
|
2293
|
|
- env' = arg_env `addNewInScopeIds` [s']
|
|
2294
|
|
- cont' = ApplyToVal { sc_dup = Dupable, sc_arg = DoneId s'
|
|
|
2296
|
+ ; let (mult,_,_) = splitFunTy fun_ty
|
|
|
2297
|
+ env' = env `addNewInScopeIds` [s']
|
|
|
2298
|
+ cont' = ApplyToVal { sc_dup = OkToDup, sc_arg = DoneId s'
|
|
2295
|
2299
|
, sc_cont = inner_cont
|
|
2296
|
|
- , sc_hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty }
|
|
|
2300
|
+ , sc_hole_ty = mkVisFunTy mult realWorldStatePrimTy new_runrw_res_ty }
|
|
2297
|
2301
|
-- cont' applies to s', then K
|
|
2298
|
|
- ; body' <- simplExprC env' arg cont'
|
|
2299
|
|
- ; return (Lam s' body') }
|
|
|
2302
|
+ ; (floats, body') <- simplClo env' arg_clo cont'
|
|
|
2303
|
+ ; return (Lam s' (wrapFloats floats body')) }
|
|
2300
|
2304
|
|
|
2301
|
2305
|
; let rr' = getRuntimeRep new_runrw_res_ty
|
|
2302
|
2306
|
call' = mkApps (Var fun) [mkTyArg rr', mkTyArg new_runrw_res_ty, arg']
|
|
2303
|
2307
|
; rebuild env call' outer_cont }
|
|
|
2308
|
+ where
|
|
|
2309
|
+ get_arg :: SimplClo -> Maybe (SimplEnv, InId, InExpr)
|
|
|
2310
|
+ get_arg (DoneEx (Lam s b) _) = Just (zapSubstEnv env, s, b)
|
|
|
2311
|
+ get_arg (ContEx se (Lam s b) MRefl) = Just (se `setInScopeFromE` env, s, b)
|
|
|
2312
|
+ get_arg _ = Nothing
|
|
2304
|
2313
|
|
|
2305
|
2314
|
-- Normal case for (f e1 .. en)
|
|
2306
|
2315
|
simplOutId env fun cont
|
| ... |
... |
@@ -2371,9 +2380,7 @@ rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_c |
|
2371
|
2380
|
|
|
2372
|
2381
|
---------- Simplify value arguments --------------------
|
|
2373
|
2382
|
rebuildCall env fun_info
|
|
2374
|
|
- (ApplyToVal { sc_arg = arg_clo
|
|
2375
|
|
- , sc_dup = dup_flag, sc_hole_ty = fun_ty
|
|
2376
|
|
- , sc_cont = cont })
|
|
|
2383
|
+ (ApplyToVal { sc_arg = arg_clo, sc_hole_ty = fun_ty, sc_cont = cont })
|
|
2377
|
2384
|
= case arg_clo of -- See Note [Avoid redundant simplification]
|
|
2378
|
2385
|
DoneId v -> rebuildCall env (addValArgTo fun_info (Var v) fun_ty) cont
|
|
2379
|
2386
|
DoneEx arg _ -> rebuildCall env (addValArgTo fun_info arg fun_ty) cont
|
| ... |
... |
@@ -2383,7 +2390,7 @@ rebuildCall env fun_info |
|
2383
|
2390
|
, seCaseCase env -- Only when case-of-case is on. See GHC.Driver.Config.Core.Opt.Simplify
|
|
2384
|
2391
|
-- Note [Case-of-case and full laziness]
|
|
2385
|
2392
|
-> simplExprF (arg_se `setInScopeFromE` env) in_arg
|
|
2386
|
|
- (add_cast mco $
|
|
|
2393
|
+ (pushCastCont mco $
|
|
2387
|
2394
|
StrictArg { sc_fun = fun_info, sc_fun_ty = fun_ty
|
|
2388
|
2395
|
, sc_dup = NoDup, sc_cont = cont })
|
|
2389
|
2396
|
-- Note [Shadowing in the Simplifier]
|
| ... |
... |
@@ -2394,13 +2401,9 @@ rebuildCall env fun_info |
|
2394
|
2401
|
-- There is no benefit (unlike in a let-binding), and we'd
|
|
2395
|
2402
|
-- have to be very careful about bogus strictness through
|
|
2396
|
2403
|
-- floating a demanded let.
|
|
2397
|
|
- -> do { arg' <- simplClo env fun_ty (Just fun_info) arg_clo
|
|
|
2404
|
+ -> do { arg' <- simplCloArg env fun_ty (Just fun_info) arg_clo
|
|
2398
|
2405
|
; rebuildCall env (addValArgTo fun_info arg' fun_ty) cont }
|
|
2399
|
2406
|
|
|
2400
|
|
- where
|
|
2401
|
|
- add_cast MRefl cont = cont
|
|
2402
|
|
- add_cast (MCo co) cont = CastIt { sc_co = co, sc_opt = True, sc_cont = cont }
|
|
2403
|
|
-
|
|
2404
|
2407
|
|
|
2405
|
2408
|
---------- No further useful info, revert to generic rebuild ------------
|
|
2406
|
2409
|
rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args, ai_rules = rules }) cont
|
| ... |
... |
@@ -2633,7 +2636,7 @@ tryRules env rules fn args |
|
2633
|
2636
|
--, text "Rule activation:" <+> ppr (ruleActivation rule)
|
|
2634
|
2637
|
, text "Full arity:" <+> ppr (ruleArity rule)
|
|
2635
|
2638
|
, text "Before:" <+> hang (ppr fn) 2 (sep (map ppr args))
|
|
2636
|
|
- , text "After: " <+> mkApps (pprCoreExpr rule_rhs) (drop (ruleArity rule) args) ]
|
|
|
2639
|
+ , text "After: " <+> ppr (mkApps rule_rhs (drop (ruleArity rule) args)) ]
|
|
2637
|
2640
|
|
|
2638
|
2641
|
| logHasDumpFlag logger Opt_D_dump_rule_firings
|
|
2639
|
2642
|
= log_rule Opt_D_dump_rule_firings "Rule fired:" $
|
| ... |
... |
@@ -3930,8 +3933,7 @@ mkDupableContWithDmds env dmds |
|
3930
|
3933
|
, sc_arg_ty = arg_ty, sc_hole_ty = hole_ty }) }
|
|
3931
|
3934
|
|
|
3932
|
3935
|
mkDupableContWithDmds env dmds
|
|
3933
|
|
- (ApplyToVal { sc_arg = arg_clo, sc_dup = dup
|
|
3934
|
|
- , sc_cont = cont, sc_hole_ty = hole_ty })
|
|
|
3936
|
+ (ApplyToVal { sc_arg = arg_clo, sc_cont = cont, sc_hole_ty = hole_ty })
|
|
3935
|
3937
|
= -- e.g. [...hole...] (...arg...)
|
|
3936
|
3938
|
-- ==>
|
|
3937
|
3939
|
-- let a = ...arg...
|
| ... |
... |
@@ -3940,7 +3942,7 @@ mkDupableContWithDmds env dmds |
|
3940
|
3942
|
do { let dmd:|cont_dmds = expectNonEmpty dmds
|
|
3941
|
3943
|
; (floats1, cont') <- mkDupableContWithDmds env cont_dmds cont
|
|
3942
|
3944
|
; let env' = env `setInScopeFromF` floats1
|
|
3943
|
|
- ; arg' <- simplClo env' hole_ty Nothing arg_clo
|
|
|
3945
|
+ ; arg' <- simplCloArg env' hole_ty Nothing arg_clo
|
|
3944
|
3946
|
; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg'
|
|
3945
|
3947
|
; let all_floats = floats1 `addLetFloats` let_floats2
|
|
3946
|
3948
|
; return ( all_floats
|