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

Commits:

4 changed files:

Changes:

  • compiler/GHC/Core/Opt/Arity.hs
    ... ... @@ -2875,43 +2875,44 @@ pushCoArg :: CoercionR -> CoreArg -> Maybe (CoreArg, MCoercion)
    2875 2875
     -- 'co' is always Representational
    
    2876 2876
     pushCoArg co arg
    
    2877 2877
       | Type ty <- arg
    
    2878
    -  = do { (ty', m_co') <- pushCoTyArg co ty
    
    2878
    +  = do { (_, ty', m_co') <- pushCoTyArg co ty
    
    2879 2879
            ; return (Type ty', m_co') }
    
    2880 2880
       | otherwise
    
    2881
    -  = do { (arg_mco, m_co') <- pushCoValArg co
    
    2881
    +  = do { (_, arg_mco, m_co') <- pushCoValArg co
    
    2882 2882
            ; let arg_mco' = checkReflexiveMCo arg_mco
    
    2883 2883
                  -- checkReflexiveMCo: see Note [Check for reflexive casts in eta expansion]
    
    2884 2884
                  -- The coercion is very often (arg_co -> res_co), but without
    
    2885 2885
                  -- the argument coercion actually being ReflCo
    
    2886 2886
            ; return (arg `mkCastMCo` arg_mco', m_co') }
    
    2887 2887
     
    
    2888
    -pushCoTyArg :: CoercionR -> Type -> Maybe (Type, MCoercionR)
    
    2888
    +pushCoTyArg :: CoercionR -> Type -> Maybe (Type, Type, MCoercionR)
    
    2889 2889
     -- We have (fun |> co) @ty
    
    2890 2890
     -- Push the coercion through to return
    
    2891 2891
     --         (fun @ty') |> co'
    
    2892 2892
     -- 'co' is always Representational
    
    2893 2893
     -- If the returned coercion is Nothing, then it would have been reflexive;
    
    2894 2894
     -- it's faster not to compute it, though.
    
    2895
    -pushCoTyArg co ty
    
    2895
    +pushCoTyArg co arg_ty
    
    2896 2896
       -- The following is inefficient - don't do `eqType` here, the coercion
    
    2897 2897
       -- optimizer will take care of it. See #14737.
    
    2898 2898
       -- -- | tyL `eqType` tyR
    
    2899 2899
       -- -- = Just (ty, Nothing)
    
    2900 2900
     
    
    2901
    -  | isReflCo co
    
    2902
    -  = Just (ty, MRefl)
    
    2901
    +  | Just (ty, _) <- isReflCo_maybe co
    
    2902
    +  = Just (ty, arg_ty, MRefl)
    
    2903 2903
     
    
    2904 2904
       | isForAllTy_ty tyL
    
    2905
    -  = assertPpr (isForAllTy_ty tyR) (ppr co $$ ppr ty) $
    
    2906
    -    Just (ty `mkCastTy` co1, MCo co2)
    
    2905
    +  = assertPpr (isForAllTy_ty tyR) (ppr co $$ ppr arg_ty) $
    
    2906
    +    Just (tyL, arg_ty `mkCastTy` co1, MCo co2)
    
    2907 2907
     
    
    2908 2908
       | otherwise
    
    2909 2909
       = Nothing
    
    2910 2910
       where
    
    2911
    -    Pair tyL tyR = coercionKind co
    
    2912
    -       -- co :: tyL ~R tyR
    
    2913
    -       -- tyL = forall (a1 :: k1). ty1
    
    2914
    -       -- tyR = forall (a2 :: k2). ty2
    
    2911
    +    -- co :: tyL ~R tyR
    
    2912
    +    -- tyL = forall (a1 :: k1). ty1
    
    2913
    +    -- tyR = forall (a2 :: k2). ty2
    
    2914
    +    tyL = coercionLKind co
    
    2915
    +    tyR = coercionRKind co -- Used only in asssertions and debug messages
    
    2915 2916
     
    
    2916 2917
         co1 = mkSymCo (mkSelCo SelForAll co)
    
    2917 2918
            -- co1 :: k2 ~N k1
    
    ... ... @@ -2919,30 +2920,32 @@ pushCoTyArg co ty
    2919 2920
            -- kinds of the types related by a coercion between forall-types.
    
    2920 2921
            -- See the SelCo case in GHC.Core.Lint.
    
    2921 2922
     
    
    2922
    -    co2 = mkInstCo co (mkGReflLeftCo Nominal ty co1)
    
    2923
    -        -- co2 :: ty1[ (ty|>co1)/a1 ] ~R ty2[ ty/a2 ]
    
    2923
    +    co2 = mkInstCo co (mkGReflLeftCo Nominal arg_ty co1)
    
    2924
    +        -- co2 :: ty1[ (arg_ty|>co1)/a1 ] ~R ty2[ arg_ty/a2 ]
    
    2924 2925
             -- Arg of mkInstCo is always nominal, hence Nominal
    
    2925 2926
     
    
    2926
    --- | If @pushCoValArg co = Just (co_arg, co_res)@, then
    
    2927
    +-- | If @pushCoValArg co = Just (tyL, co_arg, co_res)@, then
    
    2927 2928
     --
    
    2928
    --- > (\x.body) |> co  =  (\y. let { x = y |> co_arg } in body) |> co_res)
    
    2929
    +--   co :: tyL ~R# tyR
    
    2930
    +-- and
    
    2931
    +--   (\x.body) |> co  =  (\y. let { x = y |> co_arg } in body) |> co_res)
    
    2929 2932
     --
    
    2930 2933
     -- or, equivalently
    
    2931 2934
     --
    
    2932
    --- > (fun |> co) arg  =  (fun (arg |> co_arg)) |> co_res
    
    2935
    +--    (fun |> co) arg  =  (fun (arg |> co_arg)) |> co_res
    
    2933 2936
     --
    
    2934 2937
     -- If the LHS is well-typed, then so is the RHS. In particular, the argument
    
    2935 2938
     -- @arg |> co_arg@ is guaranteed to have a fixed 'RuntimeRep', in the sense of
    
    2936 2939
     -- Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete.
    
    2937
    -pushCoValArg :: CoercionR -> Maybe (MCoercionR, MCoercionR)
    
    2940
    +pushCoValArg :: CoercionR -> Maybe (Type, MCoercionR, MCoercionR)
    
    2938 2941
     pushCoValArg co
    
    2939 2942
       -- The following is inefficient - don't do `eqType` here, the coercion
    
    2940 2943
       -- optimizer will take care of it. See #14737.
    
    2941 2944
       -- -- | tyL `eqType` tyR
    
    2942 2945
       -- -- = Just (mkRepReflCo arg, Nothing)
    
    2943 2946
     
    
    2944
    -  | isReflCo co
    
    2945
    -  = Just (MRefl, MRefl)
    
    2947
    +  | Just (ty, _) <- isReflCo_maybe co
    
    2948
    +  = Just (ty, MRefl, MRefl)
    
    2946 2949
     
    
    2947 2950
       | isFunTy tyL
    
    2948 2951
       , (_, co1, co2) <- decomposeFunCo co
    
    ... ... @@ -2961,7 +2964,7 @@ pushCoValArg co
    2961 2964
          (vcat [ text "co:" <+> ppr co
    
    2962 2965
                , text "old_arg_ty:" <+> ppr old_arg_ty
    
    2963 2966
                , text "new_arg_ty:" <+> ppr new_arg_ty ]) $
    
    2964
    -    Just (coToMCo (mkSymCo co1), coToMCo co2)
    
    2967
    +    Just (tyL, coToMCo (mkSymCo co1), coToMCo co2)
    
    2965 2968
         -- Critically, coToMCo to checks for ReflCo; the whole coercion may not
    
    2966 2969
         -- be reflexive, but either of its components might be
    
    2967 2970
         -- We could use isReflexiveCo, but it's not clear if the benefit
    
    ... ... @@ -2970,9 +2973,12 @@ pushCoValArg co
    2970 2973
       | otherwise
    
    2971 2974
       = Nothing
    
    2972 2975
       where
    
    2973
    -    old_arg_ty = funArgTy tyR
    
    2976
    +    tyL        = coercionLKind co
    
    2974 2977
         new_arg_ty = funArgTy tyL
    
    2975
    -    Pair tyL tyR = coercionKind co
    
    2978
    +
    
    2979
    +    -- These two are used only in assertions and debug messages
    
    2980
    +    tyR        = coercionRKind co
    
    2981
    +    old_arg_ty = funArgTy tyR
    
    2976 2982
     
    
    2977 2983
     pushCoercionIntoLambda
    
    2978 2984
         :: HasDebugCallStack => InScopeSet -> Var -> CoreExpr -> CoercionR -> Maybe (Var, CoreExpr)
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -17,8 +17,7 @@ import GHC.Driver.Flags
    17 17
     import GHC.Core
    
    18 18
     import GHC.Core.Opt.Simplify.Monad
    
    19 19
     import GHC.Core.Opt.ConstantFold
    
    20
    -import GHC.Core.Type hiding ( substCo, substTy, substTyVar, extendTvSubst, extendCvSubst )
    
    21
    -import GHC.Core.TyCo.Compare( eqType )
    
    20
    +import GHC.Core.Opt.Stats ( Tick(..) )
    
    22 21
     import GHC.Core.Opt.Simplify.Env
    
    23 22
     import GHC.Core.Opt.Simplify.Inline
    
    24 23
     import GHC.Core.Opt.Simplify.Utils
    
    ... ... @@ -26,11 +25,14 @@ import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr, zapLambdaBndrs )
    26 25
     import GHC.Core.Make       ( FloatBind, mkImpossibleExpr, castBottomExpr )
    
    27 26
     import qualified GHC.Core.Make
    
    28 27
     import GHC.Core.Coercion hiding ( substCo, substCoVar )
    
    28
    +import qualified GHC.Core.Coercion as Coercion
    
    29 29
     import GHC.Core.Reduction
    
    30 30
     import GHC.Core.Coercion.Opt    ( optCoercion )
    
    31
    +import GHC.Core.Type hiding ( substCo, substTy, substTyVar, extendTvSubst, extendCvSubst )
    
    32
    +import GHC.Core.TyCo.Compare( eqType )
    
    33
    +import GHC.Core.TyCo.Subst( isEmptyTvSubst )
    
    31 34
     import GHC.Core.FamInstEnv      ( FamInstEnv, topNormaliseType_maybe )
    
    32 35
     import GHC.Core.DataCon
    
    33
    -import GHC.Core.Opt.Stats ( Tick(..) )
    
    34 36
     import GHC.Core.Ppr     ( pprCoreExpr )
    
    35 37
     import GHC.Core.Unfold
    
    36 38
     import GHC.Core.Unfold.Make
    
    ... ... @@ -1399,16 +1401,38 @@ simplCoercionF env co cont
    1399 1401
     
    
    1400 1402
     simplCoercion :: SimplEnv -> InCoercion -> SimplM OutCoercion
    
    1401 1403
     simplCoercion env co
    
    1402
    -  = do { let opt_co | reSimplifying env = substCo env co
    
    1403
    -                    | otherwise         = optCoercion opts subst co
    
    1404
    -             -- If (reSimplifying env) is True we have already simplified
    
    1405
    -             -- this coercion once, and we don't want do so again; doing
    
    1406
    -             -- so repeatedly risks non-linear behaviour
    
    1407
    -             -- See Note [Inline depth] in GHC.Core.Opt.Simplify.Env
    
    1408
    -       ; seqCo opt_co `seq` return opt_co }
    
    1404
    +  = seqCo opt_co `seq` return opt_co
    
    1409 1405
       where
    
    1406
    +    -- See Note [Optimising coercions]
    
    1407
    +    -- NB: substCo has a short-cut when both type and coercion substs are empty
    
    1408
    +    opt_co | subst_only  = Coercion.substCo subst co
    
    1409
    +           | otherwise   = optCoercion opts subst co
    
    1410
    +
    
    1410 1411
         subst = getTCvSubst env
    
    1411 1412
         opts  = seOptCoercionOpts env
    
    1413
    +    subst_only = isEmptyTvSubst subst || reSimplifying env
    
    1414
    +
    
    1415
    +{- Note [Optimising coercions]
    
    1416
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1417
    +Some programs have very big coercions and we'd like to avoid repeatedly
    
    1418
    +re-optimising them:
    
    1419
    +
    
    1420
    +* If the type-substitution is empty (common when no further transformations
    
    1421
    +  are taking place) then there is generally no point in re-optimising.
    
    1422
    +  If there is a type substitution, however, Refls may appear.
    
    1423
    +  Example where this isEmptyTCvSubst test really helped: aT5030.
    
    1424
    +
    
    1425
    +  Actually, if this is a "freshly-made" coercion (one built in the previous
    
    1426
    +  iteration of the Simplifier, or a previous pass) then perhaps optimisations
    
    1427
    +  /could/ occur; but we check for reflexivity in `rebuild_go`, and that's the
    
    1428
    +  big win. Otherwise having a bigger-than necessary coercion is no so bad.
    
    1429
    +
    
    1430
    +* (reSimplifying env) is True we are in the body of an inlined function
    
    1431
    +  so we (conservatively) and we don't want do so again; doing so repeatedly
    
    1432
    +  risks non-linear behaviour.  See Note [Inline depth] in GHC.Core.Opt.Simplify.Env.
    
    1433
    +
    
    1434
    +  But if the inlining did a type substitution maybe we should re-optimise?
    
    1435
    +-}
    
    1412 1436
     
    
    1413 1437
     -----------------------------------
    
    1414 1438
     -- | Push a TickIt context outwards past applications and cases, as
    
    ... ... @@ -1742,6 +1766,9 @@ pushCast :: SimplEnv -> OutCoercion -> SimplCont -> SimplM SimplCont
    1742 1766
     pushCast env co cont
    
    1743 1767
       = go co True cont
    
    1744 1768
       where
    
    1769
    +
    
    1770
    +    -- ToDo:   pushCast Refl (ApplylToVal arg1 (ApplyToVal arg2 ...))
    
    1771
    +    --         will do lots of unnecessary work.
    
    1745 1772
         go :: OutCoercion -> Bool -> SimplCont -> SimplM SimplCont
    
    1746 1773
         go co1 _ (CastIt { sc_co = co2, sc_cont = cont })  -- See Note [Optimising reflexivity]
    
    1747 1774
           = go (mkTransCo co1 co2) False cont
    
    ... ... @@ -1749,12 +1776,12 @@ pushCast env co cont
    1749 1776
                       -- See Note [Avoid re-simplifying coercions]
    
    1750 1777
     
    
    1751 1778
         go co co_is_opt (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail })
    
    1752
    -      | Just (arg_ty', m_co') <- pushCoTyArg co arg_ty
    
    1779
    +      | Just (tyL, arg_ty', m_co') <- pushCoTyArg co arg_ty
    
    1753 1780
           = {-#SCC "addCoerce-pushCoTyArg" #-}
    
    1754 1781
             do { tail' <- go_mco m_co' co_is_opt tail
    
    1755 1782
                ; return (ApplyToTy { sc_arg_ty  = arg_ty'
    
    1756 1783
                                    , sc_cont    = tail'
    
    1757
    -                               , sc_hole_ty = coercionLKind co }) }
    
    1784
    +                               , sc_hole_ty = tyL }) }
    
    1758 1785
                                         -- NB!  As the cast goes past, the
    
    1759 1786
                                         -- type of the hole changes (#16312)
    
    1760 1787
     
    
    ... ... @@ -1768,16 +1795,14 @@ pushCast env co cont
    1768 1795
           = -- pushCoValArg duplicates the coercion, so optimise first
    
    1769 1796
             go (optOutCoercion (zapSubstEnv env) co co_is_opt) True cont
    
    1770 1797
     
    
    1771
    --- ToDo: return coercionLKind. And similarly pushCoTyArg
    
    1772
    -
    
    1773
    -      | Just (m_co1, m_co2) <- pushCoValArg co
    
    1798
    +      | Just (tyL, m_co1, m_co2) <- pushCoValArg co
    
    1774 1799
           = {-#SCC "addCoerce-pushCoValArg" #-}
    
    1775
    -        do { tail' <- go_mco m_co2 co_is_opt tail
    
    1800
    +        do { tail' <- go_mco m_co2 True tail
    
    1776 1801
                ; return (ApplyToVal { sc_arg  = arg
    
    1777 1802
                                     , sc_env  = arg_se
    
    1778 1803
                                     , sc_cast = arg_mco `mkTransMCo` m_co1
    
    1779 1804
                                     , sc_cont = tail'
    
    1780
    -                                , sc_hole_ty = coercionLKind co }) }
    
    1805
    +                                , sc_hole_ty = tyL }) }
    
    1781 1806
     
    
    1782 1807
         go co co_is_opt cont
    
    1783 1808
           | isReflCo co = return cont  -- Having this at the end makes a huge
    
    ... ... @@ -1785,8 +1810,6 @@ pushCast env co cont
    1785 1810
                                        -- See Note [Optimising reflexivity]
    
    1786 1811
           | otherwise = return (CastIt { sc_co = co, sc_opt = co_is_opt, sc_cont = cont })
    
    1787 1812
     
    
    1788
    --- ToDo:   pushCast Refl (ApplylToVal arg1 (ApplyToVal arg2 ...))  will do lots of unnecessary work.
    
    1789
    -
    
    1790 1813
             -- If the first parameter is MRefl, then simplifying revealed a
    
    1791 1814
             -- reflexive coercion. Omit.
    
    1792 1815
         go_mco :: MOutCoercion -> Bool -> SimplCont -> SimplM SimplCont
    

  • compiler/GHC/Core/TyCo/Subst.hs
    ... ... @@ -12,7 +12,7 @@ module GHC.Core.TyCo.Subst
    12 12
             -- * Substitutions
    
    13 13
             Subst(..), TvSubstEnv, CvSubstEnv, IdSubstEnv,
    
    14 14
             emptyIdSubstEnv, emptyTvSubstEnv, emptyCvSubstEnv, composeTCvSubst,
    
    15
    -        emptySubst, mkEmptySubst, isEmptyTCvSubst, isEmptySubst,
    
    15
    +        emptySubst, mkEmptySubst, isEmptyTvSubst, isEmptyTCvSubst, isEmptySubst,
    
    16 16
             mkSubst, mkTCvSubst, mkTvSubst, mkCvSubst, mkIdSubst,
    
    17 17
             getTvSubstEnv, getIdSubstEnv,
    
    18 18
             getCvSubstEnv, substInScopeSet, setInScope, getSubstRangeTyCoFVs,
    
    ... ... @@ -262,6 +262,11 @@ isEmptySubst :: Subst -> Bool
    262 262
     isEmptySubst (Subst _ id_env tv_env cv_env)
    
    263 263
       = isEmptyVarEnv id_env && isEmptyVarEnv tv_env && isEmptyVarEnv cv_env
    
    264 264
     
    
    265
    +-- | Checks if the type substitution (only) is empty
    
    266
    +isEmptyTvSubst :: Subst -> Bool
    
    267
    +isEmptyTvSubst (Subst _ _ tv_env _)
    
    268
    +  = isEmptyVarEnv tv_env
    
    269
    +
    
    265 270
     -- | Checks whether the tyvar and covar environments are empty.
    
    266 271
     -- This function should be used over 'isEmptySubst' when substituting
    
    267 272
     -- for types, because types currently do not contain expressions; we can
    

  • compiler/GHC/Tc/Types/Evidence.hs
    ... ... @@ -59,7 +59,6 @@ import GHC.Tc.Utils.TcType
    59 59
     import GHC.Core
    
    60 60
     import GHC.Core.Coercion.Axiom
    
    61 61
     import GHC.Core.Coercion
    
    62
    -import GHC.Core.Utils( mkCast )
    
    63 62
     import GHC.Core.Ppr ()   -- Instance OutputableBndr TyVar
    
    64 63
     import GHC.Core.Predicate
    
    65 64
     import GHC.Core.Type
    
    ... ... @@ -932,7 +931,8 @@ evCastE ee co
    932 931
       | assertPpr (coercionRole co == Representational)
    
    933 932
                   (vcat [text "Coercion of wrong role passed to evCastE:", ppr ee, ppr co]) $
    
    934 933
         isReflCo co = ee
    
    935
    -  | otherwise   = mkCast ee co
    
    934
    +  | otherwise   = Cast ee co   -- Do not call mkCast because its assertion
    
    935
    +                               -- checks fail on un-zonked terms (#27219)
    
    936 936
     
    
    937 937
     evDFunApp :: DFunId -> [Type] -> [EvExpr] -> EvTerm
    
    938 938
     -- Dictionary instance application, including when the "dictionary function"