recursion-ninja pushed to branch wip/fix-26670 at Glasgow Haskell Compiler / GHC
Commits:
-
f7d47d20
by Recursion Ninja at 2025-12-18T18:52:11-05:00
17 changed files:
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Types/Arity.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Outputable.hs
Changes:
| ... | ... | @@ -655,27 +655,39 @@ tryCastWorkerWrapper env _ _ bndr rhs -- All other bindings |
| 655 | 655 | , text "rhs:" <+> ppr rhs ])
|
| 656 | 656 | ; return (mkFloatBind env (NonRec bndr rhs)) }
|
| 657 | 657 | |
| 658 | -mkCastWrapperInlinePrag :: forall p. IsPass p => InlinePragma (GhcPass p) -> InlinePragma (GhcPass p)
|
|
| 658 | +mkCastWrapperInlinePrag :: InlinePragma GhcRn -> InlinePragma GhcRn
|
|
| 659 | 659 | -- See Note [Cast worker/wrapper]
|
| 660 | -mkCastWrapperInlinePrag (InlinePragma { inl_ext = inTag, inl_inline = fn_inl, inl_act = fn_act, inl_rule = rule_info })
|
|
| 661 | - = InlinePragma { inl_ext = outTag
|
|
| 662 | - , inl_inline = fn_inl -- See Note [Worker/wrapper for INLINABLE functions]
|
|
| 663 | - , inl_act = wrap_act -- See Note [Wrapper activation]
|
|
| 664 | - , inl_rule = rule_info } -- in GHC.Core.Opt.WorkWrap
|
|
| 665 | - -- RuleMatchInfo is (and must be) unaffected
|
|
| 660 | +mkCastWrapperInlinePrag prag =
|
|
| 661 | + -- Consider each field of the 'InlinePragma' constructor
|
|
| 662 | + -- and deterimine what is the appropriate definition for the
|
|
| 663 | + -- corresponding value used within a worker/wrapper.
|
|
| 664 | + --
|
|
| 665 | + -- 1. 'inl_ext': Overwrite
|
|
| 666 | + setInlinePragmaArityAsNotExplicit prag
|
|
| 667 | + `setInlinePragmaSource` src_txt
|
|
| 668 | + --
|
|
| 669 | + -- 2. 'inl_inline': *Preserve*
|
|
| 670 | + -- See Note [Worker/wrapper for INLINABLE functions]
|
|
| 671 | + -- in GHC.Core.Opt.WorkWrap
|
|
| 672 | + -- <SKIP>
|
|
| 673 | + --
|
|
| 674 | + -- 3. 'inl_act': Conditionally Update
|
|
| 675 | + -- See Note [Wrapper activation]
|
|
| 676 | + -- in GHC.Core.Opt.WorkWrap
|
|
| 677 | + `setInlinePragmaActivation` wrap_act
|
|
| 678 | + --
|
|
| 679 | + -- 4. 'inl_rule': *Preserve*
|
|
| 680 | + -- RuleMatchInfo is (and must be) unaffected
|
|
| 681 | + -- <SKIP>
|
|
| 682 | + --
|
|
| 683 | + -- <DONE>
|
|
| 666 | 684 | where
|
| 667 | 685 | -- See Note [Wrapper activation] in GHC.Core.Opt.WorkWrap
|
| 668 | 686 | -- But simpler, because we don't need to disable during InitialPhase
|
| 669 | 687 | wrap_act | isNeverActive fn_act = activateDuringFinal
|
| 670 | 688 | | otherwise = fn_act
|
| 671 | - |
|
| 672 | - srcTxt = SourceText $ fsLit "{-# INLINE"
|
|
| 673 | - |
|
| 674 | - outTag = case ghcPass @p of
|
|
| 675 | - GhcPs -> inTag
|
|
| 676 | - GhcRn -> inTag { inl_ghcrn_src = srcTxt }
|
|
| 677 | - GhcTc -> inTag { inl_ghcrn_src = srcTxt }
|
|
| 678 | - |
|
| 689 | + fn_act = inlinePragmaActivation prag
|
|
| 690 | + src_txt = SourceText $ fsLit "{-# INLINE"
|
|
| 679 | 691 | |
| 680 | 692 | {- *********************************************************************
|
| 681 | 693 | * *
|
| ... | ... | @@ -44,7 +44,7 @@ import GHC.Data.Bag |
| 44 | 44 | import GHC.Data.OrdList
|
| 45 | 45 | import GHC.Data.List.SetOps
|
| 46 | 46 | |
| 47 | -import GHC.Hs.Extension ( GhcTc )
|
|
| 47 | +import GHC.Hs.Extension ( GhcRn )
|
|
| 48 | 48 | |
| 49 | 49 | import GHC.Types.Basic
|
| 50 | 50 | import GHC.Types.Unique.Supply
|
| ... | ... | @@ -1639,6 +1639,16 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
| 1639 | 1639 | (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs
|
| 1640 | 1640 | -- See Note [Account for casts in binding]
|
| 1641 | 1641 | |
| 1642 | + -- Copy InlinePragma information from the parent Id.
|
|
| 1643 | + -- So if f has INLINE[1] so does spec_fn
|
|
| 1644 | + spec_inl_prag :: InlinePragma GhcRn
|
|
| 1645 | + spec_inl_prag
|
|
| 1646 | + | not is_local -- See Note [Specialising imported functions]
|
|
| 1647 | + , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal
|
|
| 1648 | + = neverInlinePragma
|
|
| 1649 | + | otherwise
|
|
| 1650 | + = inl_prag
|
|
| 1651 | + |
|
| 1642 | 1652 | not_in_scope :: InterestingVarFun
|
| 1643 | 1653 | not_in_scope v = isLocalVar v && not (v `elemInScopeSet` in_scope)
|
| 1644 | 1654 | |
| ... | ... | @@ -1754,20 +1764,9 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
| 1754 | 1764 | -- See Note [Arity decrease] in GHC.Core.Opt.Simplify
|
| 1755 | 1765 | join_arity_decr = length rule_lhs_args - length rule_rhs_args1
|
| 1756 | 1766 | arity_decr = count isValArg rule_lhs_args - count isId rule_rhs_args1
|
| 1757 | - arity = max 0 (fn_arity - arity_decr)
|
|
| 1758 | - |
|
| 1759 | - -- Copy InlinePragma information from the parent Id.
|
|
| 1760 | - -- So if f has INLINE[1] so does spec_fn
|
|
| 1761 | - spec_inl_prag :: InlinePragma GhcTc
|
|
| 1762 | - spec_inl_prag
|
|
| 1763 | - | not is_local -- See Note [Specialising imported functions]
|
|
| 1764 | - , isStrongLoopBreaker (idOccInfo fn) -- in GHC.Core.Opt.OccurAnal
|
|
| 1765 | - = neverInlinePragma `setInlinePragmaArity` arity
|
|
| 1766 | - | otherwise
|
|
| 1767 | - = inl_prag `setInlinePragmaArity` arity
|
|
| 1768 | 1767 | |
| 1769 | 1768 | spec_fn_info
|
| 1770 | - = vanillaIdInfo `setArityInfo` arity
|
|
| 1769 | + = vanillaIdInfo `setArityInfo` max 0 (fn_arity - arity_decr)
|
|
| 1771 | 1770 | `setInlinePragInfo` spec_inl_prag
|
| 1772 | 1771 | `setUnfoldingInfo` spec_unf
|
| 1773 | 1772 |
| ... | ... | @@ -22,7 +22,7 @@ import GHC.Core.SimpleOpt |
| 22 | 22 | |
| 23 | 23 | import GHC.Data.FastString
|
| 24 | 24 | |
| 25 | -import GHC.Hs.Extension (GhcPass, GhcTc)
|
|
| 25 | +import GHC.Hs.Extension (GhcPass, GhcRn)
|
|
| 26 | 26 | |
| 27 | 27 | import GHC.Types.Var
|
| 28 | 28 | import GHC.Types.Id
|
| ... | ... | @@ -834,7 +834,7 @@ mkWWBindPair ww_opts fn_id fn_info fn_args fn_body work_uniq div |
| 834 | 834 | _ -> inl_act wrap_prag
|
| 835 | 835 | |
| 836 | 836 | srcTxt = SourceText $ fsLit "{-# INLINE"
|
| 837 | - work_prag = InlinePragma { inl_ext = InlinePragmaGhcTag srcTxt arity
|
|
| 837 | + work_prag = InlinePragma { inl_ext = XInlinePragmaGhc srcTxt ArityNotExplicit
|
|
| 838 | 838 | , inl_inline = fn_inline_spec
|
| 839 | 839 | , inl_act = work_act
|
| 840 | 840 | , inl_rule = FunLike }
|
| ... | ... | @@ -883,7 +883,7 @@ mkWWBindPair ww_opts fn_id fn_info fn_args fn_body work_uniq div |
| 883 | 883 | | otherwise = topDmd
|
| 884 | 884 | |
| 885 | 885 | wrap_rhs = wrap_fn work_id
|
| 886 | - wrap_prag = mkStrWrapperInlinePrag fn_inl_prag fn_rules arity
|
|
| 886 | + wrap_prag = mkStrWrapperInlinePrag fn_inl_prag fn_rules
|
|
| 887 | 887 | wrap_unf = mkWrapperUnfolding simpl_opts wrap_rhs arity
|
| 888 | 888 | |
| 889 | 889 | wrap_id = fn_id `setIdUnfolding` wrap_unf
|
| ... | ... | @@ -897,11 +897,11 @@ mkWWBindPair ww_opts fn_id fn_info fn_args fn_body work_uniq div |
| 897 | 897 | fn_unfolding = realUnfoldingInfo fn_info
|
| 898 | 898 | fn_rules = ruleInfoRules (ruleInfo fn_info)
|
| 899 | 899 | |
| 900 | -mkStrWrapperInlinePrag :: InlinePragma (GhcPass p) -> [CoreRule] -> Arity -> InlinePragma GhcTc
|
|
| 900 | +mkStrWrapperInlinePrag :: InlinePragma (GhcPass p) -> [CoreRule] -> InlinePragma GhcRn
|
|
| 901 | 901 | mkStrWrapperInlinePrag (InlinePragma { inl_inline = fn_inl
|
| 902 | 902 | , inl_act = fn_act
|
| 903 | - , inl_rule = rule_info }) rules arity
|
|
| 904 | - = InlinePragma { inl_ext = InlinePragmaGhcTag srcTxt arity
|
|
| 903 | + , inl_rule = rule_info }) rules
|
|
| 904 | + = InlinePragma { inl_ext = XInlinePragmaGhc srcTxt ArityNotExplicit
|
|
| 905 | 905 | |
| 906 | 906 | , inl_inline = fn_inl
|
| 907 | 907 | -- See Note [Worker/wrapper for INLINABLE functions]
|
| ... | ... | @@ -503,8 +503,7 @@ toIfaceIdInfo id_info |
| 503 | 503 | ------------ Inline prag --------------
|
| 504 | 504 | inline_prag = inlinePragInfo id_info
|
| 505 | 505 | inline_hsinfo | isDefaultInlinePragma inline_prag = Nothing
|
| 506 | - | otherwise = Just . HsInline $
|
|
| 507 | - inline_prag `setInlinePragmaArity` arity_info
|
|
| 506 | + | otherwise = Just (HsInline inline_prag)
|
|
| 508 | 507 | |
| 509 | 508 | --------------------------
|
| 510 | 509 | toIfUnfolding :: Bool -> Unfolding -> Maybe IfaceInfoItem
|
| ... | ... | @@ -324,8 +324,7 @@ dsAbsBinds dflags tyvars dicts exports |
| 324 | 324 | -- No SpecPrags (no dicts)
|
| 325 | 325 | -- Can't be a default method (default methods are singletons)
|
| 326 | 326 | = do { dsHsWrapper wrap $ \core_wrap -> do
|
| 327 | - { return ( gbl_id `setInlinePragma`
|
|
| 328 | - (defaultInlinePragma `setInlinePragmaArity` 0)
|
|
| 327 | + { return ( gbl_id `setInlinePragma` defaultInlinePragma
|
|
| 329 | 328 | , core_wrap (Var lcl_id)) } }
|
| 330 | 329 | ; main_prs <- mapM mk_main exports
|
| 331 | 330 | ; let bind_prs' = map mk_aux_bind bind_prs
|
| ... | ... | @@ -370,8 +369,7 @@ dsAbsBinds dflags tyvars dicts exports |
| 370 | 369 | mkVarApps (Var poly_tup_id) (tyvars ++ dicts)
|
| 371 | 370 | rhs_for_spec = Let (NonRec poly_tup_id poly_tup_rhs) rhs
|
| 372 | 371 | ; (spec_binds, rules) <- dsSpecs rhs_for_spec spec_prags
|
| 373 | - ; let global' = (global `setInlinePragma`
|
|
| 374 | - (defaultInlinePragma `setInlinePragmaArity` dictArity dicts))
|
|
| 372 | + ; let global' = (global `setInlinePragma` defaultInlinePragma)
|
|
| 375 | 373 | `addIdSpecialisations` rules
|
| 376 | 374 | -- Kill the INLINE pragma because it applies to
|
| 377 | 375 | -- the user written (local) function. The global
|
| ... | ... | @@ -447,7 +445,7 @@ makeCorePair dflags gbl_id is_default_method dict_arity rhs |
| 447 | 445 | = (gbl_id `setIdUnfolding` mkCompulsoryUnfolding' simpl_opts rhs, rhs)
|
| 448 | 446 | |
| 449 | 447 | | otherwise
|
| 450 | - = case inl_spec of
|
|
| 448 | + = case inlinePragmaSpec inline_prag of
|
|
| 451 | 449 | NoUserInlinePrag -> (gbl_id, rhs)
|
| 452 | 450 | NoInline {} -> (gbl_id, rhs)
|
| 453 | 451 | Opaque {} -> (gbl_id, rhs)
|
| ... | ... | @@ -455,16 +453,21 @@ makeCorePair dflags gbl_id is_default_method dict_arity rhs |
| 455 | 453 | Inline {} -> inline_pair
|
| 456 | 454 | where
|
| 457 | 455 | simpl_opts = initSimpleOpts dflags
|
| 458 | - InlinePragma (InlinePragmaGhcTag _ arity) inl_spec _ _ = idInlinePragma gbl_id
|
|
| 456 | + inline_prag = idInlinePragma gbl_id
|
|
| 459 | 457 | inlinable_unf = mkInlinableUnfolding simpl_opts StableUserSrc rhs
|
| 460 | - inline_pair =
|
|
| 461 | - -- Add an Unfolding for an INLINE (but not for NOINLINE)
|
|
| 462 | - -- And eta-expand the RHS; see Note [Eta-expanding INLINE things]
|
|
| 463 | - let real_arity = dict_arity + arity
|
|
| 464 | - -- NB: The arity passed to mkInlineUnfoldingWithArity
|
|
| 465 | - -- must take account of the dictionaries
|
|
| 466 | - in ( gbl_id `setIdUnfolding` mkInlineUnfoldingWithArity simpl_opts StableUserSrc real_arity rhs
|
|
| 467 | - , etaExpand real_arity rhs)
|
|
| 458 | + inline_pair
|
|
| 459 | + | ArityExplicitly arity <- inlinePragmaArity inline_prag
|
|
| 460 | + -- Add an Unfolding for an INLINE (but not for NOINLINE)
|
|
| 461 | + -- And eta-expand the RHS; see Note [Eta-expanding INLINE things]
|
|
| 462 | + , let real_arity = dict_arity + fromEnum arity
|
|
| 463 | + -- NB: The arity passed to mkInlineUnfoldingWithArity
|
|
| 464 | + -- must take account of the dictionaries
|
|
| 465 | + = ( gbl_id `setIdUnfolding` mkInlineUnfoldingWithArity simpl_opts StableUserSrc real_arity rhs
|
|
| 466 | + , etaExpand real_arity rhs)
|
|
| 467 | + |
|
| 468 | + | otherwise
|
|
| 469 | + = pprTrace "makeCorePair: arity missing" (ppr gbl_id) $
|
|
| 470 | + (gbl_id `setIdUnfolding` mkInlineUnfoldingNoArity simpl_opts StableUserSrc rhs, rhs)
|
|
| 468 | 471 | |
| 469 | 472 | dictArity :: [Var] -> Arity
|
| 470 | 473 | -- Don't count coercion variables in arity
|
| ... | ... | @@ -1017,7 +1020,7 @@ dsSpec_help poly_nm poly_id poly_rhs spec_inl orig_bndrs ds_call |
| 1017 | 1020 | fn_unf = realIdUnfolding poly_id
|
| 1018 | 1021 | spec_unf = specUnfolding simpl_opts spec_bndrs mk_spec_body rule_lhs_args fn_unf
|
| 1019 | 1022 | spec_info = vanillaIdInfo
|
| 1020 | - `setInlinePragInfo` specFunInlinePrag poly_id id_inl spec_inl
|
|
| 1023 | + `setInlinePragInfo` specFunInlinePrag poly_id id_inl (demoteInlinePragmaTc spec_inl)
|
|
| 1021 | 1024 | `setUnfoldingInfo` spec_unf
|
| 1022 | 1025 | spec_id = mkLocalVar (idDetails poly_id) spec_name ManyTy spec_ty spec_info
|
| 1023 | 1026 | -- Specialised binding is toplevel, hence Many.
|
| ... | ... | @@ -1057,7 +1060,7 @@ dsSpec_help poly_nm poly_id poly_rhs spec_inl orig_bndrs ds_call |
| 1057 | 1060 | ; dsWarnOrphanRule rule
|
| 1058 | 1061 | |
| 1059 | 1062 | ; case checkUselessSpecPrag poly_id rule_lhs_args spec_bndrs
|
| 1060 | - no_act_spec (unsetInlinePragmaArity spec_inl) rule_act of
|
|
| 1063 | + no_act_spec spec_inl rule_act of
|
|
| 1061 | 1064 | Nothing -> return (Just result)
|
| 1062 | 1065 | |
| 1063 | 1066 | Just reason -> do { diagnosticDs $ DsUselessSpecialisePragma poly_nm is_dfun reason
|
| ... | ... | @@ -1111,7 +1114,7 @@ decomposeCall poly_id ds_call |
| 1111 | 1114 | |
| 1112 | 1115 | -- Is this SPECIALISE pragma useless?
|
| 1113 | 1116 | checkUselessSpecPrag :: Id -> [CoreExpr]
|
| 1114 | - -> [Var] -> Bool -> InlinePragma GhcPs -> Activation
|
|
| 1117 | + -> [Var] -> Bool -> InlinePragma (GhcPass p) -> Activation
|
|
| 1115 | 1118 | -> Maybe UselessSpecialisePragmaReason
|
| 1116 | 1119 | checkUselessSpecPrag poly_id rule_lhs_args
|
| 1117 | 1120 | spec_bndrs no_act_spec spec_inl rule_act
|
| ... | ... | @@ -1187,19 +1190,17 @@ getCastedVar (Var v) = Just (v, MRefl) |
| 1187 | 1190 | getCastedVar (Cast (Var v) co) = Just (v, MCo co)
|
| 1188 | 1191 | getCastedVar _ = Nothing
|
| 1189 | 1192 | |
| 1190 | -specFunInlinePrag :: Id -> InlinePragma GhcTc
|
|
| 1191 | - -> InlinePragma GhcTc -> InlinePragma GhcTc
|
|
| 1193 | +--specFunInlinePrag :: forall p. IsPass p => Id -> InlinePragma (GhcPass p) -> InlinePragma (GhcPass p) -> InlinePragma (GhcPass p)
|
|
| 1194 | +specFunInlinePrag :: Id -> InlinePragma GhcRn -> InlinePragma GhcRn -> InlinePragma GhcRn
|
|
| 1192 | 1195 | -- See Note [Activation pragmas for SPECIALISE]
|
| 1193 | 1196 | specFunInlinePrag poly_id id_inl spec_inl
|
| 1194 | 1197 | | not (isDefaultInlinePragma spec_inl) = spec_inl
|
| 1195 | 1198 | | isGlobalId poly_id -- See Note [Specialising imported functions]
|
| 1196 | 1199 | -- in OccurAnal
|
| 1197 | - , isStrongLoopBreaker (idOccInfo poly_id) = neverInlinePragma `setInlinePragmaArity` arity
|
|
| 1200 | + , isStrongLoopBreaker (idOccInfo poly_id) = neverInlinePragma
|
|
| 1198 | 1201 | | otherwise = id_inl
|
| 1199 | 1202 | -- Get the INLINE pragma from SPECIALISE declaration, or,
|
| 1200 | 1203 | -- failing that, from the original Id
|
| 1201 | - where
|
|
| 1202 | - arity = arityInfo $ idInfo poly_id
|
|
| 1203 | 1204 | |
| 1204 | 1205 | dsWarnOrphanRule :: CoreRule -> DsM ()
|
| 1205 | 1206 | dsWarnOrphanRule rule
|
| ... | ... | @@ -1103,7 +1103,7 @@ renameSig ctxt sig@(SpecSig _ v tys inl) |
| 1103 | 1103 | TopSigCtxt {} -> lookupLocatedOccRn WL_TermVariable v
|
| 1104 | 1104 | _ -> lookupSigOccRn ctxt sig v
|
| 1105 | 1105 | ; (new_ty, fvs) <- foldM do_one ([],emptyFVs) tys
|
| 1106 | - ; return (SpecSig noAnn new_v new_ty (inl `setInlinePragmaArity` 0), fvs) } -- TODO: setting arity to 0 is likely wrong
|
|
| 1106 | + ; return (SpecSig noAnn new_v new_ty (setInlinePragmaArityAsNotExplicit inl), fvs) }
|
|
| 1107 | 1107 | where
|
| 1108 | 1108 | do_one (tys,fvs) ty
|
| 1109 | 1109 | = do { (new_ty, fvs_ty) <- rnHsSigType (SpecialiseSigCtx v) TypeLevel ty
|
| ... | ... | @@ -1114,11 +1114,11 @@ renameSig _ctxt (SpecSigE _ bndrs spec_e inl) |
| 1114 | 1114 | ; fn_name <- lookupOccRn WL_TermVariable fn_rdr -- Checks that the head isn't forall-bound
|
| 1115 | 1115 | ; bindRuleBndrs (SpecECtx fn_rdr) bndrs $ \_ bndrs' ->
|
| 1116 | 1116 | do { (spec_e', fvs) <- rnLExpr spec_e
|
| 1117 | - ; return (SpecSigE fn_name bndrs' spec_e' ( inl `setInlinePragmaArity` 0), fvs) } } -- TODO: setting arity to 0 is likely wrong
|
|
| 1117 | + ; return (SpecSigE fn_name bndrs' spec_e' (setInlinePragmaArityAsNotExplicit inl), fvs) } }
|
|
| 1118 | 1118 | |
| 1119 | 1119 | renameSig ctxt sig@(InlineSig _ v s)
|
| 1120 | 1120 | = do { new_v <- lookupSigOccRn ctxt sig v
|
| 1121 | - ; return (InlineSig noAnn new_v ( s `setInlinePragmaArity` 0 ), emptyFVs) } -- TODO: setting arity to 0 is likely wrong
|
|
| 1121 | + ; return (InlineSig noAnn new_v (setInlinePragmaArityAsNotExplicit s), emptyFVs) }
|
|
| 1122 | 1122 | |
| 1123 | 1123 | renameSig ctxt (FixSig _ fsig)
|
| 1124 | 1124 | = do { new_fsig <- rnSrcFixityDecl ctxt fsig
|
| ... | ... | @@ -604,7 +604,7 @@ addInlinePragArity _ sig = sig |
| 604 | 604 | add_inl_arity :: Arity -> InlinePragma GhcRn -> InlinePragma GhcRn
|
| 605 | 605 | add_inl_arity ar prag@(InlinePragma { inl_inline = inl_spec })
|
| 606 | 606 | | Inline {} <- inl_spec -- Add arity only for real INLINE pragmas, not INLINABLE
|
| 607 | - = prag `setInlinePragmaArity` ar
|
|
| 607 | + = prag `setInlinePragmaArityAsExplicitly` ar
|
|
| 608 | 608 | | otherwise
|
| 609 | 609 | = prag
|
| 610 | 610 | |
| ... | ... | @@ -620,7 +620,7 @@ addInlinePrags poly_id prags_for_me |
| 620 | 620 | | inl@(L _ prag) : inls <- inl_prags
|
| 621 | 621 | = do { traceTc "addInlinePrag" (ppr poly_id $$ ppr prag)
|
| 622 | 622 | ; unless (null inls) (warn_multiple_inlines inl inls)
|
| 623 | - ; return (poly_id `setInlinePragma` prag) }
|
|
| 623 | + ; return (poly_id `setInlinePragma` demoteInlinePragmaTc prag) }
|
|
| 624 | 624 | | otherwise
|
| 625 | 625 | = return poly_id
|
| 626 | 626 | where
|
| ... | ... | @@ -13,7 +13,7 @@ import GHC.Prelude |
| 13 | 13 | import GHC.Platform
|
| 14 | 14 | |
| 15 | 15 | import GHC.Types.Basic ( TypeOrConstraint(..) )
|
| 16 | -import GHC.Types.InlinePragma ( neverInlinePragma, setInlinePragmaArity )
|
|
| 16 | +import GHC.Types.InlinePragma ( neverInlinePragma )
|
|
| 17 | 17 | import GHC.Types.SourceText ( SourceText(..) )
|
| 18 | 18 | import GHC.Iface.Env( newGlobalBinder )
|
| 19 | 19 | import GHC.Core.TyCo.Rep( Type(..), TyLit(..) )
|
| ... | ... | @@ -554,8 +554,7 @@ getKindRep stuff@(Stuff {..}) in_scope = go |
| 554 | 554 | | otherwise
|
| 555 | 555 | = do -- Place a NOINLINE pragma on KindReps since they tend to be quite
|
| 556 | 556 | -- large and bloat interface files.
|
| 557 | - let prag = neverInlinePragma `setInlinePragmaArity` 0
|
|
| 558 | - rep_bndr <- (`setInlinePragma` prag)
|
|
| 557 | + rep_bndr <- (`setInlinePragma` neverInlinePragma)
|
|
| 559 | 558 | <$> newSysLocalId (fsLit "$krep") ManyTy (mkTyConTy kindRepTyCon)
|
| 560 | 559 | |
| 561 | 560 | -- do we need to tie a knot here?
|
| ... | ... | @@ -70,7 +70,6 @@ import GHC.Types.Var.Env |
| 70 | 70 | import GHC.Types.Var.Set
|
| 71 | 71 | import GHC.Types.Basic
|
| 72 | 72 | import GHC.Types.Id
|
| 73 | -import GHC.Types.Id.Info (arityInfo)
|
|
| 74 | 73 | import GHC.Types.InlinePragma
|
| 75 | 74 | import GHC.Types.SourceFile
|
| 76 | 75 | import GHC.Types.SourceText
|
| ... | ... | @@ -1429,10 +1428,9 @@ addDFunPrags :: DFunId -> [Id] -> DFunId |
| 1429 | 1428 | -- is messing with.
|
| 1430 | 1429 | addDFunPrags dfun_id sc_meth_ids
|
| 1431 | 1430 | = dfun_id `setIdUnfolding` mkDFunUnfolding dfun_bndrs dict_con dict_args
|
| 1432 | - `setInlinePragma` (dfunInlinePragma `setInlinePragmaArity` arity) -- NOTE: Check if this arity calculation is correct
|
|
| 1431 | + `setInlinePragma` dfunInlinePragma
|
|
| 1433 | 1432 | -- NB: mkDFunUnfolding takes care of unary classes
|
| 1434 | 1433 | where
|
| 1435 | - arity = length var_apps
|
|
| 1436 | 1434 | dict_args = map Type inst_tys ++ var_apps
|
| 1437 | 1435 | var_apps = [mkVarApps (Var id) dfun_bndrs | id <- sc_meth_ids]
|
| 1438 | 1436 | |
| ... | ... | @@ -2267,7 +2265,7 @@ mkDefMethBind loc dfun_id clas sel_id dm_name dm_spec |
| 2267 | 2265 | = do { logger <- getLogger
|
| 2268 | 2266 | ; dm_id <- tcLookupId dm_name
|
| 2269 | 2267 | ; let inline_prag :: InlinePragma GhcRn
|
| 2270 | - inline_prag = demoteInlinePragmaRn $ idInlinePragma dm_id
|
|
| 2268 | + inline_prag = idInlinePragma dm_id
|
|
| 2271 | 2269 | inline_prags | isAnyInlinePragma inline_prag
|
| 2272 | 2270 | = [noLocA (InlineSig noAnn fn inline_prag)]
|
| 2273 | 2271 | | otherwise
|
| ... | ... | @@ -2669,11 +2667,9 @@ tcSpecInstPrags dfun_id (InstBindings { ib_binds = binds, ib_pragmas = uprags }) |
| 2669 | 2667 | tcSpecInst :: Id -> Sig GhcRn -> TcM TcSpecPrag
|
| 2670 | 2668 | tcSpecInst dfun_id prag@(SpecInstSig _ hs_ty)
|
| 2671 | 2669 | = addErrCtxt (SpecPragmaCtxt prag) $
|
| 2672 | - let arity = arityInfo $ idInfo dfun_id
|
|
| 2673 | - prag = defaultInlinePragma `setInlinePragmaArity` arity
|
|
| 2674 | - in do { spec_dfun_ty <- tcHsClsInstType SpecInstCtxt hs_ty
|
|
| 2675 | - ; co_fn <- tcSpecWrapper SpecInstCtxt (idType dfun_id) spec_dfun_ty
|
|
| 2676 | - ; return (SpecPrag dfun_id co_fn prag) }
|
|
| 2670 | + do { spec_dfun_ty <- tcHsClsInstType SpecInstCtxt hs_ty
|
|
| 2671 | + ; co_fn <- tcSpecWrapper SpecInstCtxt (idType dfun_id) spec_dfun_ty
|
|
| 2672 | + ; return (SpecPrag dfun_id co_fn defaultInlinePragma) }
|
|
| 2677 | 2673 | |
| 2678 | 2674 | tcSpecInst _ _ = panic "tcSpecInst"
|
| 2679 | 2675 |
| ... | ... | @@ -6,14 +6,18 @@ |
| 6 | 6 | |
| 7 | 7 | module GHC.Types.Arity
|
| 8 | 8 | ( Arity
|
| 9 | - , VisArity
|
|
| 10 | - , RepArity
|
|
| 11 | - , JoinArity
|
|
| 12 | 9 | , FullArgCount
|
| 10 | + , InlineArity(..)
|
|
| 11 | + , JoinArity
|
|
| 12 | + , RepArity
|
|
| 13 | + , VisArity
|
|
| 13 | 14 | ) where
|
| 14 | 15 | |
| 15 | 16 | import GHC.Prelude
|
| 16 | 17 | |
| 18 | +import Control.DeepSeq (NFData(..))
|
|
| 19 | +import Data.Data (Data)
|
|
| 20 | + |
|
| 17 | 21 | {-
|
| 18 | 22 | ************************************************************************
|
| 19 | 23 | * *
|
| ... | ... | @@ -29,9 +33,29 @@ import GHC.Prelude |
| 29 | 33 | -- See also Note [Definition of arity] in "GHC.Core.Opt.Arity"
|
| 30 | 34 | type Arity = Int
|
| 31 | 35 | |
| 32 | --- | Syntactic (visibility) arity, i.e. the number of visible arguments.
|
|
| 33 | --- See Note [Visibility and arity]
|
|
| 34 | -type VisArity = Int
|
|
| 36 | +-- | FullArgCount is the number of type or value arguments in an application,
|
|
| 37 | +-- or the number of type or value binders in a lambda. Note: it includes
|
|
| 38 | +-- both type and value arguments!
|
|
| 39 | +type FullArgCount = Int
|
|
| 40 | + |
|
| 41 | +-- | The arity /at which to/ inline a function.
|
|
| 42 | +-- This may differ from the function's syntactic arity.
|
|
| 43 | +data InlineArity
|
|
| 44 | + = ArityExplicitly !Word
|
|
| 45 | + -- ^ Inline only when applied to @n@ explicit
|
|
| 46 | + -- (non-type, non-dictionary) arguments.
|
|
| 47 | + --
|
|
| 48 | + -- That is, 'ArityExplicitly' describes the number of
|
|
| 49 | + -- *source-code* arguments the thing must be applied to.
|
|
| 50 | + | ArityNotExplicit
|
|
| 51 | + -- ^ There does not exist an explicit number of arguments
|
|
| 52 | + -- that the inlining process should be applied to.
|
|
| 53 | + deriving (Eq, Data)
|
|
| 54 | + |
|
| 55 | +instance NFData InlineArity where
|
|
| 56 | + |
|
| 57 | + rnf (ArityExplicitly !w) = rnf w `seq` ()
|
|
| 58 | + rnf !ArityNotExplicit = ()
|
|
| 35 | 59 | |
| 36 | 60 | -- | Representation Arity
|
| 37 | 61 | --
|
| ... | ... | @@ -48,10 +72,9 @@ type RepArity = Int |
| 48 | 72 | -- are counted.
|
| 49 | 73 | type JoinArity = Int
|
| 50 | 74 | |
| 51 | --- | FullArgCount is the number of type or value arguments in an application,
|
|
| 52 | --- or the number of type or value binders in a lambda. Note: it includes
|
|
| 53 | --- both type and value arguments!
|
|
| 54 | -type FullArgCount = Int
|
|
| 75 | +-- | Syntactic (visibility) arity, i.e. the number of visible arguments.
|
|
| 76 | +-- See Note [Visibility and arity]
|
|
| 77 | +type VisArity = Int
|
|
| 55 | 78 | |
| 56 | 79 | {- Note [Visibility and arity]
|
| 57 | 80 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1304,18 +1304,18 @@ failed Succeeded = False |
| 1304 | 1304 | failed Failed = True
|
| 1305 | 1305 | |
| 1306 | 1306 | {-
|
| 1307 | -data InlinePragmaGhcTag = InlinePragmaGhcTag
|
|
| 1307 | +data XInlinePragmaGhc = XInlinePragmaGhc
|
|
| 1308 | 1308 | { inl_ghcrn_src :: {-# UNPACK#-} !SourceText
|
| 1309 | 1309 | , inl_ghcrn_arity :: {-# UNPACK#-} !Arity
|
| 1310 | 1310 | }
|
| 1311 | 1311 | deriving (Eq, Data)
|
| 1312 | 1312 | |
| 1313 | -instance NFData InlinePragmaGhcTag where
|
|
| 1314 | - rnf (InlinePragmaGhcTag s a) = rnf s `seq` rnf a `seq` ()
|
|
| 1313 | +instance NFData XInlinePragmaGhc where
|
|
| 1314 | + rnf (XInlinePragmaGhc s a) = rnf s `seq` rnf a `seq` ()
|
|
| 1315 | 1315 | |
| 1316 | 1316 | type instance XInlinePragma GhcPs = SourceText
|
| 1317 | -type instance XInlinePragma GhcRn = InlinePragmaGhcTag
|
|
| 1318 | -type instance XInlinePragma GhcTc = InlinePragmaGhcTag
|
|
| 1317 | +type instance XInlinePragma GhcRn = XInlinePragmaGhc
|
|
| 1318 | +type instance XInlinePragma GhcTc = XInlinePragmaGhc
|
|
| 1319 | 1319 | type instance XXInlinePragma (GhcPass _) = DataConCantHappen
|
| 1320 | 1320 | |
| 1321 | 1321 | defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma
|
| ... | ... | @@ -1339,7 +1339,7 @@ dfunInlinePragma = defaultInlinePragma { inl_act = AlwaysActive |
| 1339 | 1339 | |
| 1340 | 1340 | setInlinePragmaArity :: InlinePragma GhcPs -> Arity -> InlinePragma GhcTc
|
| 1341 | 1341 | setInlinePragmaArity prag@(InlinePragma { inl_ext = srcTxt }) arity =
|
| 1342 | - prag { inl_ext = InlinePragmaGhcTag srcTxt arity }
|
|
| 1342 | + prag { inl_ext = XInlinePragmaGhc srcTxt arity }
|
|
| 1343 | 1343 | |
| 1344 | 1344 | |
| 1345 | 1345 | inlinePragmaSource :: forall p. IsPass p => InlinePragma (GhcPass p) -> SourceText
|
| ... | ... | @@ -150,7 +150,7 @@ import GHC.Core.DataCon |
| 150 | 150 | import GHC.Core.Class
|
| 151 | 151 | import GHC.Core.Multiplicity
|
| 152 | 152 | |
| 153 | -import GHC.Hs.Extension (GhcTc)
|
|
| 153 | +import GHC.Hs.Extension (GhcRn)
|
|
| 154 | 154 | |
| 155 | 155 | import GHC.Types.RepType
|
| 156 | 156 | import GHC.Types.Demand
|
| ... | ... | @@ -944,13 +944,13 @@ The inline pragma tells us to be very keen to inline this Id, but it's still |
| 944 | 944 | OK not to if optimisation is switched off.
|
| 945 | 945 | -}
|
| 946 | 946 | |
| 947 | -idInlinePragma :: Id -> InlinePragma GhcTc
|
|
| 947 | +idInlinePragma :: Id -> InlinePragma GhcRn
|
|
| 948 | 948 | idInlinePragma id = inlinePragInfo (idInfo id)
|
| 949 | 949 | |
| 950 | -setInlinePragma :: Id -> InlinePragma GhcTc -> Id
|
|
| 950 | +setInlinePragma :: Id -> InlinePragma GhcRn -> Id
|
|
| 951 | 951 | setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
|
| 952 | 952 | |
| 953 | -modifyInlinePragma :: Id -> (InlinePragma GhcTc -> InlinePragma GhcTc) -> Id
|
|
| 953 | +modifyInlinePragma :: Id -> (InlinePragma GhcRn -> InlinePragma GhcRn) -> Id
|
|
| 954 | 954 | modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
|
| 955 | 955 | |
| 956 | 956 | idInlineActivation :: Id -> Activation
|
| ... | ... | @@ -106,10 +106,8 @@ import GHC.Unit.Module |
| 106 | 106 | import GHC.Types.Demand
|
| 107 | 107 | import GHC.Types.Cpr
|
| 108 | 108 | import GHC.Types.InlinePragma
|
| 109 | -import GHC.Types.SourceText
|
|
| 110 | 109 | import {-# SOURCE #-} GHC.Tc.Utils.TcType ( ConcreteTyVars, noConcreteTyVars )
|
| 111 | 110 | |
| 112 | - |
|
| 113 | 111 | import GHC.Utils.Outputable
|
| 114 | 112 | import GHC.Utils.Panic
|
| 115 | 113 | import GHC.Stg.EnforceEpt.TagSig
|
| ... | ... | @@ -441,7 +439,7 @@ data IdInfo |
| 441 | 439 | -- See Note [Specialisations and RULES in IdInfo]
|
| 442 | 440 | realUnfoldingInfo :: Unfolding,
|
| 443 | 441 | -- ^ The 'Id's unfolding
|
| 444 | - inlinePragInfo :: InlinePragma GhcTc,
|
|
| 442 | + inlinePragInfo :: InlinePragma GhcRn,
|
|
| 445 | 443 | -- ^ Any inline pragma attached to the 'Id'
|
| 446 | 444 | occInfo :: OccInfo,
|
| 447 | 445 | -- ^ How the 'Id' occurs in the program
|
| ... | ... | @@ -554,16 +552,9 @@ tagSigInfo = tagSig |
| 554 | 552 | |
| 555 | 553 | setRuleInfo :: IdInfo -> RuleInfo -> IdInfo
|
| 556 | 554 | setRuleInfo info sp = sp `seq` info { ruleInfo = sp }
|
| 557 | ---setInlinePragInfo :: IdInfo -> InlinePragma GhcTc -> IdInfo
|
|
| 558 | ---setInlinePragInfo info pr = pr `seq` info { inlinePragInfo = pr }
|
|
| 559 | -setInlinePragInfo :: forall p. IsPass p => IdInfo -> InlinePragma (GhcPass p) -> IdInfo
|
|
| 560 | -setInlinePragInfo info pr@(InlinePragma { inl_ext = src }) = pr `seq` info { inlinePragInfo = pr { inl_ext = tag } }
|
|
| 561 | - where
|
|
| 562 | - tag :: InlinePragmaGhcTag
|
|
| 563 | - tag = case ghcPass @p of
|
|
| 564 | - GhcPs -> InlinePragmaGhcTag (src :: SourceText) 0
|
|
| 565 | - GhcRn -> (src :: InlinePragmaGhcTag)
|
|
| 566 | - GhcTc -> (src :: InlinePragmaGhcTag)
|
|
| 555 | + |
|
| 556 | +setInlinePragInfo :: IdInfo -> InlinePragma GhcRn -> IdInfo
|
|
| 557 | +setInlinePragInfo info pr = pr `seq` info { inlinePragInfo = pr }
|
|
| 567 | 558 | |
| 568 | 559 | setOccInfo :: IdInfo -> OccInfo -> IdInfo
|
| 569 | 560 | setOccInfo info oc = oc `seq` info { occInfo = oc }
|
| ... | ... | @@ -630,7 +621,7 @@ vanillaIdInfo |
| 630 | 621 | = IdInfo {
|
| 631 | 622 | ruleInfo = emptyRuleInfo,
|
| 632 | 623 | realUnfoldingInfo = noUnfolding,
|
| 633 | - inlinePragInfo = defaultInlinePragma `setInlinePragmaArity` 0,
|
|
| 624 | + inlinePragInfo = defaultInlinePragma,
|
|
| 634 | 625 | occInfo = noOccInfo,
|
| 635 | 626 | demandInfo = topDmd,
|
| 636 | 627 | dmdSigInfo = nopSig,
|
| ... | ... | @@ -65,7 +65,7 @@ import GHC.Core.TyCon |
| 65 | 65 | import GHC.Core.Class
|
| 66 | 66 | import GHC.Core.DataCon
|
| 67 | 67 | |
| 68 | -import GHC.Hs.Extension (GhcPs, GhcTc)
|
|
| 68 | +import GHC.Hs.Extension (GhcRn)
|
|
| 69 | 69 | |
| 70 | 70 | import GHC.Types.Literal
|
| 71 | 71 | import GHC.Types.RepType ( countFunRepArgs, typePrimRep )
|
| ... | ... | @@ -608,8 +608,8 @@ mkDataConWorkId wkr_name data_con |
| 608 | 608 | -- See Note [Strict fields in Core]
|
| 609 | 609 | `setLFInfo` wkr_lf_info
|
| 610 | 610 | |
| 611 | - wkr_inline_prag :: InlinePragma GhcTc
|
|
| 612 | - wkr_inline_prag = alwaysInlineConLikePragma `setInlinePragmaArity` wkr_arity
|
|
| 611 | + wkr_inline_prag :: InlinePragma GhcRn
|
|
| 612 | + wkr_inline_prag = alwaysInlineConLikePragma
|
|
| 613 | 613 | wkr_arity = dataConRepArity data_con
|
| 614 | 614 | |
| 615 | 615 | wkr_sig = mkClosedDmdSig wkr_dmds topDiv
|
| ... | ... | @@ -989,7 +989,7 @@ mkDataConRep dc_bang_opts fam_envs wrap_name data_con |
| 989 | 989 | ; return (unbox_fn expr) }
|
| 990 | 990 | |
| 991 | 991 | |
| 992 | -dataConWrapperInlinePragma :: InlinePragma GhcPs
|
|
| 992 | +dataConWrapperInlinePragma :: InlinePragma GhcRn
|
|
| 993 | 993 | -- See Note [DataCon wrappers are conlike]
|
| 994 | 994 | dataConWrapperInlinePragma = alwaysInlineConLikePragma
|
| 995 | 995 | |
| ... | ... | @@ -1950,7 +1950,7 @@ nullAddrId :: Id |
| 1950 | 1950 | -- a way to write this literal in Haskell.
|
| 1951 | 1951 | nullAddrId = pcMiscPrelId nullAddrName addrPrimTy info
|
| 1952 | 1952 | where
|
| 1953 | - info = noCafIdInfo `setInlinePragInfo` (alwaysInlinePragma `setInlinePragmaArity` 0 :: InlinePragma GhcTc)
|
|
| 1953 | + info = noCafIdInfo `setInlinePragInfo` alwaysInlinePragma
|
|
| 1954 | 1954 | `setUnfoldingInfo` mkCompulsoryUnfolding (Lit nullAddrLit)
|
| 1955 | 1955 | |
| 1956 | 1956 | ------------------------------------------------
|
| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | (c) The GRASP/AQUA Project, Glasgow University, 1997-1998
|
| 7 | 7 | -}
|
| 8 | 8 | |
| 9 | -{-# OPTIONS_GHC -Wno-orphans #-} -- Binary InlinePragmaGhcTag, Binary InlinePragma
|
|
| 9 | +{-# OPTIONS_GHC -Wno-orphans #-} -- Binary XInlinePragmaGhc, Binary InlinePragma
|
|
| 10 | 10 | |
| 11 | 11 | module GHC.Types.InlinePragma
|
| 12 | 12 | ( -- * Inline Pragma Encoding
|
| ... | ... | @@ -21,6 +21,7 @@ module GHC.Types.InlinePragma |
| 21 | 21 | , neverInlinePragma
|
| 22 | 22 | -- *** Field accessors
|
| 23 | 23 | , inlinePragmaActivation
|
| 24 | + , inlinePragmaArity
|
|
| 24 | 25 | , inlinePragmaName
|
| 25 | 26 | , inlinePragmaRuleMatchInfo
|
| 26 | 27 | , inlinePragmaSource
|
| ... | ... | @@ -33,20 +34,22 @@ module GHC.Types.InlinePragma |
| 33 | 34 | , isNoInlinePragma
|
| 34 | 35 | , isOpaquePragma
|
| 35 | 36 | -- *** Mutators
|
| 37 | + , setInlinePragmaSource
|
|
| 38 | + , setInlinePragmaArityAsExplicitly
|
|
| 39 | + , setInlinePragmaArityAsNotExplicit
|
|
| 36 | 40 | , setInlinePragmaActivation
|
| 37 | - , setInlinePragmaArity
|
|
| 41 | + , setInlinePragmaSpec
|
|
| 38 | 42 | , setInlinePragmaRuleMatchInfo
|
| 39 | 43 | -- *** GHC pass conversions
|
| 40 | - , demoteInlinePragmaRn
|
|
| 44 | + , demoteInlinePragmaTc
|
|
| 41 | 45 | , promoteInlinePragmaRn
|
| 42 | - , setInlinePragmaTag
|
|
| 43 | - , unsetInlinePragmaArity
|
|
| 44 | 46 | -- *** Pretty-printing
|
| 45 | 47 | , pprInline
|
| 46 | 48 | , pprInlineDebug
|
| 47 | 49 | |
| 48 | 50 | -- ** Extensible record type for GhcRn & GhcTc
|
| 49 | - , InlinePragmaGhcTag(..)
|
|
| 51 | + , XInlinePragmaGhc(..)
|
|
| 52 | + , InlineArity(..)
|
|
| 50 | 53 | |
| 51 | 54 | -- ** InlineSpec
|
| 52 | 55 | -- *** Data-type
|
| ... | ... | @@ -98,19 +101,26 @@ import {-# SOURCE #-} GHC.Hs.Extension |
| 98 | 101 | import GHC.Data.FastString
|
| 99 | 102 | import GHC.Utils.Binary
|
| 100 | 103 | import GHC.Utils.Outputable
|
| 101 | -import GHC.Types.Arity (Arity)
|
|
| 102 | -import GHC.Types.SourceText
|
|
| 104 | +import GHC.Types.Arity (InlineArity(..))
|
|
| 105 | +import GHC.Types.SourceText (SourceText(..))
|
|
| 103 | 106 | import Control.DeepSeq (NFData(..))
|
| 104 | -import Data.Data
|
|
| 107 | +import Data.Data (Data)
|
|
| 105 | 108 | |
| 106 | 109 | import Language.Haskell.Syntax.Binds.InlinePragma
|
| 107 | 110 | import Language.Haskell.Syntax.Extension
|
| 108 | 111 | |
| 112 | +-- infixl so you can say (prag `set` a `set` b)
|
|
| 113 | +infixl 1 `setInlinePragmaActivation`,
|
|
| 114 | + `setInlinePragmaArityAsExplicitly`,
|
|
| 115 | + `setInlinePragmaRuleMatchInfo`,
|
|
| 116 | + `setInlinePragmaSource`,
|
|
| 117 | + `setInlinePragmaSpec`
|
|
| 118 | + |
|
| 109 | 119 | data XInlinePragmaGhc = XInlinePragmaGhc
|
| 110 | 120 | { xinl_src :: SourceText
|
| 111 | 121 | -- ^ See Note [Pragma source text]
|
| 112 | - , xinl_sat :: Maybe Arity
|
|
| 113 | - -- ^ @Just n@ <=> Inline only when applied to @n@ explicit
|
|
| 122 | + , xinl_sat :: InlineArity
|
|
| 123 | + -- ^ Inline only when applied to @n@ explicit
|
|
| 114 | 124 | -- (non-type, non-dictionary) arguments.
|
| 115 | 125 | --
|
| 116 | 126 | -- That is, 'xinl_sat' describes the number of *source-code*
|
| ... | ... | @@ -120,33 +130,48 @@ data XInlinePragmaGhc = XInlinePragmaGhc |
| 120 | 130 | }
|
| 121 | 131 | deriving (Eq, Data)
|
| 122 | 132 | |
| 123 | -instance NFData InlinePragmaGhcTag where
|
|
| 124 | - rnf (InlinePragmaGhcTag s a) = rnf s `seq` rnf a `seq` ()
|
|
| 133 | +instance NFData XInlinePragmaGhc where
|
|
| 134 | + rnf (XInlinePragmaGhc s a) = rnf s `seq` rnf a `seq` ()
|
|
| 125 | 135 | |
| 126 | 136 | type instance XInlinePragma GhcPs = SourceText
|
| 127 | -type instance XInlinePragma GhcRn = InlinePragmaGhcTag
|
|
| 128 | -type instance XInlinePragma GhcTc = InlinePragmaGhcTag
|
|
| 137 | +type instance XInlinePragma GhcRn = XInlinePragmaGhc
|
|
| 138 | +type instance XInlinePragma GhcTc = XInlinePragmaGhc
|
|
| 129 | 139 | type instance XXInlinePragma (GhcPass _) = DataConCantHappen
|
| 130 | 140 | |
| 131 | -defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma
|
|
| 132 | - :: InlinePragma GhcPs
|
|
| 133 | -defaultInlinePragma = InlinePragma { inl_ext = SourceText $ fsLit "{-# INLINE"
|
|
| 134 | - , inl_act = AlwaysActive
|
|
| 135 | - , inl_rule = FunLike
|
|
| 136 | - , inl_inline = NoUserInlinePrag }
|
|
| 137 | - |
|
| 138 | -alwaysInlinePragma = defaultInlinePragma { inl_inline = Inline }
|
|
| 139 | -neverInlinePragma = defaultInlinePragma { inl_act = NeverActive }
|
|
| 140 | - |
|
| 141 | -alwaysInlineConLikePragma :: InlinePragma GhcPs
|
|
| 142 | -alwaysInlineConLikePragma = alwaysInlinePragma { inl_rule = ConLike }
|
|
| 141 | +-- | The default 'InlinePragma' definition for GHC.
|
|
| 142 | +-- The type and value of 'inl_ext' provided will differ
|
|
| 143 | +-- between the passes of GHC. Consequently, it may be
|
|
| 144 | +-- necessary to apply type annotation at the call site
|
|
| 145 | +-- to help the type checker disambiguate the correct
|
|
| 146 | +-- type of 'inl_ext'.
|
|
| 147 | +defaultInlinePragma :: forall p. IsPass p => InlinePragma (GhcPass p)
|
|
| 148 | +defaultInlinePragma =
|
|
| 149 | + let srcTxt = SourceText $ fsLit "{-# INLINE"
|
|
| 150 | + inlExt = case ghcPass @p of
|
|
| 151 | + GhcPs -> srcTxt
|
|
| 152 | + GhcRn -> XInlinePragmaGhc srcTxt ArityNotExplicit
|
|
| 153 | + GhcTc -> XInlinePragmaGhc srcTxt ArityNotExplicit
|
|
| 154 | + in InlinePragma
|
|
| 155 | + { inl_ext = inlExt
|
|
| 156 | + , inl_act = AlwaysActive
|
|
| 157 | + , inl_rule = FunLike
|
|
| 158 | + , inl_inline = NoUserInlinePrag }
|
|
| 159 | + |
|
| 160 | +-- | The default 'InlinePragma' definition for the "parser pass" of GHC.
|
|
| 161 | +alwaysInlinePragma, neverInlinePragma, alwaysInlineConLikePragma, dfunInlinePragma
|
|
| 162 | + :: forall p. IsPass p => InlinePragma (GhcPass p)
|
|
| 163 | + |
|
| 164 | + |
|
| 165 | +alwaysInlinePragma = (defaultInlinePragma @p) { inl_inline = Inline }
|
|
| 166 | +neverInlinePragma = (defaultInlinePragma @p) { inl_act = NeverActive }
|
|
| 167 | +alwaysInlineConLikePragma = (alwaysInlinePragma @p) { inl_rule = ConLike }
|
|
| 143 | 168 | |
| 144 | 169 | -- A DFun has an always-active inline activation so that
|
| 145 | 170 | -- exprIsConApp_maybe can "see" its unfolding
|
| 146 | 171 | -- (However, its actual Unfolding is a DFunUnfolding, which is
|
| 147 | 172 | -- never inlined other than via exprIsConApp_maybe.)
|
| 148 | -dfunInlinePragma = defaultInlinePragma { inl_act = AlwaysActive
|
|
| 149 | - , inl_rule = ConLike }
|
|
| 173 | +dfunInlinePragma = (defaultInlinePragma @p) { inl_act = AlwaysActive
|
|
| 174 | + , inl_rule = ConLike }
|
|
| 150 | 175 | |
| 151 | 176 | isDefaultInlinePragma :: InlinePragma p -> Bool
|
| 152 | 177 | isDefaultInlinePragma (XInlinePragma _) = False
|
| ... | ... | @@ -155,28 +180,38 @@ isDefaultInlinePragma (InlinePragma { inl_act = activation |
| 155 | 180 | , inl_inline = inline })
|
| 156 | 181 | = noUserInlineSpec inline && isAlwaysActive activation && isFunLike match_info
|
| 157 | 182 | |
| 158 | -setInlinePragmaArity :: forall p q. (IsPass p, XInlinePragma (GhcPass q) ~ InlinePragmaGhcTag)
|
|
| 159 | - => InlinePragma (GhcPass p) -> Arity -> InlinePragma (GhcPass q)
|
|
| 183 | +setInlinePragmaArity :: forall p q. (IsPass p, XInlinePragma (GhcPass q) ~ XInlinePragmaGhc)
|
|
| 184 | + => InlinePragma (GhcPass p) -> InlineArity -> InlinePragma (GhcPass q)
|
|
| 160 | 185 | setInlinePragmaArity prag arity =
|
| 161 | - prag { inl_ext = InlinePragmaGhcTag (inlinePragmaSource prag) arity }
|
|
| 186 | + prag { inl_ext = XInlinePragmaGhc (inlinePragmaSource prag) arity }
|
|
| 187 | + |
|
| 188 | +setInlinePragmaArityAsExplicitly :: forall a p q. (Integral a, IsPass p, XInlinePragma (GhcPass q) ~ XInlinePragmaGhc)
|
|
| 189 | + => InlinePragma (GhcPass p) -> a -> InlinePragma (GhcPass q)
|
|
| 190 | +setInlinePragmaArityAsExplicitly prag intVal = prag `setInlinePragmaArity` arity
|
|
| 191 | + where
|
|
| 192 | + arity = ArityExplicitly . fromIntegral $ abs intVal
|
|
| 162 | 193 | |
| 163 | -unsetInlinePragmaArity :: forall p. IsPass p => InlinePragma (GhcPass p) -> InlinePragma GhcPs
|
|
| 164 | -unsetInlinePragmaArity prag =
|
|
| 165 | - prag { inl_ext = inlinePragmaSource prag }
|
|
| 194 | +setInlinePragmaArityAsNotExplicit :: forall p q. (IsPass p, XInlinePragma (GhcPass q) ~ XInlinePragmaGhc)
|
|
| 195 | + => InlinePragma (GhcPass p) -> InlinePragma (GhcPass q)
|
|
| 196 | +setInlinePragmaArityAsNotExplicit = flip setInlinePragmaArity ArityNotExplicit
|
|
| 166 | 197 | |
| 167 | 198 | inlinePragmaSource :: forall p. IsPass p => InlinePragma (GhcPass p) -> SourceText
|
| 168 | 199 | inlinePragmaSource (InlinePragma { inl_ext = src }) = srcTxt
|
| 169 | 200 | where
|
| 170 | 201 | srcTxt = case ghcPass @p of
|
| 171 | 202 | GhcPs -> src
|
| 172 | - GhcRn -> inl_ghcrn_src src
|
|
| 173 | - GhcTc -> inl_ghcrn_src src
|
|
| 203 | + GhcRn -> xinl_src src
|
|
| 204 | + GhcTc -> xinl_src src
|
|
| 205 | + |
|
| 206 | +inlinePragmaArity :: forall p. (XInlinePragma (GhcPass p) ~ XInlinePragmaGhc)
|
|
| 207 | + => InlinePragma (GhcPass p) -> InlineArity
|
|
| 208 | +inlinePragmaArity = xinl_sat . inl_ext
|
|
| 174 | 209 | |
| 175 | 210 | promoteInlinePragmaRn :: InlinePragma GhcRn -> InlinePragma GhcTc
|
| 176 | 211 | promoteInlinePragmaRn prag@(InlinePragma { inl_ext = src }) = prag { inl_ext = src }
|
| 177 | 212 | |
| 178 | -demoteInlinePragmaRn :: InlinePragma GhcTc -> InlinePragma GhcRn
|
|
| 179 | -demoteInlinePragmaRn prag@(InlinePragma { inl_ext = src }) = prag { inl_ext = src }
|
|
| 213 | +demoteInlinePragmaTc :: InlinePragma GhcTc -> InlinePragma GhcRn
|
|
| 214 | +demoteInlinePragmaTc prag@(InlinePragma { inl_ext = src }) = prag { inl_ext = src }
|
|
| 180 | 215 | |
| 181 | 216 | inlinePragmaSpec :: InlinePragma p -> InlineSpec
|
| 182 | 217 | inlinePragmaSpec = inl_inline
|
| ... | ... | @@ -187,8 +222,18 @@ inlinePragmaActivation (InlinePragma { inl_act = activation }) = activation |
| 187 | 222 | inlinePragmaRuleMatchInfo :: InlinePragma (GhcPass p) -> RuleMatchInfo
|
| 188 | 223 | inlinePragmaRuleMatchInfo (InlinePragma { inl_rule = info }) = info
|
| 189 | 224 | |
| 190 | -setInlinePragmaTag :: InlinePragma (GhcPass p) -> XInlinePragma (GhcPass q) -> InlinePragma (GhcPass q)
|
|
| 191 | -setInlinePragmaTag prag tag = prag { inl_ext = tag }
|
|
| 225 | +setInlinePragmaSource :: forall p. IsPass p
|
|
| 226 | + => InlinePragma (GhcPass p) -> SourceText -> InlinePragma (GhcPass p)
|
|
| 227 | +setInlinePragmaSource prag srcTxt = prag { inl_ext = newExt }
|
|
| 228 | + where
|
|
| 229 | + oldExt = inl_ext prag
|
|
| 230 | + newExt = case ghcPass @p of
|
|
| 231 | + GhcPs -> srcTxt
|
|
| 232 | + GhcRn -> oldExt { xinl_src = srcTxt }
|
|
| 233 | + GhcTc -> oldExt { xinl_src = srcTxt }
|
|
| 234 | + |
|
| 235 | +setInlinePragmaSpec :: InlinePragma (GhcPass p) -> InlineSpec -> InlinePragma (GhcPass p)
|
|
| 236 | +setInlinePragmaSpec prag spec = prag { inl_inline = spec }
|
|
| 192 | 237 | |
| 193 | 238 | setInlinePragmaActivation :: InlinePragma (GhcPass p) -> Activation -> InlinePragma (GhcPass p)
|
| 194 | 239 | setInlinePragmaActivation prag activation = prag { inl_act = activation }
|
| ... | ... | @@ -360,15 +405,15 @@ no harm. |
| 360 | 405 | modules once TTG has progressed and the Language.Haskell.Syntax.Types module
|
| 361 | 406 | no longer depends on importing GHC.Hs.Doc.
|
| 362 | 407 | -}
|
| 363 | -instance Binary InlinePragmaGhcTag where
|
|
| 364 | - put_ bh (InlinePragmaGhcTag s a) = do
|
|
| 408 | +instance Binary XInlinePragmaGhc where
|
|
| 409 | + put_ bh (XInlinePragmaGhc s a) = do
|
|
| 365 | 410 | put_ bh s
|
| 366 | 411 | put_ bh a
|
| 367 | 412 | |
| 368 | 413 | get bh = do
|
| 369 | 414 | s <- get bh
|
| 370 | 415 | a <- get bh
|
| 371 | - return (InlinePragmaGhcTag s a)
|
|
| 416 | + return (XInlinePragmaGhc s a)
|
|
| 372 | 417 | |
| 373 | 418 | instance forall p. IsPass p => Binary (InlinePragma (GhcPass p)) where
|
| 374 | 419 | put_ bh (InlinePragma s a b c) = do
|
| ... | ... | @@ -125,6 +125,7 @@ import GHC.Data.FastString |
| 125 | 125 | import GHC.Data.TrieMap
|
| 126 | 126 | import GHC.Utils.Exception
|
| 127 | 127 | import GHC.Utils.Panic.Plain
|
| 128 | +import GHC.Types.Arity (InlineArity(..))
|
|
| 128 | 129 | import GHC.Types.Unique.FM
|
| 129 | 130 | import GHC.Data.FastMutInt
|
| 130 | 131 | import GHC.Utils.Fingerprint
|
| ... | ... | @@ -2064,28 +2065,21 @@ instance Binary FFIType where |
| 2064 | 2065 | FFIUInt64 -> 11
|
| 2065 | 2066 | |
| 2066 | 2067 | instance Binary Activation where
|
| 2067 | - put_ bh NeverActive =
|
|
| 2068 | - putByte bh 0
|
|
| 2069 | - put_ bh FinalActive = do
|
|
| 2070 | - putByte bh 1
|
|
| 2071 | - put_ bh AlwaysActive =
|
|
| 2072 | - putByte bh 2
|
|
| 2073 | - put_ bh (ActiveBefore aa) = do
|
|
| 2074 | - putByte bh 3
|
|
| 2075 | - put_ bh aa
|
|
| 2076 | - put_ bh (ActiveAfter ab) = do
|
|
| 2077 | - putByte bh 4
|
|
| 2078 | - put_ bh ab
|
|
| 2068 | + put_ bh = \case
|
|
| 2069 | + NeverActive -> putByte bh 0
|
|
| 2070 | + FinalActive -> putByte bh 1
|
|
| 2071 | + AlwaysActive -> putByte bh 2
|
|
| 2072 | + ActiveBefore aa -> putByte bh 3 *> put_ bh aa
|
|
| 2073 | + ActiveAfter ab -> putByte bh 4 *> put_ bh ab
|
|
| 2074 | + |
|
| 2079 | 2075 | get bh = do
|
| 2080 | - h <- getByte bh
|
|
| 2081 | - case h of
|
|
| 2082 | - 0 -> return NeverActive
|
|
| 2083 | - 1 -> return FinalActive
|
|
| 2084 | - 2 -> return AlwaysActive
|
|
| 2085 | - 3 -> do aa <- get bh
|
|
| 2086 | - return (ActiveBefore aa)
|
|
| 2087 | - _ -> do ab <- get bh
|
|
| 2088 | - return (ActiveAfter ab)
|
|
| 2076 | + h <- getByte bh
|
|
| 2077 | + case h of
|
|
| 2078 | + 0 -> pure NeverActive
|
|
| 2079 | + 1 -> pure FinalActive
|
|
| 2080 | + 2 -> pure AlwaysActive
|
|
| 2081 | + 3 -> ActiveBefore <$> get bh
|
|
| 2082 | + _ -> ActiveAfter <$> get bh
|
|
| 2089 | 2083 | |
| 2090 | 2084 | instance Binary InlineSpec where
|
| 2091 | 2085 | put_ bh = putByte bh . \case
|
| ... | ... | @@ -2095,18 +2089,29 @@ instance Binary InlineSpec where |
| 2095 | 2089 | NoInline -> 3
|
| 2096 | 2090 | Opaque -> 4
|
| 2097 | 2091 | |
| 2098 | - get bh = do h <- getByte bh
|
|
| 2099 | - return $ case h of
|
|
| 2100 | - 0 -> NoUserInlinePrag
|
|
| 2101 | - 1 -> Inline
|
|
| 2102 | - 2 -> Inlinable
|
|
| 2103 | - 3 -> NoInline
|
|
| 2104 | - _ -> Opaque
|
|
| 2092 | + get bh = do
|
|
| 2093 | + h <- getByte bh
|
|
| 2094 | + return $ case h of
|
|
| 2095 | + 0 -> NoUserInlinePrag
|
|
| 2096 | + 1 -> Inline
|
|
| 2097 | + 2 -> Inlinable
|
|
| 2098 | + 3 -> NoInline
|
|
| 2099 | + _ -> Opaque
|
|
| 2105 | 2100 | |
| 2106 | 2101 | instance Binary RuleMatchInfo where
|
| 2107 | 2102 | put_ bh FunLike = putByte bh 0
|
| 2108 | 2103 | put_ bh ConLike = putByte bh 1
|
| 2104 | + |
|
| 2105 | + get bh = do
|
|
| 2106 | + h <- getByte bh
|
|
| 2107 | + if h == 1 then pure ConLike
|
|
| 2108 | + else pure FunLike
|
|
| 2109 | + |
|
| 2110 | +instance Binary InlineArity where
|
|
| 2111 | + put_ bh ArityNotExplicit = putByte bh 0
|
|
| 2112 | + put_ bh (ArityExplicitly w) = putByte bh 1 *> put_ bh w
|
|
| 2113 | + |
|
| 2109 | 2114 | get bh = do
|
| 2110 | - h <- getByte bh
|
|
| 2111 | - if h == 1 then return ConLike
|
|
| 2112 | - else return FunLike |
|
| 2115 | + h <- getByte bh
|
|
| 2116 | + if h == 0 then pure ArityNotExplicit
|
|
| 2117 | + else ArityExplicitly <$> get bh |
| ... | ... | @@ -112,6 +112,7 @@ module GHC.Utils.Outputable ( |
| 112 | 112 | ) where
|
| 113 | 113 | |
| 114 | 114 | import Language.Haskell.Syntax.Binds.InlinePragma
|
| 115 | +import Language.Haskell.Syntax.Extension ( dataConCantHappen )
|
|
| 115 | 116 | import Language.Haskell.Syntax.Module.Name ( ModuleName(..) )
|
| 116 | 117 | |
| 117 | 118 | import {-# SOURCE #-} GHC.Hs.Extension
|
| ... | ... | @@ -2025,7 +2026,15 @@ pprInlineDebug = pprInline' False |
| 2025 | 2026 | pprInline' :: Bool -- True <=> do not display the inl_inline field
|
| 2026 | 2027 | -> InlinePragma (GhcPass p)
|
| 2027 | 2028 | -> SDoc
|
| 2028 | -pprInline' _ (XInlinePragma ext) = dataConCantHappen ext
|
|
| 2029 | +-- TODO: Revise this definition for XInlinePragma constructor.
|
|
| 2030 | +-- The proper defintion is:
|
|
| 2031 | +-- > pprInline' _ (XInlinePragma ext) = dataConCantHappen ext
|
|
| 2032 | +-- We cannot add this proper definition until this module imports
|
|
| 2033 | +-- 'GHC.Types.InlinePragma', instead of the other way around.
|
|
| 2034 | +-- Until then, the type family definition of XInlinePragma (GhcPass _)
|
|
| 2035 | +-- will not be in scope and the type-checker cannot determine that
|
|
| 2036 | +-- the binding 'ext' is in fact a 'DataConCantHappen' value.
|
|
| 2037 | +pprInline' _ (XInlinePragma ext) = error "XInlinePragma = dataConCantHappen"
|
|
| 2029 | 2038 | pprInline' emptyInline (InlinePragma
|
| 2030 | 2039 | { inl_inline = inline,
|
| 2031 | 2040 | inl_act = activation,
|