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

Commits:

4 changed files:

Changes:

  • compiler/GHC/Core/Coercion.hs
    ... ... @@ -426,7 +426,8 @@ decomposeFunCo :: HasDebugCallStack
    426 426
     
    
    427 427
     decomposeFunCo (FunCo { fco_mult = w, fco_arg = co1, fco_res = co2 })
    
    428 428
       = (w, co1, co2)
    
    429
    -   -- Short-circuits the calls to mkSelCo
    
    429
    +   -- Fast path that short-circuits the calls to mkSelCo,
    
    430
    +   -- even though they would give the exact same answers
    
    430 431
     
    
    431 432
     decomposeFunCo co
    
    432 433
       = assertPpr all_ok (ppr co) $
    

  • compiler/GHC/Core/Opt/Arity.hs
    ... ... @@ -2691,10 +2691,11 @@ same fix.
    2691 2691
     
    
    2692 2692
     -- | `tryEtaReduce [x,y,z] e sd` returns `Just e'` if `\x y z -> e` is evaluated
    
    2693 2693
     -- according to `sd` and can soundly and gainfully be eta-reduced to `e'`.
    
    2694
    --- See Note [Eta reduction soundness]
    
    2695
    --- and Note [Eta reduction makes sense] when that is the case.
    
    2696 2694
     tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> SubDemand -> Maybe CoreExpr
    
    2697 2695
     -- Return an expression equal to (\bndrs. body)
    
    2696
    +-- See Note [Eta reduction soundness]
    
    2697
    +-- and Note [Eta reduction makes sense] when that is the case.
    
    2698
    +-- and Note [Eta reduction based on evaluation context] for the `eval_sd` arg
    
    2698 2699
     tryEtaReduce rec_ids bndrs body eval_sd
    
    2699 2700
       = go (reverse bndrs) body (mkRepReflCo (exprType body))
    
    2700 2701
       where
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -1729,10 +1729,15 @@ optOutCoercion env co already_optimised
    1729 1729
         opts = seOptCoercionOpts env
    
    1730 1730
     
    
    1731 1731
     addCastMCo :: MOutCoercion -> SimplCont -> SimplCont
    
    1732
    --- Simpler version of `pushCast` when optionally want to add a cast to the top
    
    1732
    +-- Simpler, non-monadic version of pushCastMCo when we are certain that
    
    1733
    +-- the cast should be at the top; i.e. cont is Stop or StrictArg
    
    1733 1734
     addCastMCo MRefl    cont = cont
    
    1734 1735
     addCastMCo (MCo co) cont = CastIt { sc_co = co, sc_opt = False, sc_cont = cont }
    
    1735 1736
     
    
    1737
    +pushCastMCo :: SimplEnv -> MOutCoercion -> SimplCont -> SimplM SimplCont
    
    1738
    +pushCastMCo _env MRefl    cont = return cont
    
    1739
    +pushCastMCo env  (MCo co) cont = pushCast env co cont
    
    1740
    +
    
    1736 1741
     pushCast :: SimplEnv -> OutCoercion -> SimplCont -> SimplM SimplCont
    
    1737 1742
     pushCast env co cont
    
    1738 1743
       = go co True cont
    
    ... ... @@ -1753,7 +1758,7 @@ pushCast env co cont
    1753 1758
                                         -- NB!  As the cast goes past, the
    
    1754 1759
                                         -- type of the hole changes (#16312)
    
    1755 1760
     
    
    1756
    -    -- (f |> co) e   ===>   (f (e |> co1)) |> co2
    
    1761
    +    -- (f |> co) arg   ===>   (f (arg |> co1)) |> co2
    
    1757 1762
         -- where   co :: (s1->s2) ~ (t1->t2)
    
    1758 1763
         --         co1 :: t1 ~ s1
    
    1759 1764
         --         co2 :: s2 ~ t2
    
    ... ... @@ -1763,12 +1768,14 @@ pushCast env co cont
    1763 1768
           = -- pushCoValArg duplicates the coercion, so optimise first
    
    1764 1769
             go (optOutCoercion (zapSubstEnv env) co co_is_opt) True cont
    
    1765 1770
     
    
    1771
    +-- ToDo: return coercionLKind. And similarly pushCoTyArg
    
    1772
    +
    
    1766 1773
           | Just (m_co1, m_co2) <- pushCoValArg co
    
    1767 1774
           = {-#SCC "addCoerce-pushCoValArg" #-}
    
    1768 1775
             do { tail' <- go_mco m_co2 co_is_opt tail
    
    1769 1776
                ; return (ApplyToVal { sc_arg  = arg
    
    1770 1777
                                     , sc_env  = arg_se
    
    1771
    -                                , sc_cast = m_co1 `mkTransMCo` arg_mco
    
    1778
    +                                , sc_cast = arg_mco `mkTransMCo` m_co1
    
    1772 1779
                                     , sc_cont = tail'
    
    1773 1780
                                     , sc_hole_ty = coercionLKind co }) }
    
    1774 1781
     
    
    ... ... @@ -1778,6 +1785,7 @@ pushCast env co cont
    1778 1785
                                        -- See Note [Optimising reflexivity]
    
    1779 1786
           | otherwise = return (CastIt { sc_co = co, sc_opt = co_is_opt, sc_cont = cont })
    
    1780 1787
     
    
    1788
    +-- ToDo:   pushCast Refl (ApplylToVal arg1 (ApplyToVal arg2 ...))  will do lots of unnecessary work.
    
    1781 1789
     
    
    1782 1790
             -- If the first parameter is MRefl, then simplifying revealed a
    
    1783 1791
             -- reflexive coercion. Omit.
    
    ... ... @@ -2295,7 +2303,8 @@ simplInId env var cont
    2295 2303
       | otherwise
    
    2296 2304
       = case substId env var of
    
    2297 2305
           ContEx se e mco
    
    2298
    -        -> simplExprF (se `setInScopeFromE` env) e (addCastMCo mco cont)
    
    2306
    +        -> do { cont' <- pushCastMCo env mco cont
    
    2307
    +              ; simplExprF (se `setInScopeFromE` env) e cont' }
    
    2299 2308
             -- Don't trimJoinCont; haven't already simplified e,
    
    2300 2309
             -- so the cont is not embodied in e
    
    2301 2310
     
    
    ... ... @@ -2393,10 +2402,12 @@ simplOutId env fun cont
    2393 2402
                _ -> do { s' <- newId (fsLit "s") ManyTy realWorldStatePrimTy
    
    2394 2403
                        ; let (m,_,_) = splitFunTy fun_ty
    
    2395 2404
                              env'  = arg_env `addNewInScopeIds` [s']
    
    2396
    -                         cont' = addCastMCo arg_mco $
    
    2397
    -                                 ApplyToVal { sc_arg = Var s', sc_cast = MRefl
    
    2398
    -                                            , sc_env = Simplified OkDup, sc_cont = inner_cont
    
    2399
    -                                            , sc_hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty }
    
    2405
    +                         hole_ty = mkVisFunTy m realWorldStatePrimTy new_runrw_res_ty
    
    2406
    +                   ; cont' <- pushCastMCo env' arg_mco $
    
    2407
    +                              ApplyToVal { sc_arg = Var s', sc_cast = MRefl
    
    2408
    +                                         , sc_env = Simplified OkDup
    
    2409
    +                                         , sc_cont = inner_cont
    
    2410
    +                                         , sc_hole_ty = hole_ty }
    
    2400 2411
                                     -- cont' applies to s', then K
    
    2401 2412
                        ; body' <- simplExprC env' arg cont'
    
    2402 2413
                        ; return (Lam s' body') }
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -620,26 +620,33 @@ dropContArgs n cont = pprPanic "dropContArgs" (ppr n $$ ppr cont)
    620 620
     -- For example, when simplifying the argument `e` in `f e` and `f` has the
    
    621 621
     -- demand signature `<MP(S,A)>`, this function will give you back `P(S,A)` when
    
    622 622
     -- simplifying `e`.
    
    623
    ---
    
    624
    --- PRECONDITION: Don't call with 'ApplyToVal'. We haven't thoroughly thought
    
    625
    --- about what to do then and no call sites so far seem to care.
    
    626
    -contEvalContext :: SimplCont -> SubDemand
    
    627
    -contEvalContext k = case k of
    
    628
    -  Stop _ _ sd              -> sd
    
    629
    -  TickIt _ k               -> contEvalContext k
    
    630
    -  CastIt   { sc_cont = k } -> contEvalContext k
    
    631
    -  ApplyToTy{ sc_cont = k } -> contEvalContext k
    
    632
    -    --  ApplyToVal{sc_cont=k}      -> mkCalledOnceDmd $ contEvalContext k
    
    623
    +contEvalContext :: [Var] -> SimplCont -> SubDemand
    
    624
    +contEvalContext bndrs cont = go cont
    
    625
    +  where
    
    626
    +    go (Stop _ _ sd)              = sd
    
    627
    +    go (TickIt _ k)               = go k
    
    628
    +    go (CastIt   { sc_cont = k }) = go k
    
    629
    +    go (ApplyToTy{ sc_cont = k }) = go k
    
    630
    +
    
    631
    +    -- The ApplyToVal case can actually happen, if we have
    
    632
    +    --     (CastIt co (ApplyToVal ..))
    
    633
    +    -- Possible code:
    
    634
    +    --    go (ApplyToVal{sc_cont=k}) = mkCalledOnceDmd $ contEvalContext k
    
    633 635
         -- Not 100% sure that's correct, . Here's an example:
    
    634 636
         --   f (e x) and f :: <SC(S,C(1,L))>
    
    635 637
         -- then what is the evaluation context of 'e' when we simplify it? E.g.,
    
    636 638
         --   simpl e (ApplyToVal x $ Stop "C(S,C(1,L))")
    
    637 639
         -- then it *should* be "C(1,C(S,C(1,L))", so perhaps correct after all.
    
    638
    -    -- But for now we just panic:
    
    639
    -  ApplyToVal{}               -> pprPanic "contEvalContext" (ppr k)
    
    640
    -  StrictArg{sc_fun=fun_info} -> subDemandIfEvaluated (Partial.head (ai_dmds fun_info))
    
    641
    -  StrictBind{sc_bndr=bndr}   -> subDemandIfEvaluated (idDemandInfo bndr)
    
    642
    -  Select{}                   -> topSubDmd
    
    640
    +    -- But for now we just return topDmd.
    
    641
    +    go (ApplyToVal{ sc_arg = arg }) = warnPprTrace True "contEvalContext"
    
    642
    +                                        (vcat [ text "arg:"   <+> ppr arg
    
    643
    +                                              , text "bndrs:" <+> ppr bndrs
    
    644
    +                                              , text "cont:"  <+> ppr cont ])
    
    645
    +                                      topSubDmd
    
    646
    +
    
    647
    +    go (StrictArg{sc_fun=fun_info}) = subDemandIfEvaluated (Partial.head (ai_dmds fun_info))
    
    648
    +    go (StrictBind{sc_bndr=bndr})   = subDemandIfEvaluated (idDemandInfo bndr)
    
    649
    +    go (Select{})                   = topSubDmd
    
    643 650
         -- Perhaps reconstruct the demand on the scrutinee by looking at field
    
    644 651
         -- and case binder dmds, see addCaseBndrDmd. No priority right now.
    
    645 652
     
    
    ... ... @@ -1957,9 +1964,7 @@ rebuildLam env bndrs@(bndr:_) body cont
    1957 1964
         mb_rhs   = contIsRhs cont
    
    1958 1965
     
    
    1959 1966
         -- See Note [Eta reduction based on evaluation context]
    
    1960
    -    eval_sd = contEvalContext cont
    
    1961
    -        -- NB: cont is never ApplyToVal, because beta-reduction would
    
    1962
    -        -- have happened.  So contEvalContext can panic on ApplyToVal.
    
    1967
    +    eval_sd = contEvalContext bndrs cont
    
    1963 1968
     
    
    1964 1969
         try_eta :: [OutBndr] -> OutExpr -> SimplM OutExpr
    
    1965 1970
         try_eta bndrs body