Simon Peyton Jones pushed to branch wip/spj-try-opt-coercion at Glasgow Haskell Compiler / GHC
Commits:
-
5c1b0929
by Simon Peyton Jones at 2026-01-06T13:43:50+00:00
9 changed files:
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/Lint.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/TyCo/FVs.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Types/Var/Env.hs
- hadrian/src/Flavour.hs
Changes:
| ... | ... | @@ -445,12 +445,7 @@ opt_co4' env sym rep r (CoVarCo cv) |
| 445 | 445 | where
|
| 446 | 446 | Pair ty1 ty2 = coVarTypes cv1
|
| 447 | 447 | |
| 448 | - cv1 = case lookupInScope (lcInScopeSet env) cv of
|
|
| 449 | - Just cv1 -> cv1
|
|
| 450 | - Nothing -> warnPprTrace True
|
|
| 451 | - "opt_co: not in scope"
|
|
| 452 | - (ppr cv $$ ppr env)
|
|
| 453 | - cv
|
|
| 448 | + cv1 = refineFromInScope (lcInScopeSet env) cv
|
|
| 454 | 449 | -- cv1 might have a substituted kind!
|
| 455 | 450 | |
| 456 | 451 | opt_co4' _ _ _ _ (HoleCo h)
|
| ... | ... | @@ -588,22 +588,8 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty |
| 588 | 588 | |
| 589 | 589 | -- Check the let-can-float invariant
|
| 590 | 590 | -- See Note [Core let-can-float invariant] in GHC.Core
|
| 591 | - ; checkL ( isTopLevel top_lvl
|
|
| 592 | - || isJoinId binder
|
|
| 593 | - || mightBeLiftedType binder_ty
|
|
| 594 | - || (isNonRec rec_flag && exprOkForSpeculation rhs)) $
|
|
| 595 | - badBndrTyMsg binder (text "unlifted")
|
|
| 596 | - |
|
| 597 | - -- Check that if the binder is at the top level the binding
|
|
| 598 | - -- satisfies exprIsTopLevelBindable
|
|
| 599 | - -- See Note [Core top-level string literals].
|
|
| 600 | - ; checkL ( not (isTopLevel top_lvl)
|
|
| 601 | - || exprIsTopLevelBindable rhs binder_ty
|
|
| 602 | - || isDataConWorkId binder || isDataConWrapId binder -- until #17521 is fixed
|
|
| 603 | - ) $
|
|
| 604 | - mkTopNonLitStrMsg binder
|
|
| 605 | - |
|
| 606 | - ; flags <- getLintFlags
|
|
| 591 | + ; checkL (bindingIsOk top_lvl rec_flag binder binder_ty rhs) $
|
|
| 592 | + mkLetErr binder rhs
|
|
| 607 | 593 | |
| 608 | 594 | -- Check that a join-point binder has a valid type
|
| 609 | 595 | -- NB: lintIdBinder has checked that it is not top-level bound
|
| ... | ... | @@ -612,6 +598,7 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty |
| 612 | 598 | JoinPoint arity -> checkL (isValidJoinPointType arity binder_ty)
|
| 613 | 599 | (mkInvalidJoinPointMsg binder binder_ty)
|
| 614 | 600 | |
| 601 | + ; flags <- getLintFlags
|
|
| 615 | 602 | ; when (lf_check_inline_loop_breakers flags
|
| 616 | 603 | && isStableUnfolding (realIdUnfolding binder)
|
| 617 | 604 | && isStrongLoopBreaker (idOccInfo binder)
|
| ... | ... | @@ -659,6 +646,28 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty |
| 659 | 646 | -- We should check the unfolding, if any, but this is tricky because
|
| 660 | 647 | -- the unfolding is a SimplifiableCoreExpr. Give up for now.
|
| 661 | 648 | |
| 649 | +bindingIsOk :: TopLevelFlag -> RecFlag -> OutId -> OutType -> CoreExpr -> Bool
|
|
| 650 | +bindingIsOk top_lvl rec_flag binder binder_ty rhs
|
|
| 651 | + | isCoVar binder
|
|
| 652 | + = isCoArg rhs
|
|
| 653 | + |
|
| 654 | + | isJoinId binder
|
|
| 655 | + = not (isTopLevel top_lvl)
|
|
| 656 | + |
|
| 657 | + -- Not a JoinId nor a CoVar
|
|
| 658 | + | isTopLevel top_lvl
|
|
| 659 | + = exprIsTopLevelBindable rhs binder_ty
|
|
| 660 | + || isDataConWorkId binder || isDataConWrapId binder -- until #17521 is fixed
|
|
| 661 | + |
|
| 662 | + -- So not top level, not JoinId, not CoVar
|
|
| 663 | + | isRec rec_flag
|
|
| 664 | + = exprIsTopLevelBindable rhs binder_ty
|
|
| 665 | + |
|
| 666 | + -- Not top level, not recursive
|
|
| 667 | + | otherwise
|
|
| 668 | + = mightBeLiftedType binder_ty
|
|
| 669 | + || exprOkForSpeculation rhs
|
|
| 670 | + |
|
| 662 | 671 | -- | Checks the RHS of bindings. It only differs from 'lintCoreExpr'
|
| 663 | 672 | -- in that it doesn't reject occurrences of the function 'makeStatic' when they
|
| 664 | 673 | -- appear at the top level and @lf_check_static_ptrs == AllowAtTopLevel@, and
|
| ... | ... | @@ -3829,11 +3838,6 @@ mkRhsMsg binder what ty |
| 3829 | 3838 | hsep [text "Binder's type:", ppr (idType binder)],
|
| 3830 | 3839 | hsep [text "Rhs type:", ppr ty]]
|
| 3831 | 3840 | |
| 3832 | -badBndrTyMsg :: Id -> SDoc -> SDoc
|
|
| 3833 | -badBndrTyMsg binder what
|
|
| 3834 | - = vcat [ text "The type of this binder is" <+> what <> colon <+> ppr binder
|
|
| 3835 | - , text "Binder's type:" <+> ppr (idType binder) ]
|
|
| 3836 | - |
|
| 3837 | 3841 | mkNonTopExportedMsg :: Id -> SDoc
|
| 3838 | 3842 | mkNonTopExportedMsg binder
|
| 3839 | 3843 | = hsep [text "Non-top-level binder is marked as exported:", ppr binder]
|
| ... | ... | @@ -3842,10 +3846,6 @@ mkNonTopExternalNameMsg :: Id -> SDoc |
| 3842 | 3846 | mkNonTopExternalNameMsg binder
|
| 3843 | 3847 | = hsep [text "Non-top-level binder has an external name:", ppr binder]
|
| 3844 | 3848 | |
| 3845 | -mkTopNonLitStrMsg :: Id -> SDoc
|
|
| 3846 | -mkTopNonLitStrMsg binder
|
|
| 3847 | - = hsep [text "Top-level Addr# binder has a non-literal rhs:", ppr binder]
|
|
| 3848 | - |
|
| 3849 | 3849 | mkKindErrMsg :: TyVar -> Type -> SDoc
|
| 3850 | 3850 | mkKindErrMsg tyvar arg_ty
|
| 3851 | 3851 | = vcat [text "Kinds don't match in type application:",
|
| ... | ... | @@ -624,7 +624,7 @@ reSimplifying :: SimplEnv -> Bool |
| 624 | 624 | reSimplifying (SimplEnv { seInlineDepth = n }) = n>0
|
| 625 | 625 | |
| 626 | 626 | ---------------------
|
| 627 | -extendIdSubst :: SimplEnv -> Id -> SimplSR -> SimplEnv
|
|
| 627 | +extendIdSubst :: HasDebugCallStack => SimplEnv -> Id -> SimplSR -> SimplEnv
|
|
| 628 | 628 | extendIdSubst env@(SimplEnv {seIdSubst = subst}) var res
|
| 629 | 629 | = assertPpr (isId var && not (isCoVar var)) (ppr var) $
|
| 630 | 630 | env { seIdSubst = extendVarEnv subst var res }
|
| ... | ... | @@ -934,8 +934,6 @@ addJoinFlts = appOL |
| 934 | 934 | mkRecFloats :: SimplFloats -> SimplFloats
|
| 935 | 935 | -- Flattens the floats into a single Rec group,
|
| 936 | 936 | -- They must either all be lifted LetFloats or all JoinFloats
|
| 937 | ---
|
|
| 938 | --- ToDo: explain about CoVar floats
|
|
| 939 | 937 | mkRecFloats floats@(SimplFloats { sfLetFloats = LetFloats bs _ff
|
| 940 | 938 | , sfJoinFloats = jbs
|
| 941 | 939 | , sfInScope = in_scope })
|
| ... | ... | @@ -953,17 +951,7 @@ mkRecFloats floats@(SimplFloats { sfLetFloats = LetFloats bs _ff |
| 953 | 951 | flatten_rec :: OrdList OutBind -> OrdList OutBind
|
| 954 | 952 | -- Put CoVar bindings first (guaranteed non-recursive)
|
| 955 | 953 | -- then one recursive value binding
|
| 956 | - flatten_rec bs = let !(covar_bs, prs) = foldrOL do_one (nilOL, []) bs
|
|
| 957 | - in covar_bs `snocOL` Rec prs
|
|
| 958 | - |
|
| 959 | - do_one :: OutBind -> (OrdList OutBind,[(OutId,OutExpr)])
|
|
| 960 | - -> (OrdList OutBind,[(OutId,OutExpr)])
|
|
| 961 | - do_one bind (cvbs, prs)
|
|
| 962 | - = case bind of
|
|
| 963 | - NonRec bndr rhs
|
|
| 964 | - | isCoVar bndr -> (bind `consOL` cvbs, prs)
|
|
| 965 | - | otherwise -> (cvbs, (bndr,rhs):prs)
|
|
| 966 | - Rec prs1 -> (cvbs, prs1 ++ prs)
|
|
| 954 | + flatten_rec bs = unitOL (Rec (flattenBinds (fromOL bs)))
|
|
| 967 | 955 | |
| 968 | 956 | wrapFloats :: SimplFloats -> OutExpr -> OutExpr
|
| 969 | 957 | -- Wrap the floats around the expression
|
| ... | ... | @@ -1037,14 +1025,6 @@ substId (SimplEnv { seInScope = in_scope, seIdSubst = ids }) v |
| 1037 | 1025 | --
|
| 1038 | 1026 | -- See also Note [In-scope set as a substitution] in GHC.Core.Opt.Simplify.
|
| 1039 | 1027 | |
| 1040 | -refineFromInScope :: InScopeSet -> Var -> Var
|
|
| 1041 | -refineFromInScope in_scope v
|
|
| 1042 | - | isLocalId v = case lookupInScope in_scope v of
|
|
| 1043 | - Just v' -> v'
|
|
| 1044 | - Nothing -> pprPanic "refineFromInScope" (ppr in_scope $$ ppr v)
|
|
| 1045 | - -- c.f #19074 for a subtle place where this went wrong
|
|
| 1046 | - | otherwise = v
|
|
| 1047 | - |
|
| 1048 | 1028 | lookupRecBndr :: SimplEnv -> InId -> OutId
|
| 1049 | 1029 | -- Look up an Id which has been put into the envt by simplRecBndrs,
|
| 1050 | 1030 | -- but where we have not yet done its RHS
|
| ... | ... | @@ -1388,7 +1368,7 @@ substCoVarBndr env cv |
| 1388 | 1368 | (Subst in_scope' _ tv_env' cv_env', cv')
|
| 1389 | 1369 | -> (env { seInScope = in_scope', seTvSubst = tv_env', seCvSubst = cv_env' }, cv')
|
| 1390 | 1370 | |
| 1391 | -substCo :: SimplEnv -> Coercion -> Coercion
|
|
| 1371 | +substCo :: HasDebugCallStack => SimplEnv -> Coercion -> Coercion
|
|
| 1392 | 1372 | substCo env co = Coercion.substCo (getTCvSubst env) co
|
| 1393 | 1373 | |
| 1394 | 1374 | ------------------
|
| ... | ... | @@ -258,11 +258,11 @@ simplRecBind env0 bind_cxt pairs0 |
| 258 | 258 | = do { (env', bndr') <- addBndrRules env bndr (lookupRecBndr env bndr) bind_cxt
|
| 259 | 259 | ; return (env', (bndr, bndr', rhs)) }
|
| 260 | 260 | |
| 261 | + go :: SimplEnv -> [(InId, OutId, InExpr)] -> SimplM (SimplFloats, SimplEnv)
|
|
| 261 | 262 | go env [] = return (emptyFloats env, env)
|
| 262 | 263 | |
| 263 | 264 | go env ((old_bndr, new_bndr, rhs) : pairs)
|
| 264 | - = do { (float, env1) <- simplRecOrTopPair env bind_cxt
|
|
| 265 | - old_bndr new_bndr rhs
|
|
| 265 | + = do { (float, env1) <- simplRecOrTopPair env bind_cxt old_bndr new_bndr rhs
|
|
| 266 | 266 | ; (floats, env2) <- go env1 pairs
|
| 267 | 267 | ; return (float `addFloats` floats, env2) }
|
| 268 | 268 | |
| ... | ... | @@ -842,6 +842,10 @@ makeTrivial env top_lvl dmd occ_fs expr |
| 842 | 842 | ; simplTrace "makeTrivial:co" (ppr (Cast triv_expr triv_co)) $
|
| 843 | 843 | return (floats1 `addLetFlts` floats2, Cast triv_expr triv_co) }
|
| 844 | 844 | |
| 845 | + | Coercion co <- expr
|
|
| 846 | + = do { (floats, triv_co) <- makeCoTrivial co
|
|
| 847 | + ; return (floats, Coercion triv_co) }
|
|
| 848 | + |
|
| 845 | 849 | | otherwise -- 'expr' is not of form (Cast e co)
|
| 846 | 850 | = do { (floats, expr1) <- prepareRhs env top_lvl occ_fs expr
|
| 847 | 851 | ; uniq <- getUniqueM
|
| ... | ... | @@ -950,12 +954,16 @@ completeBind :: BindContext |
| 950 | 954 | -- Binder /can/ be a JoinId
|
| 951 | 955 | -- Precondition: rhs obeys the let-can-float invariant
|
| 952 | 956 | completeBind bind_cxt (old_bndr, unf_se) (new_bndr, new_rhs, env)
|
| 953 | - | isCoVar old_bndr
|
|
| 954 | - = case new_rhs of
|
|
| 955 | - Coercion co -> return (emptyFloats env, extendCvSubst env old_bndr co)
|
|
| 956 | - _ -> return (mkFloatBind env (NonRec new_bndr new_rhs))
|
|
| 957 | - |
|
| 958 | - | otherwise
|
|
| 957 | + | isCoVar old_bndr
|
|
| 958 | + = case new_rhs of
|
|
| 959 | + Coercion co -- Inline if it is trivial
|
|
| 960 | + | postInlineUnconditionally env bind_cxt old_bndr new_bndr new_rhs
|
|
| 961 | + -> return (emptyFloats env, extendCvSubst env old_bndr co)
|
|
| 962 | + _otherwise -> -- Can't inline anything other than a Coercion inside a coercion
|
|
| 963 | + -- So retain the binding insteadd
|
|
| 964 | + return (mkFloatBind env (NonRec new_bndr new_rhs))
|
|
| 965 | + |
|
| 966 | + | otherwise -- Non-CoVars
|
|
| 959 | 967 | = assert (isId new_bndr) $
|
| 960 | 968 | do { let old_info = idInfo old_bndr
|
| 961 | 969 | old_unf = realUnfoldingInfo old_info
|
| ... | ... | @@ -982,8 +990,8 @@ completeBind bind_cxt (old_bndr, unf_se) (new_bndr, new_rhs, env) |
| 982 | 990 | return ( emptyFloats env
|
| 983 | 991 | , extendIdSubst env old_bndr $
|
| 984 | 992 | DoneEx unf_rhs (idJoinPointHood new_bndr)) }
|
| 985 | - -- Use the substitution to make quite, quite sure that the
|
|
| 986 | - -- substitution will happen, since we are going to discard the binding
|
|
| 993 | + -- Use the substitution to make quite, quite sure that the
|
|
| 994 | + -- substitution will happen, since we are going to discard the binding
|
|
| 987 | 995 | |
| 988 | 996 | else -- Keep the binding; do cast worker/wrapper
|
| 989 | 997 | -- simplTrace "completeBind" (vcat [ text "bndrs" <+> ppr old_bndr <+> ppr new_bndr
|
| ... | ... | @@ -59,7 +59,7 @@ import GHC.Core.Opt.Arity |
| 59 | 59 | import GHC.Core.Unfold
|
| 60 | 60 | import GHC.Core.Unfold.Make
|
| 61 | 61 | import GHC.Core.Opt.Simplify.Monad
|
| 62 | -import GHC.Core.Type hiding( substTy )
|
|
| 62 | +import GHC.Core.Type hiding( substTy, extendCvSubst )
|
|
| 63 | 63 | import GHC.Core.Coercion hiding( substCo )
|
| 64 | 64 | import GHC.Core.DataCon ( dataConWorkId, isNullaryRepDataCon )
|
| 65 | 65 | import GHC.Core.Multiplicity
|
| ... | ... | @@ -1499,7 +1499,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env |
| 1499 | 1499 | | not pre_inline_unconditionally = Nothing
|
| 1500 | 1500 | | not active = Nothing
|
| 1501 | 1501 | | isTopLevel top_lvl && isDeadEndId bndr = Nothing -- Note [Top-level bottoming Ids]
|
| 1502 | - | isCoVar bndr = Nothing -- Note [Do not inline CoVars unconditionally]
|
|
| 1502 | + | isCoVar bndr, not (isCoArg rhs) = Nothing -- Note [Do not inline CoVars unconditionally]
|
|
| 1503 | 1503 | | isExitJoinId bndr = Nothing -- Note [Do not inline exit join points]
|
| 1504 | 1504 | -- in module Exitify
|
| 1505 | 1505 | | not (one_occ (idOccInfo bndr)) = Nothing
|
| ... | ... | @@ -1511,7 +1511,9 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env |
| 1511 | 1511 | | otherwise = Nothing
|
| 1512 | 1512 | where
|
| 1513 | 1513 | unf = idUnfolding bndr
|
| 1514 | - extend_subst_with inl_rhs = extendIdSubst env bndr $! (mkContEx rhs_env inl_rhs)
|
|
| 1514 | + extend_subst_with inl_rhs
|
|
| 1515 | + | Coercion co <- inl_rhs = extendCvSubst env bndr co
|
|
| 1516 | + | otherwise = extendIdSubst env bndr $! (mkContEx rhs_env inl_rhs)
|
|
| 1515 | 1517 | |
| 1516 | 1518 | one_occ IAmDead = True -- Happens in ((\x.1) v)
|
| 1517 | 1519 | one_occ OneOcc{ occ_n_br = 1
|
| ... | ... | @@ -1548,15 +1550,16 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env |
| 1548 | 1550 | -- canInlineInLam => free vars of rhs are (Once in_lam) or Many,
|
| 1549 | 1551 | -- so substituting rhs inside a lambda doesn't change the occ info.
|
| 1550 | 1552 | -- Sadly, not quite the same as exprIsHNF.
|
| 1551 | - canInlineInLam (Lit _) = True
|
|
| 1552 | - canInlineInLam (Cast e _) = canInlineInLam e
|
|
| 1553 | - canInlineInLam (Lam b e) = isRuntimeVar b || canInlineInLam e
|
|
| 1554 | - canInlineInLam (Tick t e) = not (tickishIsCode t) && canInlineInLam e
|
|
| 1555 | - canInlineInLam (Var v) = case idOccInfo v of
|
|
| 1556 | - OneOcc { occ_in_lam = IsInsideLam } -> True
|
|
| 1557 | - ManyOccs {} -> True
|
|
| 1558 | - _ -> False
|
|
| 1559 | - canInlineInLam _ = False
|
|
| 1553 | + canInlineInLam (Lit _) = True
|
|
| 1554 | + canInlineInLam (Coercion _) = True
|
|
| 1555 | + canInlineInLam (Cast e _) = canInlineInLam e
|
|
| 1556 | + canInlineInLam (Lam b e) = isRuntimeVar b || canInlineInLam e
|
|
| 1557 | + canInlineInLam (Tick t e) = not (tickishIsCode t) && canInlineInLam e
|
|
| 1558 | + canInlineInLam (Var v) = case idOccInfo v of
|
|
| 1559 | + OneOcc { occ_in_lam = IsInsideLam } -> True
|
|
| 1560 | + ManyOccs {} -> True
|
|
| 1561 | + _ -> False
|
|
| 1562 | + canInlineInLam _ = False
|
|
| 1560 | 1563 | -- not ticks. Counting ticks cannot be duplicated, and non-counting
|
| 1561 | 1564 | -- ticks around a Lam will disappear anyway.
|
| 1562 | 1565 | |
| ... | ... | @@ -1646,7 +1649,6 @@ postInlineUnconditionally env bind_cxt old_bndr bndr rhs |
| 1646 | 1649 | | isStableUnfolding unfolding = False -- Note [Stable unfoldings and postInlineUnconditionally]
|
| 1647 | 1650 | | isTopLevel (bindContextLevel bind_cxt)
|
| 1648 | 1651 | = False -- Note [Top level and postInlineUnconditionally]
|
| 1649 | - | isCoVar bndr = False
|
|
| 1650 | 1652 | | exprIsTrivial rhs = True
|
| 1651 | 1653 | | BC_Join {} <- bind_cxt = False -- See point (1) of Note [Duplicating join points]
|
| 1652 | 1654 | -- in GHC.Core.Opt.Simplify.Iteration
|
| ... | ... | @@ -350,7 +350,8 @@ deepTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synon |
| 350 | 350 | where
|
| 351 | 351 | do_tcv is v = EndoOS do_it
|
| 352 | 352 | where
|
| 353 | - do_it acc | v `elemVarSet` is = acc
|
|
| 353 | + do_it acc | not (isLocalVar v) = acc
|
|
| 354 | + | v `elemVarSet` is = acc
|
|
| 354 | 355 | | v `elemVarSet` acc = acc
|
| 355 | 356 | | otherwise = appEndoOS (deep_ty (varType v)) $
|
| 356 | 357 | acc `extendVarSet` v
|
| ... | ... | @@ -412,7 +413,8 @@ shallowTcvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and sy |
| 412 | 413 | where
|
| 413 | 414 | do_tcv is v = EndoOS do_it
|
| 414 | 415 | where
|
| 415 | - do_it acc | v `elemVarSet` is = acc
|
|
| 416 | + do_it acc | not (isLocalVar v) = acc
|
|
| 417 | + | v `elemVarSet` is = acc
|
|
| 416 | 418 | | v `elemVarSet` acc = acc
|
| 417 | 419 | | otherwise = acc `extendVarSet` v
|
| 418 | 420 | |
| ... | ... | @@ -475,7 +477,8 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView |
| 475 | 477 | |
| 476 | 478 | do_covar is v = EndoOS do_it
|
| 477 | 479 | where
|
| 478 | - do_it acc | v `elemVarSet` is = acc
|
|
| 480 | + do_it acc | not (isLocalVar v) = acc
|
|
| 481 | + | v `elemVarSet` is = acc
|
|
| 479 | 482 | | v `elemVarSet` acc = acc
|
| 480 | 483 | | otherwise = appEndoOS (deep_cv_ty (varType v)) $
|
| 481 | 484 | acc `extendVarSet` v
|
| ... | ... | @@ -706,7 +709,10 @@ tyCoFVsOfCo (SubCo co) fv_cand in_scope acc = tyCoFVsOfCo co fv_cand in |
| 706 | 709 | |
| 707 | 710 | tyCoFVsOfCoVar :: CoVar -> FV
|
| 708 | 711 | tyCoFVsOfCoVar v fv_cand in_scope acc
|
| 712 | + | isLocalId v
|
|
| 709 | 713 | = (unitFV v `unionFV` tyCoFVsOfType (varType v)) fv_cand in_scope acc
|
| 714 | + | otherwise
|
|
| 715 | + = emptyFV fv_cand in_scope acc
|
|
| 710 | 716 | |
| 711 | 717 | tyCoFVsOfCos :: [Coercion] -> FV
|
| 712 | 718 | tyCoFVsOfCos [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc
|
| ... | ... | @@ -2548,8 +2548,10 @@ extendCorePrepEnvList cpe@(CPE { cpe_subst = subst }) prs |
| 2548 | 2548 | subst2 = extendIdSubstList subst1 [(id, Var id') | (id,id') <- prs]
|
| 2549 | 2549 | |
| 2550 | 2550 | extendCorePrepEnvExpr :: CorePrepEnv -> Id -> CoreExpr -> CorePrepEnv
|
| 2551 | +-- The Id can be a CoVar
|
|
| 2551 | 2552 | extendCorePrepEnvExpr cpe id expr
|
| 2552 | - = cpe { cpe_subst = extendIdSubst (cpe_subst cpe) id expr }
|
|
| 2553 | + = cpe { cpe_subst = extendSubst (cpe_subst cpe) id expr }
|
|
| 2554 | + -- NB: extendSubst not extendIdSubst; the id can be a CoVar
|
|
| 2553 | 2555 | |
| 2554 | 2556 | lookupCorePrepEnv :: CorePrepEnv -> Id -> CoreExpr
|
| 2555 | 2557 | lookupCorePrepEnv cpe id
|
| ... | ... | @@ -55,9 +55,9 @@ module GHC.Types.Var.Env ( |
| 55 | 55 | -- ** Operations on InScopeSets
|
| 56 | 56 | emptyInScopeSet, mkInScopeSet, mkInScopeSetList, delInScopeSet,
|
| 57 | 57 | extendInScopeSet, extendInScopeSetList, extendInScopeSetSet,
|
| 58 | - getInScopeVars, lookupInScope, lookupInScope_Directly,
|
|
| 58 | + lookupInScope, lookupInScope_Directly, refineFromInScope,
|
|
| 59 | 59 | unionInScope, elemInScopeSet, uniqAway,
|
| 60 | - varSetInScope,
|
|
| 60 | + varSetInScope, getInScopeVars,
|
|
| 61 | 61 | unsafeGetFreshLocalUnique,
|
| 62 | 62 | |
| 63 | 63 | -- * The RnEnv2 type
|
| ... | ... | @@ -191,6 +191,14 @@ unionInScope (InScope s1) (InScope s2) |
| 191 | 191 | varSetInScope :: VarSet -> InScopeSet -> Bool
|
| 192 | 192 | varSetInScope vars (InScope s1) = vars `subVarSet` s1
|
| 193 | 193 | |
| 194 | +refineFromInScope :: HasDebugCallStack => InScopeSet -> Var -> Var
|
|
| 195 | +refineFromInScope in_scope v
|
|
| 196 | + | isLocalVar v = case lookupInScope in_scope v of
|
|
| 197 | + Just v' -> v'
|
|
| 198 | + Nothing -> pprPanic "refineFromInScope" (ppr in_scope $$ ppr v)
|
|
| 199 | + -- c.f #19074 for a subtle place where this went wrong
|
|
| 200 | + | otherwise = v
|
|
| 201 | + |
|
| 194 | 202 | {-
|
| 195 | 203 | Note [Local uniques]
|
| 196 | 204 | ~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -70,7 +70,8 @@ flavourTransformers = M.fromList |
| 70 | 70 | , "fully_static" =: fullyStatic
|
| 71 | 71 | , "host_fully_static" =: hostFullyStatic
|
| 72 | 72 | , "collect_timings" =: collectTimings
|
| 73 | - , "assertions" =: enableAssertions
|
|
| 73 | + , "assertions" =: enableAssertions Stage2
|
|
| 74 | + , "assertions_stage1" =: enableAssertions Stage1
|
|
| 74 | 75 | , "debug_ghc" =: debugGhc Stage2
|
| 75 | 76 | , "debug_stage1_ghc" =: debugGhc Stage1
|
| 76 | 77 | , "lint" =: enableLinting
|
| ... | ... | @@ -394,11 +395,11 @@ enableLateCCS = addArgs |
| 394 | 395 | ? arg "-fprof-late"
|
| 395 | 396 | |
| 396 | 397 | -- | Enable assertions for the stage2 compiler
|
| 397 | -enableAssertions :: Flavour -> Flavour
|
|
| 398 | -enableAssertions flav = flav { ghcDebugAssertions = f }
|
|
| 398 | +enableAssertions :: Stage -> Flavour -> Flavour
|
|
| 399 | +enableAssertions stage flav = flav { ghcDebugAssertions = f }
|
|
| 399 | 400 | where
|
| 400 | - f Stage2 = True
|
|
| 401 | - f st = ghcDebugAssertions flav st
|
|
| 401 | + f s | s == stage = True
|
|
| 402 | + | otherwise = ghcDebugAssertions flav s
|
|
| 402 | 403 | |
| 403 | 404 | -- | Build the stage3 compiler using the non-moving GC.
|
| 404 | 405 | enableBootNonmovingGc :: Flavour -> Flavour
|