Simon Peyton Jones pushed to branch wip/spj-try-opt-coercion at Glasgow Haskell Compiler / GHC
Commits:
-
760fe6e0
by Simon Peyton Jones at 2026-01-02T14:02:20+00:00
8 changed files:
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg.hs
Changes:
| 1 | +{-# LANGUAGE MagicHash #-}
|
|
| 2 | + |
|
| 1 | 3 | {-
|
| 2 | 4 | (c) The University of Glasgow 2006
|
| 3 | 5 | -}
|
| ... | ... | @@ -23,6 +25,7 @@ module GHC.Core.Coercion ( |
| 23 | 25 | coercionType, mkCoercionType,
|
| 24 | 26 | coercionKind, coercionLKind, coercionRKind,coercionKinds,
|
| 25 | 27 | coercionRole, coercionKindRole,
|
| 28 | + coercionIsSmall,
|
|
| 26 | 29 | |
| 27 | 30 | -- ** Constructing coercions
|
| 28 | 31 | mkGReflCo, mkGReflMCo, mkReflCo, mkRepReflCo, mkNomReflCo,
|
| ... | ... | @@ -169,6 +172,8 @@ import qualified Data.Monoid as Monoid |
| 169 | 172 | import Data.List.NonEmpty ( NonEmpty (..) )
|
| 170 | 173 | import Control.DeepSeq
|
| 171 | 174 | |
| 175 | +import GHC.Exts
|
|
| 176 | + |
|
| 172 | 177 | {-
|
| 173 | 178 | %************************************************************************
|
| 174 | 179 | %* *
|
| ... | ... | @@ -2468,6 +2473,40 @@ seqCos :: [Coercion] -> () |
| 2468 | 2473 | seqCos [] = ()
|
| 2469 | 2474 | seqCos (co:cos) = seqCo co `seq` seqCos cos
|
| 2470 | 2475 | |
| 2476 | +coercionIsSmall :: Coercion -> Bool
|
|
| 2477 | +-- This function should return False quickly on a big coercion
|
|
| 2478 | +-- It should /not/ traverse the big coercion!
|
|
| 2479 | +coercionIsSmall co
|
|
| 2480 | + = not (isTrue# ((go co 100#) <# 0#))
|
|
| 2481 | + where
|
|
| 2482 | + go :: Coercion -> Int# -> Int#
|
|
| 2483 | + go _co n | isTrue# (n <# 0#) = n
|
|
| 2484 | + go (Refl {}) n = dec n
|
|
| 2485 | + go (GRefl _ _ mco) n = go_mco mco (dec n)
|
|
| 2486 | + go (TyConAppCo _ _ cos) n = go_cos cos (dec n)
|
|
| 2487 | + go (AxiomCo _ cos) n = go_cos cos (dec n)
|
|
| 2488 | + go (UnivCo _ _ _ _ cos) n = go_cos cos (dec n)
|
|
| 2489 | + go (AppCo co1 co2) n = go co1 (go co2 (dec n))
|
|
| 2490 | + go (CoVarCo {}) n = dec n
|
|
| 2491 | + go (HoleCo {}) n = dec n
|
|
| 2492 | + go (SymCo co) n = go co (dec n)
|
|
| 2493 | + go (KindCo co) n = go co (dec n)
|
|
| 2494 | + go (SubCo co) n = go co (dec n)
|
|
| 2495 | + go (TransCo co1 co2) n = go co1 (go co2 (dec n))
|
|
| 2496 | + go (SelCo _ co) n = go co (dec n)
|
|
| 2497 | + go (LRCo _ co) n = go co (dec n)
|
|
| 2498 | + go (InstCo co1 co2) n = go co1 (go co2 (dec n))
|
|
| 2499 | + go (ForAllCo _ _ _ kco co) n = go co (go_mco kco (dec n))
|
|
| 2500 | + go (FunCo _ _ _ mco aco rco) n = go mco (go aco (go rco (dec n)))
|
|
| 2501 | + |
|
| 2502 | + go_cos [] n = n
|
|
| 2503 | + go_cos (co:cos) n = go_cos cos (go co n)
|
|
| 2504 | + |
|
| 2505 | + go_mco MRefl n = dec n
|
|
| 2506 | + go_mco (MCo co) n = go co n
|
|
| 2507 | + |
|
| 2508 | + dec n = n -# 1#
|
|
| 2509 | + |
|
| 2471 | 2510 | {-
|
| 2472 | 2511 | %************************************************************************
|
| 2473 | 2512 | %* *
|
| ... | ... | @@ -845,10 +845,8 @@ unitLetFloat bind = assert (all (not . isJoinId) (bindersOf bind)) $ |
| 845 | 845 | where
|
| 846 | 846 | flag (Rec {}) = FltLifted
|
| 847 | 847 | flag (NonRec bndr rhs)
|
| 848 | - | not (isStrictId bndr) = FltLifted
|
|
| 849 | - | exprIsTickedString rhs = FltLifted
|
|
| 850 | - -- String literals can be floated freely.
|
|
| 851 | - -- See Note [Core top-level string literals] in GHC.Core.
|
|
| 848 | + | exprIsTopLevelBindable rhs (idType bndr) = FltLifted
|
|
| 849 | + -- Things that can float freely, including to top level
|
|
| 852 | 850 | | exprOkForSpeculation rhs = FltOkSpec -- Unlifted, and lifted but ok-for-spec (eg HNF)
|
| 853 | 851 | | otherwise = FltCareful
|
| 854 | 852 |
| ... | ... | @@ -597,15 +597,20 @@ tryCastWorkerWrapper env bind_cxt old_bndr bndr (Cast rhs co) |
| 597 | 597 | work_id = mkLocalIdWithInfo work_name ManyTy work_ty work_info
|
| 598 | 598 | is_strict = isStrictId bndr
|
| 599 | 599 | |
| 600 | + ; (co_floats, co') <- makeCoTrivial co
|
|
| 601 | + |
|
| 600 | 602 | ; (rhs_floats, work_rhs) <- prepareBinding env top_lvl is_rec is_strict
|
| 601 | 603 | work_id (emptyFloats env) rhs
|
| 602 | 604 | |
| 603 | 605 | ; work_unf <- mk_worker_unfolding top_lvl work_id work_rhs
|
| 606 | + |
|
| 604 | 607 | ; let work_id_w_unf = work_id `setIdUnfolding` work_unf
|
| 605 | - floats = rhs_floats `addLetFloats`
|
|
| 606 | - unitLetFloat (NonRec work_id_w_unf work_rhs)
|
|
| 608 | + work_float = unitLetFloat (NonRec work_id_w_unf work_rhs)
|
|
| 607 | 609 | |
| 608 | - triv_rhs = Cast (Var work_id_w_unf) co
|
|
| 610 | + floats = rhs_floats `addLetFloats`
|
|
| 611 | + (co_floats `addLetFlts` work_float)
|
|
| 612 | + |
|
| 613 | + triv_rhs = Cast (Var work_id_w_unf) co'
|
|
| 609 | 614 | |
| 610 | 615 | ; if postInlineUnconditionally env bind_cxt old_bndr bndr triv_rhs
|
| 611 | 616 | -- Almost always True, because the RHS is trivial
|
| ... | ... | @@ -715,12 +720,15 @@ prepareBinding env top_lvl is_rec strict_bind bndr rhs_floats rhs |
| 715 | 720 | ; let all_floats = rhs_floats1 `addLetFloats` anf_floats
|
| 716 | 721 | ; if doFloatFromRhs (seFloatEnable env) top_lvl is_rec strict_bind all_floats rhs2
|
| 717 | 722 | then -- Float!
|
| 723 | + simplTrace "prepareBinding:yes" (ppr all_floats $$ text "rhs" <+> ppr rhs2) $
|
|
| 718 | 724 | do { tick LetFloatFromLet
|
| 719 | 725 | ; return (all_floats, rhs2) }
|
| 720 | 726 | |
| 721 | 727 | else -- Abandon floating altogether; revert to original rhs
|
| 722 | 728 | -- Since we have already built rhs1, we just need to add
|
| 723 | 729 | -- rhs_floats1 to it
|
| 730 | + simplTrace "prepareBinding:no" (vcat [ ppr all_floats
|
|
| 731 | + , text "rhs" <+> ppr rhs2 ]) $
|
|
| 724 | 732 | return (emptyFloats env, wrapFloats rhs_floats1 rhs1) }
|
| 725 | 733 | |
| 726 | 734 | {- Note [prepareRhs]
|
| ... | ... | @@ -753,7 +761,9 @@ prepareRhs :: HasDebugCallStack |
| 753 | 761 | -- x = Just a
|
| 754 | 762 | -- See Note [prepareRhs]
|
| 755 | 763 | prepareRhs env top_lvl occ rhs0
|
| 756 | - | is_expandable = anfise rhs0
|
|
| 764 | + | is_expandable = do { (flts,rhs) <- anfise rhs0
|
|
| 765 | + ; pprTrace "prepareRhs" (ppr rhs0 $$ text "new" <+> ppr rhs) $
|
|
| 766 | + return (flts, rhs) }
|
|
| 757 | 767 | | otherwise = return (emptyLetFloats, rhs0)
|
| 758 | 768 | where
|
| 759 | 769 | -- We can't use exprIsExpandable because the WHOLE POINT is that
|
| ... | ... | @@ -762,7 +772,8 @@ prepareRhs env top_lvl occ rhs0 |
| 762 | 772 | -- just say no!
|
| 763 | 773 | is_expandable = go rhs0 0
|
| 764 | 774 | where
|
| 765 | - go (Var fun) n_val_args = isExpandableApp fun n_val_args
|
|
| 775 | + go (Var fun) n_val_args = pprTrace "is_exp" (ppr fun <+> ppr n_val_args $$ ppr (isExpandableApp fun n_val_args)) $
|
|
| 776 | + isExpandableApp fun n_val_args
|
|
| 766 | 777 | go (App fun arg) n_val_args
|
| 767 | 778 | | isTypeArg arg = go fun n_val_args
|
| 768 | 779 | | otherwise = go fun (n_val_args + 1)
|
| ... | ... | @@ -772,8 +783,9 @@ prepareRhs env top_lvl occ rhs0 |
| 772 | 783 | |
| 773 | 784 | anfise :: OutExpr -> SimplM (LetFloats, OutExpr)
|
| 774 | 785 | anfise (Cast rhs co)
|
| 775 | - = do { (floats, rhs') <- anfise rhs
|
|
| 776 | - ; return (floats, Cast rhs' co) }
|
|
| 786 | + = do { (floats1, rhs') <- anfise rhs
|
|
| 787 | + ; (floats2, co') <- makeCoTrivial co
|
|
| 788 | + ; return (floats1 `addLetFlts` floats2, Cast rhs' co') }
|
|
| 777 | 789 | anfise (App fun (Type ty))
|
| 778 | 790 | = do { (floats, rhs') <- anfise fun
|
| 779 | 791 | ; return (floats, App rhs' (Type ty)) }
|
| ... | ... | @@ -818,13 +830,19 @@ makeTrivial :: HasDebugCallStack |
| 818 | 830 | -- For the Demand argument, see Note [Keeping demand info in StrictArg Plan A]
|
| 819 | 831 | makeTrivial env top_lvl dmd occ_fs expr
|
| 820 | 832 | | exprIsTrivial expr -- Already trivial
|
| 821 | - || not (bindingOk top_lvl expr expr_ty) -- Cannot trivialise
|
|
| 822 | - -- See Note [Cannot trivialise]
|
|
| 823 | - = return (emptyLetFloats, expr)
|
|
| 833 | + = simplTrace "makeTrivial:triv" (ppr expr) $
|
|
| 834 | + return (emptyLetFloats, expr)
|
|
| 835 | + |
|
| 836 | + | not (bindingOk top_lvl expr expr_ty) -- Cannot trivialise
|
|
| 837 | + -- See Note [Cannot trivialise]
|
|
| 838 | + = simplTrace "makeTrivial:cannot" (ppr expr) $
|
|
| 839 | + return (emptyLetFloats, expr)
|
|
| 824 | 840 | |
| 825 | 841 | | Cast expr' co <- expr
|
| 826 | - = do { (floats, triv_expr) <- makeTrivial env top_lvl dmd occ_fs expr'
|
|
| 827 | - ; return (floats, Cast triv_expr co) }
|
|
| 842 | + = do { (floats1, triv_co) <- makeCoTrivial co
|
|
| 843 | + ; (floats2, triv_expr) <- makeTrivial env top_lvl dmd occ_fs expr'
|
|
| 844 | + ; simplTrace "makeTrivial:co" (ppr (Cast triv_expr triv_co)) $
|
|
| 845 | + return (floats1 `addLetFlts` floats2, Cast triv_expr triv_co) }
|
|
| 828 | 846 | |
| 829 | 847 | | otherwise -- 'expr' is not of form (Cast e co)
|
| 830 | 848 | = do { (floats, expr1) <- prepareRhs env top_lvl occ_fs expr
|
| ... | ... | @@ -850,6 +868,17 @@ makeTrivial env top_lvl dmd occ_fs expr |
| 850 | 868 | id_info = vanillaIdInfo `setDemandInfo` dmd
|
| 851 | 869 | expr_ty = exprType expr
|
| 852 | 870 | |
| 871 | +makeCoTrivial :: OutCoercion -> SimplM (LetFloats, OutCoercion)
|
|
| 872 | +makeCoTrivial co
|
|
| 873 | + | coercionIsSmall co
|
|
| 874 | + = return (emptyLetFloats, co)
|
|
| 875 | + | otherwise
|
|
| 876 | + = do { co_uniq <- getUniqueM
|
|
| 877 | + ; let co_name = mkSystemVarName co_uniq (fsLit "aco")
|
|
| 878 | + co_var = mkLocalCoVar co_name (coercionType co)
|
|
| 879 | + ; return ( unitLetFloat (NonRec co_var (Coercion co))
|
|
| 880 | + , mkCoVarCo co_var ) }
|
|
| 881 | + |
|
| 853 | 882 | bindingOk :: TopLevelFlag -> CoreExpr -> Type -> Bool
|
| 854 | 883 | -- True iff we can have a binding of this expression at this level
|
| 855 | 884 | -- Precondition: the type is the type of the expression
|
| ... | ... | @@ -1259,7 +1288,7 @@ simplExprF1 env (Let (NonRec bndr rhs) body) cont |
| 1259 | 1288 | | Just env' <- preInlineUnconditionally env NotTopLevel bndr rhs env
|
| 1260 | 1289 | -- Because of the let-can-float invariant, it's ok to
|
| 1261 | 1290 | -- inline freely, or to drop the binding if it is dead.
|
| 1262 | - = do { simplTrace "SimplBindr:inline-uncond2" (ppr bndr) $
|
|
| 1291 | + = do { simplTrace "SimplBindr:inline-uncond2" (ppr bndr <+> ppr rhs) $
|
|
| 1263 | 1292 | tick (PreInlineUnconditionally bndr)
|
| 1264 | 1293 | ; simplExprF env' body cont }
|
| 1265 | 1294 | |
| ... | ... | @@ -1758,12 +1787,12 @@ simpl_lam env bndr body (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont }) |
| 1758 | 1787 | ; simplLam (extendTvSubst env bndr arg_ty) body cont }
|
| 1759 | 1788 | |
| 1760 | 1789 | -- Coercion beta-reduction
|
| 1761 | -simpl_lam env bndr body (ApplyToVal { sc_arg = Coercion arg_co, sc_env = arg_se
|
|
| 1762 | - , sc_cont = cont })
|
|
| 1763 | - = assertPpr (isCoVar bndr) (ppr bndr) $
|
|
| 1764 | - do { tick (BetaReduction bndr)
|
|
| 1765 | - ; let arg_co' = substCo (arg_se `setInScopeFromE` env) arg_co
|
|
| 1766 | - ; simplLam (extendCvSubst env bndr arg_co') body cont }
|
|
| 1790 | +-- simpl_lam env bndr body (ApplyToVal { sc_arg = Coercion arg_co, sc_env = arg_se
|
|
| 1791 | +-- , sc_cont = cont })
|
|
| 1792 | +-- = assertPpr (isCoVar bndr) (ppr bndr) $
|
|
| 1793 | +-- do { tick (BetaReduction bndr)
|
|
| 1794 | +-- ; let arg_co' = substCo (arg_se `setInScopeFromE` env) arg_co
|
|
| 1795 | +-- ; simplLam (extendCvSubst env bndr arg_co') body cont }
|
|
| 1767 | 1796 | |
| 1768 | 1797 | -- Value beta-reduction
|
| 1769 | 1798 | -- This works for /coercion/ lambdas too
|
| ... | ... | @@ -1791,7 +1820,7 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se |
| 1791 | 1820 | , not ( isSimplified dup && -- See (SR2) in Note [Avoiding simplifying repeatedly]
|
| 1792 | 1821 | not (exprIsTrivial arg) &&
|
| 1793 | 1822 | not (isDeadOcc (idOccInfo bndr)) )
|
| 1794 | - -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr) $
|
|
| 1823 | + -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr <+> ppr arg) $
|
|
| 1795 | 1824 | tick (PreInlineUnconditionally bndr)
|
| 1796 | 1825 | ; simplLam env' body cont }
|
| 1797 | 1826 | |
| ... | ... | @@ -3688,9 +3717,9 @@ knownCon env scrut dc_floats dc dc_ty_args dc_args bndr bs rhs cont |
| 3688 | 3717 | = assert (isTyVar b )
|
| 3689 | 3718 | bind_args (extendTvSubst env' b ty) bs' args
|
| 3690 | 3719 | |
| 3691 | - bind_args env' (b:bs') (Coercion co : args)
|
|
| 3692 | - = assert (isCoVar b )
|
|
| 3693 | - bind_args (extendCvSubst env' b co) bs' args
|
|
| 3720 | +-- bind_args env' (b:bs') (Coercion co : args)
|
|
| 3721 | +-- = assert (isCoVar b )
|
|
| 3722 | +-- bind_args (extendCvSubst env' b co) bs' args
|
|
| 3694 | 3723 | |
| 3695 | 3724 | bind_args env' (b:bs') (arg : args)
|
| 3696 | 3725 | = assert (isId b) $
|
| ... | ... | @@ -1646,6 +1646,7 @@ postInlineUnconditionally env bind_cxt old_bndr bndr rhs |
| 1646 | 1646 | | isStableUnfolding unfolding = False -- Note [Stable unfoldings and postInlineUnconditionally]
|
| 1647 | 1647 | | isTopLevel (bindContextLevel bind_cxt)
|
| 1648 | 1648 | = False -- Note [Top level and postInlineUnconditionally]
|
| 1649 | + | isCoVar bndr = False
|
|
| 1649 | 1650 | | exprIsTrivial rhs = True
|
| 1650 | 1651 | | BC_Join {} <- bind_cxt = False -- See point (1) of Note [Duplicating join points]
|
| 1651 | 1652 | -- in GHC.Core.Opt.Simplify.Iteration
|
| ... | ... | @@ -191,7 +191,7 @@ ppr_expr :: OutputableBndr b => (SDoc -> SDoc) -> Expr b -> SDoc |
| 191 | 191 | |
| 192 | 192 | ppr_expr add_par (Var id) = ppr_id_occ add_par id
|
| 193 | 193 | ppr_expr add_par (Type ty) = add_par (text "TYPE:" <+> ppr ty) -- Weird
|
| 194 | -ppr_expr add_par (Coercion co) = add_par (text "CO:" <+> ppr co)
|
|
| 194 | +ppr_expr add_par (Coercion co) = add_par (text "CO:" <+> pprOptCo co)
|
|
| 195 | 195 | ppr_expr add_par (Lit lit) = pprLiteral add_par lit
|
| 196 | 196 | |
| 197 | 197 | ppr_expr add_par (Cast expr co)
|
| ... | ... | @@ -815,7 +815,7 @@ type CoercionN = Coercion -- always Nominal |
| 815 | 815 | type CoercionR = Coercion -- always Representational
|
| 816 | 816 | type CoercionP = Coercion -- always Phantom
|
| 817 | 817 | |
| 818 | -type MCoercionN = MCoercion -- alwyas Nominal
|
|
| 818 | +type MCoercionN = MCoercion -- always Nominal
|
|
| 819 | 819 | type MCoercionR = MCoercion -- always Representational
|
| 820 | 820 | |
| 821 | 821 | {- Note [KindCoercion]
|
| ... | ... | @@ -1280,37 +1280,44 @@ it off at source. |
| 1280 | 1280 | -}
|
| 1281 | 1281 | |
| 1282 | 1282 | {-# INLINE trivial_expr_fold #-}
|
| 1283 | -trivial_expr_fold :: (Id -> r) -> (Literal -> r) -> r -> r -> CoreExpr -> r
|
|
| 1283 | +trivial_expr_fold :: (Id -> r) -- Var
|
|
| 1284 | + -> (Literal -> r) -- Lit
|
|
| 1285 | + -> (Type -> r) -- Type
|
|
| 1286 | + -> (Coercion -> r) -- Coercion
|
|
| 1287 | + -> (r -> Coercion -> r) -- Cast
|
|
| 1288 | + -> r -- Anything else
|
|
| 1289 | + -> CoreExpr -> r
|
|
| 1284 | 1290 | -- ^ The worker function for Note [exprIsTrivial] and Note [getIdFromTrivialExpr]
|
| 1285 | 1291 | -- This is meant to have the code of both functions in one place and make it
|
| 1286 | 1292 | -- easy to derive custom predicates.
|
| 1287 | 1293 | --
|
| 1288 | --- (trivial_expr_fold k_id k_triv k_not_triv e)
|
|
| 1294 | +-- (trivial_expr_fold k_id k_ty k_co k_not_triv e)
|
|
| 1289 | 1295 | -- * returns (k_id x) if `e` is a variable `x` (with trivial wrapping)
|
| 1290 | 1296 | -- * returns (k_lit x) if `e` is a trivial literal `l` (with trivial wrapping)
|
| 1291 | --- * returns k_triv if `e` is a literal, type, or coercion (with trivial wrapping)
|
|
| 1297 | +-- * returns (k_ty ty) if `e` is a type (with trivial wrapping)
|
|
| 1298 | +-- * returns (k_co co) if `e` is a coercion (with trivial wrapping)
|
|
| 1292 | 1299 | -- * returns k_not_triv otherwise
|
| 1293 | 1300 | --
|
| 1294 | 1301 | -- where "trivial wrapping" is
|
| 1295 | 1302 | -- * Type application or abstraction
|
| 1296 | 1303 | -- * Ticks other than `tickishIsCode`
|
| 1297 | 1304 | -- * `case e of {}` an empty case
|
| 1298 | -trivial_expr_fold k_id k_lit k_triv k_not_triv = go
|
|
| 1305 | +trivial_expr_fold k_id k_lit k_ty k_co k_cast k_not_triv = go
|
|
| 1299 | 1306 | where
|
| 1300 | 1307 | -- If you change this function, be sure to change
|
| 1301 | 1308 | -- SetLevels.notWorthFloating as well!
|
| 1302 | 1309 | -- (Or yet better: Come up with a way to share code with this function.)
|
| 1303 | 1310 | go (Var v) = k_id v -- See Note [Variables are trivial]
|
| 1304 | 1311 | go (Lit l) | litIsTrivial l = k_lit l
|
| 1305 | - go (Type _) = k_triv
|
|
| 1306 | - go (Coercion _) = k_triv
|
|
| 1312 | + go (Type ty) = k_ty ty
|
|
| 1313 | + go (Coercion co) = k_co co
|
|
| 1314 | + go (Cast e co) = k_cast (go e) co
|
|
| 1307 | 1315 | go (App f arg)
|
| 1308 | 1316 | | not (isRuntimeArg arg) = go f
|
| 1309 | 1317 | | exprIsUnaryClassFun f = go arg
|
| 1310 | 1318 | | otherwise = k_not_triv
|
| 1311 | 1319 | go (Lam b e) | not (isRuntimeVar b) = go e
|
| 1312 | 1320 | go (Tick t e) | not (tickishIsCode t) = go e -- See Note [Tick trivial]
|
| 1313 | - go (Cast e _) = go e
|
|
| 1314 | 1321 | go (Case e b _ as)
|
| 1315 | 1322 | | null as
|
| 1316 | 1323 | = go e -- See Note [Empty case is trivial]
|
| ... | ... | @@ -1319,7 +1326,14 @@ trivial_expr_fold k_id k_lit k_triv k_not_triv = go |
| 1319 | 1326 | go _ = k_not_triv
|
| 1320 | 1327 | |
| 1321 | 1328 | exprIsTrivial :: CoreExpr -> Bool
|
| 1322 | -exprIsTrivial e = trivial_expr_fold (const True) (const True) True False e
|
|
| 1329 | +exprIsTrivial e = trivial_expr_fold
|
|
| 1330 | + (const True) -- Ids
|
|
| 1331 | + (const True) -- Literals
|
|
| 1332 | + (const True) -- Types
|
|
| 1333 | + coercionIsSmall -- Coercions
|
|
| 1334 | + (\ r co -> pprTrace "exprIsTrivial" (ppr (coercionIsSmall co) $$ ppr co) $
|
|
| 1335 | + r && coercionIsSmall co) -- Casts
|
|
| 1336 | + False e
|
|
| 1323 | 1337 | |
| 1324 | 1338 | {-
|
| 1325 | 1339 | Note [getIdFromTrivialExpr]
|
| ... | ... | @@ -1340,12 +1354,16 @@ T12076lit for an example where this matters. |
| 1340 | 1354 | |
| 1341 | 1355 | getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Id
|
| 1342 | 1356 | -- See Note [getIdFromTrivialExpr]
|
| 1343 | -getIdFromTrivialExpr e = trivial_expr_fold id (const panic) panic panic e
|
|
| 1357 | +getIdFromTrivialExpr e
|
|
| 1358 | + = trivial_expr_fold id panic panic panic panic panic e
|
|
| 1344 | 1359 | where
|
| 1360 | + panic :: forall a. a
|
|
| 1345 | 1361 | panic = pprPanic "getIdFromTrivialExpr" (ppr e)
|
| 1346 | 1362 | |
| 1347 | 1363 | getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id
|
| 1348 | -getIdFromTrivialExpr_maybe e = trivial_expr_fold Just (const Nothing) Nothing Nothing e
|
|
| 1364 | +getIdFromTrivialExpr_maybe e
|
|
| 1365 | + = trivial_expr_fold Just (const Nothing) (const Nothing)
|
|
| 1366 | + (const Nothing) (\ r _ -> r) Nothing e
|
|
| 1349 | 1367 | |
| 1350 | 1368 | {- *********************************************************************
|
| 1351 | 1369 | * *
|
| ... | ... | @@ -2371,6 +2389,13 @@ exprIsTopLevelBindable expr ty |
| 2371 | 2389 | -- as the latter would panic.
|
| 2372 | 2390 | || exprIsTickedString expr
|
| 2373 | 2391 | |
| 2392 | + || exprIsCoercion expr
|
|
| 2393 | + |
|
| 2394 | +-- | Check if the expression is a literal coercion; these can appear at top level
|
|
| 2395 | +exprIsCoercion :: CoreExpr -> Bool
|
|
| 2396 | +exprIsCoercion (Coercion {}) = True
|
|
| 2397 | +exprIsCoercion _ = False
|
|
| 2398 | + |
|
| 2374 | 2399 | -- | Check if the expression is zero or more Ticks wrapped around a literal
|
| 2375 | 2400 | -- string.
|
| 2376 | 2401 | exprIsTickedString :: CoreExpr -> Bool
|
| ... | ... | @@ -598,8 +598,10 @@ getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg |
| 598 | 598 | -- CoreArgs may not immediately look trivial, e.g., `case e of {}` or
|
| 599 | 599 | -- `case unsafeequalityProof of UnsafeRefl -> e` might intervene.
|
| 600 | 600 | -- Good thing we can just call `trivial_expr_fold` here.
|
| 601 | -getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg panic panic e
|
|
| 601 | +getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg
|
|
| 602 | + panic panic panic panic e
|
|
| 602 | 603 | where
|
| 604 | + panic :: forall a. a
|
|
| 603 | 605 | panic = pprPanic "getStgArgFromTrivialArg" (ppr e)
|
| 604 | 606 | |
| 605 | 607 | coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [StgTickish])
|