Adam Gundry pushed to branch wip/amg/castz at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/Opt/Arity.hs
    ... ... @@ -2246,13 +2246,13 @@ etaInfoApp in_scope expr eis
    2246 2246
         -- Beta-reduction if possible, pushing any intervening casts past
    
    2247 2247
         -- the argument. See Note [The EtaInfo mechanism]
    
    2248 2248
         go subst (Lam v e) (EI (b:bs) mco)
    
    2249
    -      | Just (arg,mco') <- pushCoArg (exprType (Lam v e)) mco (varToCoreExpr b)
    
    2249
    +      | Just (arg,_, mco') <- pushCoArg (exprType (Lam v e)) mco (varToCoreExpr b)
    
    2250 2250
           = go (Core.extendSubst subst v arg) e (EI bs mco')
    
    2251 2251
     
    
    2252 2252
         -- Stop pushing down; just wrap the expression up
    
    2253 2253
         -- See Note [Check for reflexive casts in eta expansion]
    
    2254 2254
         go subst e (EI bs mco) = Core.substExprSC subst e
    
    2255
    -                             `mkCastCo` checkReflexiveCastCo (exprType e) mco -- TODO check type
    
    2255
    +                             `mkCastCo` checkReflexiveCastCo (exprType e) mco
    
    2256 2256
                                  `mkVarApps` bs
    
    2257 2257
     
    
    2258 2258
     --------------
    
    ... ... @@ -2359,12 +2359,12 @@ mkEtaWW orig_oss ppr_orig_expr in_scope orig_ty
    2359 2359
             -- with an explicit lambda having a non-function type
    
    2360 2360
     
    
    2361 2361
     mkEtaForAllMCo :: ForAllTyBinder -> Type -> CastCoercion -> CastCoercion
    
    2362
    -mkEtaForAllMCo (Bndr tcv vis) ty mco
    
    2362
    +mkEtaForAllMCo bdnr@(Bndr tcv vis) ty mco
    
    2363 2363
       = case mco of
    
    2364 2364
           ReflCastCo | vis == coreTyLamForAllTyFlag -> ReflCastCo
    
    2365 2365
                      | otherwise                    -> mk_fco (mkRepReflCo ty)
    
    2366 2366
           CCoercion co                              -> mk_fco co
    
    2367
    -      ZCoercion _ty2 cos                         -> ZCoercion ty cos -- TODO: is ty right?
    
    2367
    +      ZCoercion tyR cos                         -> ZCoercion (mkForAllTy bdnr tyR) cos
    
    2368 2368
       where
    
    2369 2369
         mk_fco co = CCoercion (mkForAllCo tcv vis coreTyLamForAllTyFlag MRefl co)
    
    2370 2370
         -- coreTyLamForAllTyFlag: See Note [The EtaInfo mechanism], particularly
    
    ... ... @@ -2871,17 +2871,17 @@ Here we implement the "push rules" from FC papers:
    2871 2871
       by pushing the coercion into the arguments
    
    2872 2872
     -}
    
    2873 2873
     
    
    2874
    -pushCoArgs :: Type -> CastCoercion -> [CoreArg] -> Maybe ([CoreArg], CastCoercion)
    
    2875
    -pushCoArgs _ co []         = return ([], co)
    
    2874
    +pushCoArgs :: Type -> CastCoercion -> [CoreArg] -> Maybe ([CoreArg], Type, CastCoercion)
    
    2875
    +pushCoArgs fun_ty co []         = return ([], fun_ty, co)
    
    2876 2876
     pushCoArgs fun_ty co (arg:args) = do
    
    2877
    -    { (arg',  m_co1) <- pushCoArg fun_ty co arg
    
    2877
    +    { (arg', ty, m_co1) <- pushCoArg fun_ty co arg
    
    2878 2878
         ; if isReflCastCo m_co1
    
    2879
    -        then return (arg':args, ReflCastCo)
    
    2880
    -        else do { (args', m_co2) <- pushCoArgs (funResultTy fun_ty) m_co1 args -- TODO check type
    
    2881
    -                ; return (arg':args', m_co2) }
    
    2879
    +        then return (arg':args, ty, ReflCastCo)
    
    2880
    +        else do { (args', ty', m_co2) <- pushCoArgs ty m_co1 args
    
    2881
    +                ; return (arg':args', ty', m_co2) }
    
    2882 2882
         }
    
    2883 2883
     
    
    2884
    -pushCoArg :: Type -> CastCoercion -> CoreArg -> Maybe (CoreArg, CastCoercion)
    
    2884
    +pushCoArg :: Type -> CastCoercion -> CoreArg -> Maybe (CoreArg, Type, CastCoercion)
    
    2885 2885
     -- We have (fun |> co) arg, and we want to transform it to
    
    2886 2886
     --         (fun arg) |> co
    
    2887 2887
     -- This may fail, e.g. if (fun :: N) where N is a newtype
    
    ... ... @@ -2889,22 +2889,22 @@ pushCoArg :: Type -> CastCoercion -> CoreArg -> Maybe (CoreArg, CastCoercion)
    2889 2889
     -- 'co' is always Representational
    
    2890 2890
     pushCoArg fun_ty co arg
    
    2891 2891
       | Type ty <- arg
    
    2892
    -  = do { (ty', m_co') <- pushCastCoTyArg co ty
    
    2893
    -       ; return (Type ty', m_co') }
    
    2892
    +  = do { (ty', ty, m_co') <- pushCastCoTyArg co ty
    
    2893
    +       ; return (Type ty', ty, m_co') }
    
    2894 2894
       | otherwise
    
    2895
    -  = do { (arg_mco, m_co') <- pushCastCoValArg fun_ty co
    
    2896
    -       ; let arg_mco' = checkReflexiveCastCo (funArgTy fun_ty) arg_mco
    
    2895
    +  = do { (arg_ty, arg_mco, res_ty, m_co') <- pushCastCoValArg fun_ty co
    
    2896
    +       ; let arg_mco' = checkReflexiveCastCo arg_ty arg_mco
    
    2897 2897
                  -- checkReflexiveCastCo: see Note [Check for reflexive casts in eta expansion]
    
    2898 2898
                  -- The coercion is very often (arg_co -> res_co), but without
    
    2899 2899
                  -- the argument coercion actually being ReflCo
    
    2900
    -       ; return (arg `mkCastCo` arg_mco', m_co') }
    
    2900
    +       ; return (arg `mkCastCo` arg_mco', res_ty, m_co') }
    
    2901 2901
     
    
    2902
    -pushCastCoTyArg :: CastCoercion -> Type -> Maybe (Type, CastCoercion)
    
    2902
    +pushCastCoTyArg :: CastCoercion -> Type -> Maybe (Type, Type, CastCoercion)
    
    2903 2903
     pushCastCoTyArg (CCoercion co)         ty = pushCoTyArg co ty
    
    2904
    -pushCastCoTyArg ReflCastCo             ty = Just (ty, ReflCastCo)
    
    2904
    +pushCastCoTyArg ReflCastCo             ty = Just (ty, error "TODO: asdasdad", ReflCastCo)
    
    2905 2905
     pushCastCoTyArg (ZCoercion _fun_ty _cos) _ty = Nothing -- TODO do better
    
    2906 2906
     
    
    2907
    -pushCoTyArg :: CoercionR -> Type -> Maybe (Type, CastCoercion)
    
    2907
    +pushCoTyArg :: CoercionR -> Type -> Maybe (Type, Type, CastCoercion)
    
    2908 2908
     -- We have (fun |> co) @ty
    
    2909 2909
     -- Push the coercion through to return
    
    2910 2910
     --         (fun @ty') |> co'
    
    ... ... @@ -2916,11 +2916,11 @@ pushCoTyArg co ty
    2916 2916
       -- -- = Just (ty, Nothing)
    
    2917 2917
     
    
    2918 2918
       | isReflCo co
    
    2919
    -  = Just (ty, ReflCastCo)
    
    2919
    +  = Just (ty, coercionLKind co2, ReflCastCo)
    
    2920 2920
     
    
    2921 2921
       | isForAllTy_ty tyL
    
    2922 2922
       = assertPpr (isForAllTy_ty tyR) (ppr co $$ ppr ty) $
    
    2923
    -    Just (ty `mkCastTy` co1, CCoercion co2)
    
    2923
    +    Just (ty `mkCastTy` co1, coercionLKind co2, CCoercion co2)
    
    2924 2924
     
    
    2925 2925
       | otherwise
    
    2926 2926
       = Nothing
    
    ... ... @@ -2940,14 +2940,14 @@ pushCoTyArg co ty
    2940 2940
             -- co2 :: ty1[ (ty|>co1)/a1 ] ~R ty2[ ty/a2 ]
    
    2941 2941
             -- Arg of mkInstCo is always nominal, hence Nominal
    
    2942 2942
     
    
    2943
    -pushCastCoValArg :: Type -> CastCoercion -> Maybe (CastCoercion, CastCoercion)
    
    2944
    -pushCastCoValArg _ ReflCastCo         = Just (ReflCastCo, ReflCastCo)
    
    2943
    +pushCastCoValArg :: Type -> CastCoercion -> Maybe (Type, CastCoercion, Type, CastCoercion)
    
    2944
    +pushCastCoValArg tyL ReflCastCo       = Just (funArgTy tyL, ReflCastCo, funResultTy tyL, ReflCastCo)
    
    2945 2945
     pushCastCoValArg _ (CCoercion co)     = pushCoValArg co
    
    2946 2946
     pushCastCoValArg tyL (ZCoercion tyR cos)
    
    2947 2947
       | isFunTy tyL  -- TODO: do we need to check this or can we assume it?
    
    2948 2948
       , isFunTy tyR
    
    2949 2949
       , typeHasFixedRuntimeRep new_arg_ty
    
    2950
    -              = Just (ZCoercion new_arg_ty cos, ZCoercion (funResultTy tyR) cos)
    
    2950
    +              = Just (funArgTy tyL, ZCoercion new_arg_ty cos, funResultTy tyL, ZCoercion (funResultTy tyR) cos)
    
    2951 2951
       | otherwise = Nothing
    
    2952 2952
       where
    
    2953 2953
         new_arg_ty = funArgTy tyR
    
    ... ... @@ -2963,7 +2963,7 @@ pushCastCoValArg tyL (ZCoercion tyR cos)
    2963 2963
     -- If the LHS is well-typed, then so is the RHS. In particular, the argument
    
    2964 2964
     -- @arg |> co_arg@ is guaranteed to have a fixed 'RuntimeRep', in the sense of
    
    2965 2965
     -- Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete.
    
    2966
    -pushCoValArg :: CoercionR -> Maybe (CastCoercion, CastCoercion)
    
    2966
    +pushCoValArg :: CoercionR -> Maybe (Type, CastCoercion, Type, CastCoercion)
    
    2967 2967
     pushCoValArg co
    
    2968 2968
       -- The following is inefficient - don't do `eqType` here, the coercion
    
    2969 2969
       -- optimizer will take care of it. See #14737.
    
    ... ... @@ -2971,7 +2971,7 @@ pushCoValArg co
    2971 2971
       -- -- = Just (mkRepReflCo arg, Nothing)
    
    2972 2972
     
    
    2973 2973
       | isReflCo co
    
    2974
    -  = Just (ReflCastCo, ReflCastCo)
    
    2974
    +  = Just (old_arg_ty, ReflCastCo, funResultTy tyL, ReflCastCo)
    
    2975 2975
     
    
    2976 2976
       | isFunTy tyL
    
    2977 2977
       , (_, co1, co2) <- decomposeFunCo co
    
    ... ... @@ -2990,7 +2990,7 @@ pushCoValArg co
    2990 2990
          (vcat [ text "co:" <+> ppr co
    
    2991 2991
                , text "old_arg_ty:" <+> ppr old_arg_ty
    
    2992 2992
                , text "new_arg_ty:" <+> ppr new_arg_ty ]) $
    
    2993
    -    Just (coToCastCo (mkSymCo co1), coToCastCo co2)
    
    2993
    +    Just (old_arg_ty, coToCastCo (mkSymCo co1), funResultTy tyL, coToCastCo co2)
    
    2994 2994
         -- Critically, coToCastCo to checks for ReflCo; the whole coercion may not
    
    2995 2995
         -- be reflexive, but either of its components might be
    
    2996 2996
         -- We could use isReflexiveCo, but it's not clear if the benefit
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -1715,10 +1715,10 @@ simplCast env body co0 cont0
    1715 1715
                           -- False: (mkTransCo co1 co2) is not fully optimised
    
    1716 1716
                           -- See Note [Avoid re-simplifying coercions]
    
    1717 1717
     
    
    1718
    -        addCoerce tyL co co_is_opt (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = tail })
    
    1719
    -          | Just (arg_ty', m_co') <- pushCastCoTyArg co arg_ty
    
    1718
    +        addCoerce tyL co co_is_opt (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail })
    
    1719
    +          | Just (arg_ty', res_ty, m_co') <- pushCastCoTyArg co arg_ty
    
    1720 1720
               = {-#SCC "addCoerce-pushCoTyArg" #-}
    
    1721
    -            do { tail' <- addCoerceM hole_ty m_co' co_is_opt tail -- TODO is hole_ty right?
    
    1721
    +            do { tail' <- addCoerceM res_ty m_co' co_is_opt tail
    
    1722 1722
                    ; return (ApplyToTy { sc_arg_ty  = arg_ty'
    
    1723 1723
                                        , sc_cont    = tail'
    
    1724 1724
                                        , sc_hole_ty = tyL }) }
    
    ... ... @@ -1734,9 +1734,9 @@ simplCast env body co0 cont0
    1734 1734
               | not co_is_opt  -- pushCoValArg duplicates the coercion, so optimise first
    
    1735 1735
               = addCoerce tyL (optOutCastCoercion (zapSubstEnv env) co co_is_opt) True cont
    
    1736 1736
     
    
    1737
    -          | Just (m_co1, m_co2) <- pushCastCoValArg fun_ty co -- TODO check fun_ty
    
    1737
    +          | Just (_, m_co1, res_ty, m_co2) <- pushCastCoValArg tyL co
    
    1738 1738
               = {-#SCC "addCoerce-pushCoValArg" #-}
    
    1739
    -            do { tail' <- addCoerceM (funResultTy fun_ty) m_co2 co_is_opt tail -- TODO check funResultTy fun_ty
    
    1739
    +            do { tail' <- addCoerceM res_ty m_co2 co_is_opt tail
    
    1740 1740
                    ; if isReflCastCo m_co1
    
    1741 1741
                        then return (cont { sc_cont = tail'
    
    1742 1742
                                              , sc_hole_ty = tyL }) ;
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -1376,7 +1376,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
    1376 1376
            | not (tickishIsCode t) = go subst floats expr cont
    
    1377 1377
     
    
    1378 1378
         go subst floats (Cast expr co1) (CC args m_co2) -- TODO: is the subst_ty below needed?
    
    1379
    -       | Just (args', m_co1') <- pushCoArgs (subst_ty subst (exprType expr)) (subst_cast_co subst co1) args
    
    1379
    +       | Just (args', _, m_co1') <- pushCoArgs (subst_ty subst (exprType expr)) (subst_cast_co subst co1) args
    
    1380 1380
                 -- See Note [Push coercions in exprIsConApp_maybe]
    
    1381 1381
            = go subst floats expr (CC args' (m_co1' `mkTransCastCo` m_co2))
    
    1382 1382