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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -498,10 +498,11 @@ instance Outputable SimplClo where
    498 498
                     JoinPoint n  -> parens (int n)
    
    499 499
     
    
    500 500
       ppr (ContEx _se e mco)
    
    501
    -    = text "ContEx" <> vcat [ pprParendExpr e
    
    502
    -                            , case mco of
    
    503
    -                                 MRefl -> empty
    
    504
    -                                 MCo co -> text "|>" <+> pprOptCo co ]
    
    501
    +    = text "ContEx" <>
    
    502
    +      braces (vcat [ pprParendExpr e
    
    503
    +                   , case mco of
    
    504
    +                        MRefl -> empty
    
    505
    +                        MCo co -> text "|>" <+> pprOptCo co ])
    
    505 506
             -- where
    
    506 507
             -- fvs = exprFreeVars e
    
    507 508
             -- filter_env env = filterVarEnv_Directly keep env
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -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
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -24,12 +24,12 @@ module GHC.Core.Opt.Simplify.Utils (
    24 24
     
    
    25 25
             -- The continuation type
    
    26 26
             SimplCont(..), DupFlag(..), FromWhat(..), StaticEnv,
    
    27
    -        isSimplified, contIsStop,
    
    27
    +        contIsStop,
    
    28 28
             contIsDupable, contResultType, contHoleType, contHoleScaling,
    
    29 29
             contIsTrivial, contArgs, contIsRhs,
    
    30 30
             countArgs, contOutArgs, dropContArgs,
    
    31 31
             mkBoringStop, mkRhsStop, mkLazyArgStop,
    
    32
    -        interestingCallContext,
    
    32
    +        interestingCallContext, pushCastCont,
    
    33 33
     
    
    34 34
             -- ArgInfo
    
    35 35
             ArgInfo(..), ArgSpec(..), mkArgInfo,
    
    ... ... @@ -420,6 +420,11 @@ mkLazyArgStop ty fun_info = Stop ty (lazyArgContext fun_info) arg_sd
    420 420
       where
    
    421 421
         arg_sd = subDemandIfEvaluated (Partial.head (ai_dmds fun_info))
    
    422 422
     
    
    423
    +pushCastCont :: MOutCoercion -> SimplCont -> SimplCont
    
    424
    +-- Assumes the MOutCoercion is optimised
    
    425
    +pushCastCont MRefl    cont = cont
    
    426
    +pushCastCont (MCo co) cont = CastIt { sc_co = co, sc_opt = True, sc_cont = cont }
    
    427
    +
    
    423 428
     -------------------
    
    424 429
     contIsRhs :: SimplCont -> Maybe RecFlag
    
    425 430
     contIsRhs (Stop _ (RhsCtxt is_rec) _) = Just is_rec