Commit 15d2340c authored by Simon Peyton Jones's avatar Simon Peyton Jones Committed by Marge Bot

Fix some missed opportunities for preInlineUnconditionally

There are two signficant changes here:

* Ticket #18815 showed that we were missing some opportunities for
  preInlineUnconditionally.  The one-line fix is in the code for
  GHC.Core.Opt.Simplify.Utils.preInlineUnconditionally, which now
  switches off only for INLINE pragmas.  I expanded
  Note [Stable unfoldings and preInlineUnconditionally] to explain.

* When doing this I discovered a way in which preInlineUnconditionally
  was occasionally /too/ eager.  It's all explained in
  Note [Occurrences in stable unfoldings] in GHC.Core.Opt.OccurAnal,
  and the one-line change adding markAllMany to occAnalUnfolding.

I also got confused about what NoUserInline meant, so I've renamed
it to NoUserInlinePrag, and changed its pretty-printing slightly.
That led to soem error messate wibbling, and touches quite a few
files, but there is no change in functionality.

I did a nofib run.  As expected, no significant changes.

        Program           Size    Allocs
----------------------------------------
         sphere          -0.0%     -0.4%
----------------------------------------
            Min          -0.0%     -0.4%
            Max          -0.0%     +0.0%
 Geometric Mean          -0.0%     -0.0%

I'm allowing a max-residency increase for T10370, which seems
very irreproducible. (See comments on !4241.)  There is always
sampling error for max-residency measurements; and in any case
the change shows up on some platforms but not others.

Metric Increase:
    T10370
parent e60ae8a3
Pipeline #26312 passed with stages
in 351 minutes and 32 seconds
......@@ -1693,14 +1693,16 @@ occAnalUnfolding :: OccEnv
occAnalUnfolding env is_rec mb_join_arity unf
= case unf of
unf@(CoreUnfolding { uf_tmpl = rhs, uf_src = src })
| isStableSource src -> (usage, unf')
| otherwise -> (emptyDetails, unf)
where -- For non-Stable unfoldings we leave them undisturbed, but
| isStableSource src -> (markAllMany usage, unf')
-- markAllMany: see Note [Occurrences in stable unfoldings]
| otherwise -> (emptyDetails, unf)
-- For non-Stable unfoldings we leave them undisturbed, but
-- don't count their usage because the simplifier will discard them.
-- We leave them undisturbed because nodeScore uses their size info
-- to guide its decisions. It's ok to leave un-substituted
-- expressions in the tree because all the variables that were in
-- scope remain in scope; there is no cloning etc.
where
(usage, rhs') = occAnalRhs env is_rec mb_join_arity rhs
unf' | noBinderSwaps env = unf -- Note [Unfoldings and rules]
......@@ -1759,6 +1761,28 @@ the FloatIn pass knows to float into join point RHSs; and the simplifier
does not float things out of join point RHSs. But it's a simple, cheap
thing to do. See #14137.
Note [Occurrences in stable unfoldings]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
f p = BIG
{-# INLINE g #-}
g y = not (f y)
where this is the /only/ occurrence of 'f'. So 'g' will get a stable
unfolding. Now suppose that g's RHS gets optimised (perhaps by a rule
or inlining f) so that it doesn't mention 'f' any more. Now the last
remaining call to f is in g's Stable unfolding. But, even though there
is only one syntactic occurrence of f, we do /not/ want to do
preinlineUnconditionally here!
The INLINE pragma says "inline exactly this RHS"; perhaps the
programmer wants to expose that 'not', say. If we inline f that will make
the Stable unfoldign big, and that wasn't what the programmer wanted.
Another way to think about it: if we inlined g as-is into multiple
call sites, now there's be multiple calls to f.
Bottom line: treat all occurrences in a stable unfolding as "Many".
Note [Unfoldings and rules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generally unfoldings and rules are already occurrence-analysed, so we
......
......@@ -549,7 +549,7 @@ mkCastWrapperInlinePrag :: InlinePragma -> InlinePragma
-- See Note [Cast wrappers]
mkCastWrapperInlinePrag (InlinePragma { inl_act = act, inl_rule = rule_info })
= InlinePragma { inl_src = SourceText "{-# INLINE"
, inl_inline = NoUserInline -- See Note [Wrapper NoUserInline]
, inl_inline = NoUserInlinePrag -- See Note [Wrapper NoUserInline]
, inl_sat = Nothing -- in GHC.Core.Opt.WorkWrap
, inl_act = wrap_act -- See Note [Wrapper activation]
, inl_rule = rule_info } -- in GHC.Core.Opt.WorkWrap
......
......@@ -1190,7 +1190,7 @@ However, as usual for Gentle mode, do not inline things that are
inactive in the initial stages. See Note [Gentle mode].
Note [Stable unfoldings and preInlineUnconditionally]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Surprisingly, do not pre-inline-unconditionally Ids with INLINE pragmas!
Example
......@@ -1210,10 +1210,18 @@ the application is saturated for exactly this reason; and we don't
want PreInlineUnconditionally to second-guess it. A live example is #3736.
c.f. Note [Stable unfoldings and postInlineUnconditionally]
NB: if the pragma is INLINEABLE, then we don't want to behave in
this special way -- an INLINEABLE pragma just says to GHC "inline this
if you like". But if there is a unique occurrence, we want to inline
the stable unfolding, not the RHS.
NB: this only applies for INLINE things. Do /not/ switch off
preInlineUnconditionally for
* INLINABLE. It just says to GHC "inline this if you like". If there
is a unique occurrence, we want to inline the stable unfolding, not
the RHS.
* NONLINE[n] just switches off inlining until phase n. We should
respect that, but after phase n, just behave as usual.
* NoUserInlinePrag. There is no pragma at all. This ends up on wrappers.
(See #18815.)
Note [Top-level bottoming Ids]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......@@ -1247,7 +1255,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env
| not (isStableUnfolding unf) = Just (extend_subst_with rhs)
-- Note [Stable unfoldings and preInlineUnconditionally]
| isInlinablePragma inline_prag
| not (isInlinePragma inline_prag)
, Just inl <- maybeUnfoldingTemplate unf = Just (extend_subst_with inl)
| otherwise = Nothing
where
......
......@@ -1524,7 +1524,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
-- See Note [Specialising imported functions] in "GHC.Core.Opt.OccurAnal"
| InlinePragma { inl_inline = Inlinable } <- inl_prag
= (inl_prag { inl_inline = NoUserInline }, noUnfolding)
= (inl_prag { inl_inline = NoUserInlinePrag }, noUnfolding)
| otherwise
= (inl_prag, specUnfolding simpl_opts spec_bndrs (`mkApps` spec_args)
......
......@@ -446,13 +446,19 @@ Conclusion:
- Otherwise inline wrapper in phase 2. That allows the
'gentle' simplification pass to apply specialisation rules
Note [Wrapper NoUserInline]
Note [Wrapper NoUserInlinePrag]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The use an inl_inline of NoUserInline on the wrapper distinguishes
this pragma from one that was given by the user. In particular, CSE
will not happen if there is a user-specified pragma, but should happen
for w/w’ed things (#14186).
We use NoUserInlinePrag on the wrapper, to say that there is no
user-specified inline pragma. (The worker inherits that; see Note
[Worker-wrapper for INLINABLE functions].) The wrapper has no pragma
given by the user.
(Historical note: we used to give the wrapper an INLINE pragma, but
CSE will not happen if there is a user-specified pragma, but should
happen for w/w’ed things (#14186). We don't need a pragma, because
everything we needs is expressed by (a) the stable unfolding and (b)
the inl_act activation.)
-}
tryWW :: DynFlags
......@@ -678,7 +684,7 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs
mkStrWrapperInlinePrag :: InlinePragma -> InlinePragma
mkStrWrapperInlinePrag (InlinePragma { inl_act = act, inl_rule = rule_info })
= InlinePragma { inl_src = SourceText "{-# INLINE"
, inl_inline = NoUserInline -- See Note [Wrapper NoUserInline]
, inl_inline = NoUserInlinePrag -- See Note [Wrapper NoUserInline]
, inl_sat = Nothing
, inl_act = wrap_act
, inl_rule = rule_info } -- RuleMatchInfo is (and must be) unaffected
......
......@@ -1160,8 +1160,8 @@ ppr_sig (SpecSig _ var ty inl@(InlinePragma { inl_inline = spec }))
(interpp'SP ty) inl)
where
pragmaSrc = case spec of
NoUserInline -> "{-# SPECIALISE"
_ -> "{-# SPECIALISE_INLINE"
NoUserInlinePrag -> "{-# SPECIALISE"
_ -> "{-# SPECIALISE_INLINE"
ppr_sig (InlineSig _ var inl)
= pragSrcBrackets (inl_src inl) "{-# INLINE" (pprInline inl
<+> pprPrefixOcc (unLoc var))
......
......@@ -384,10 +384,10 @@ makeCorePair dflags gbl_id is_default_method dict_arity rhs
| otherwise
= case inlinePragmaSpec inline_prag of
NoUserInline -> (gbl_id, rhs)
NoInline -> (gbl_id, rhs)
Inlinable -> (gbl_id `setIdUnfolding` inlinable_unf, rhs)
Inline -> inline_pair
NoUserInlinePrag -> (gbl_id, rhs)
NoInline -> (gbl_id, rhs)
Inlinable -> (gbl_id `setIdUnfolding` inlinable_unf, rhs)
Inline -> inline_pair
where
simpl_opts = initSimpleOpts dflags
......
......@@ -1108,10 +1108,10 @@ rep_specialiseInst ty loc
; return [(loc, pragma)] }
repInline :: InlineSpec -> MetaM (Core TH.Inline)
repInline NoInline = dataCon noInlineDataConName
repInline Inline = dataCon inlineDataConName
repInline Inlinable = dataCon inlinableDataConName
repInline NoUserInline = notHandled "NOUSERINLINE" empty
repInline NoInline = dataCon noInlineDataConName
repInline Inline = dataCon inlineDataConName
repInline Inlinable = dataCon inlinableDataConName
repInline NoUserInlinePrag = notHandled "NOUSERINLINE" empty
repRuleMatch :: RuleMatchInfo -> MetaM (Core TH.RuleMatch)
repRuleMatch ConLike = dataCon conLikeDataConName
......
......@@ -2513,7 +2513,7 @@ sigdecl :: { LHsDecl GhcPs }
| '{-# SPECIALISE' activation qvar '::' sigtypes1 '#-}'
{% ams (
let inl_prag = mkInlinePragma (getSPEC_PRAGs $1)
(NoUserInline, FunLike) (snd $2)
(NoUserInlinePrag, FunLike) (snd $2)
in sLL $1 $> $ SigD noExtField (SpecSig noExtField $3 (fromOL $5) inl_prag))
(mo $1:mu AnnDcolon $4:mc $6:(fst $2)) }
......
......@@ -761,7 +761,7 @@ cvtPragmaD (SpecialiseP nm ty inline phases)
; let (inline', dflt,srcText) = case inline of
Just inline1 -> (cvtInline inline1, dfltActivation inline1,
src inline1)
Nothing -> (NoUserInline, AlwaysActive,
Nothing -> (NoUserInlinePrag, AlwaysActive,
"{-# SPECIALISE")
; let ip = InlinePragma { inl_src = SourceText srcText
, inl_inline = inline'
......
......@@ -1467,11 +1467,11 @@ data RuleMatchInfo = ConLike -- See Note [CONLIKE pragma]
-- | Inline Specification
data InlineSpec -- What the user's INLINE pragma looked like
= Inline -- User wrote INLINE
| Inlinable -- User wrote INLINABLE
| NoInline -- User wrote NOINLINE
| NoUserInline -- User did not write any of INLINE/INLINABLE/NOINLINE
-- e.g. in `defaultInlinePragma` or when created by CSE
= Inline -- User wrote INLINE
| Inlinable -- User wrote INLINABLE
| NoInline -- User wrote NOINLINE
| NoUserInlinePrag -- User did not write any of INLINE/INLINABLE/NOINLINE
-- e.g. in `defaultInlinePragma` or when created by CSE
deriving( Eq, Data, Show )
-- Show needed for GHC.Parser.Lexer
......@@ -1481,7 +1481,7 @@ This data type mirrors what you can write in an INLINE or NOINLINE pragma in
the source program.
If you write nothing at all, you get defaultInlinePragma:
inl_inline = NoUserInline
inl_inline = NoUserInlinePrag
inl_act = AlwaysActive
inl_rule = FunLike
......@@ -1555,15 +1555,15 @@ isFunLike FunLike = True
isFunLike _ = False
noUserInlineSpec :: InlineSpec -> Bool
noUserInlineSpec NoUserInline = True
noUserInlineSpec _ = False
noUserInlineSpec NoUserInlinePrag = True
noUserInlineSpec _ = False
defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma
:: InlinePragma
defaultInlinePragma = InlinePragma { inl_src = SourceText "{-# INLINE"
, inl_act = AlwaysActive
, inl_rule = FunLike
, inl_inline = NoUserInline
, inl_inline = NoUserInlinePrag
, inl_sat = Nothing }
alwaysInlinePragma = defaultInlinePragma { inl_inline = Inline }
......@@ -1629,10 +1629,10 @@ instance Outputable RuleMatchInfo where
ppr FunLike = text "FUNLIKE"
instance Outputable InlineSpec where
ppr Inline = text "INLINE"
ppr NoInline = text "NOINLINE"
ppr Inlinable = text "INLINABLE"
ppr NoUserInline = text "NOUSERINLINE" -- what is better?
ppr Inline = text "INLINE"
ppr NoInline = text "NOINLINE"
ppr Inlinable = text "INLINABLE"
ppr NoUserInlinePrag = empty
instance Outputable InlinePragma where
ppr = pprInline
......
......@@ -1311,14 +1311,14 @@ instance Binary RuleMatchInfo where
else return FunLike
instance Binary InlineSpec where
put_ bh NoUserInline = putByte bh 0
put_ bh Inline = putByte bh 1
put_ bh Inlinable = putByte bh 2
put_ bh NoInline = putByte bh 3
put_ bh NoUserInlinePrag = putByte bh 0
put_ bh Inline = putByte bh 1
put_ bh Inlinable = putByte bh 2
put_ bh NoInline = putByte bh 3
get bh = do h <- getByte bh
case h of
0 -> return NoUserInline
0 -> return NoUserInlinePrag
1 -> return Inline
2 -> return Inlinable
_ -> return NoInline
......
......@@ -20,7 +20,7 @@ DATA CONSTRUCTORS
K2 :: forall a. a -> T2 a
K1 :: forall a. a -> T1 a
Dependent modules: []
Dependent packages: [base-4.14.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
Dependent packages: [base-4.15.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
==================== Typechecker ====================
Roles1.$tcT7
......@@ -79,37 +79,36 @@ Roles1.$tc'K1
= GHC.Types.TyCon
1265606750138351672## 7033043930969109074## Roles1.$trModule
(GHC.Types.TrNameS "'K1"#) 1 $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 2
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepApp $krep $krep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 2
$krep [InlPrag=[~]] = GHC.Types.KindRepApp $krep $krep
$krep [InlPrag=[~]]
= GHC.Types.KindRepFun $krep GHC.Types.krep$*Arr*
$krep [InlPrag=NOUSERINLINE[~]]
= GHC.Types.KindRepFun $krep GHC.Types.krep$*
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep GHC.Types.krep$*
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]]
= GHC.Types.KindRepFun GHC.Types.krep$*Arr* GHC.Types.krep$*Arr*
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
Roles1.$tcT7 ((:) $krep ((:) $krep ((:) $krep [])))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles1.$tcT6 ((:) $krep ((:) $krep []))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles1.$tcT4 ((:) $krep ((:) $krep []))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles1.$tcT3 ((:) $krep ((:) $krep []))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles1.$tcT5 ((:) $krep [])
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles1.$tcT2 ((:) $krep [])
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles1.$tcT1 ((:) $krep [])
Roles1.$trModule
= GHC.Types.Module
......
......@@ -6,7 +6,7 @@ TYPE CONSTRUCTORS
COERCION AXIOMS
axiom Roles12.N:C2 :: C2 a = a -> a
Dependent modules: []
Dependent packages: [base-4.14.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
Dependent packages: [base-4.15.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
==================== Typechecker ====================
Roles12.$tcC2
......@@ -17,14 +17,13 @@ Roles12.$tc'C:C2
= GHC.Types.TyCon
7087988437584478859## 11477953550142401435## Roles12.$trModule
(GHC.Types.TrNameS "'C:C2"#) 1 $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]]
= GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp GHC.Types.$tcConstraint []
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles12.$tcC2 ((:) $krep [])
Roles12.$trModule
= GHC.Types.Module
......
......@@ -6,7 +6,7 @@ DATA CONSTRUCTORS
K2 :: forall a. FunPtr a -> T2 a
K1 :: forall a. IO a -> T1 a
Dependent modules: []
Dependent packages: [base-4.14.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
Dependent packages: [base-4.15.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
==================== Typechecker ====================
Roles2.$tcT2
......@@ -25,16 +25,16 @@ Roles2.$tc'K1
= GHC.Types.TyCon
16530009231990968394## 11761390951471299534## Roles2.$trModule
(GHC.Types.TrNameS "'K1"#) 1 $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp GHC.Ptr.$tcFunPtr ((:) $krep [])
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles2.$tcT2 ((:) $krep [])
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp GHC.Types.$tcIO ((:) $krep [])
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles2.$tcT1 ((:) $krep [])
Roles2.$trModule
= GHC.Types.Module
......
......@@ -21,7 +21,7 @@ COERCION AXIOMS
axiom Roles3.N:C3 :: C3 a b = a -> F3 b -> F3 b
axiom Roles3.N:C4 :: C4 a b = a -> F4 b -> F4 b
Dependent modules: []
Dependent packages: [base-4.14.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
Dependent packages: [base-4.15.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
==================== Typechecker ====================
Roles3.$tcC4
......@@ -48,25 +48,23 @@ Roles3.$tc'C:C1
= GHC.Types.TyCon
4508088879886988796## 13962145553903222779## Roles3.$trModule
(GHC.Types.TrNameS "'C:C1"#) 1 $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]]
= GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=NOUSERINLINE[~]]
= GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp GHC.Types.$tcConstraint []
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
GHC.Types.$tc~ ((:) GHC.Types.krep$* ((:) $krep ((:) $krep [])))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles3.$tcC2 ((:) $krep ((:) $krep []))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles3.$tcC1 ((:) $krep [])
Roles3.$trModule
= GHC.Types.Module
......
......@@ -9,7 +9,7 @@ COERCION AXIOMS
axiom Roles4.N:C1 :: C1 a = a -> a
axiom Roles4.N:C3 :: C3 a = a -> Syn1 a
Dependent modules: []
Dependent packages: [base-4.14.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
Dependent packages: [base-4.15.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
==================== Typechecker ====================
Roles4.$tcC3
......@@ -28,20 +28,19 @@ Roles4.$tc'C:C1
= GHC.Types.TyCon
3870707671502302648## 10631907186261837450## Roles4.$trModule
(GHC.Types.TrNameS "'C:C1"#) 1 $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]]
= GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp GHC.Types.$tc[] ((:) $krep [])
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp GHC.Types.$tcConstraint []
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles4.$tcC3 ((:) $krep [])
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp Roles4.$tcC1 ((:) $krep [])
Roles4.$trModule
= GHC.Types.Module
......
......@@ -16,7 +16,7 @@ CLASS INSTANCES
-- Defined at T8958.hs:10:10
instance [incoherent] Nominal a -- Defined at T8958.hs:7:10
Dependent modules: []
Dependent packages: [base-4.14.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
Dependent packages: [base-4.15.0.0, ghc-bignum-1.0, ghc-prim-0.7.0]
==================== Typechecker ====================
T8958.$tcMap
......@@ -43,33 +43,32 @@ T8958.$tc'C:Nominal
= GHC.Types.TyCon
10562260635335201742## 1215478186250709459## T8958.$trModule
(GHC.Types.TrNameS "'C:Nominal"#) 1 $krep
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=NOUSERINLINE[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=NOUSERINLINE[~]]
= GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 0
$krep [InlPrag=[~]] = GHC.Types.KindRepVar 1
$krep [InlPrag=[~]] = GHC.Types.KindRepFun $krep $krep
$krep [InlPrag=[~]] = GHC.Types.KindRepFun GHC.Types.krep$* $krep
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
GHC.Tuple.$tc(,)
((:) @GHC.Types.KindRep
$krep ((:) @GHC.Types.KindRep $krep [] @GHC.Types.KindRep))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
T8958.$tcMap
((:) @GHC.Types.KindRep
$krep ((:) @GHC.Types.KindRep $krep [] @GHC.Types.KindRep))
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
GHC.Types.$tc[]
((:) @GHC.Types.KindRep $krep [] @GHC.Types.KindRep)
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
GHC.Types.$tcConstraint [] @GHC.Types.KindRep
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
T8958.$tcRepresentational
((:) @GHC.Types.KindRep $krep [] @GHC.Types.KindRep)
$krep [InlPrag=NOUSERINLINE[~]]
$krep [InlPrag=[~]]
= GHC.Types.KindRepTyConApp
T8958.$tcNominal
((:) @GHC.Types.KindRep $krep [] @GHC.Types.KindRep)
......@@ -79,7 +78,7 @@ T8958.$trModule
AbsBinds [a] []
{Exports: [T8958.$fRepresentationala <= $dRepresentational
wrap: <>]
Exported types: T8958.$fRepresentationala [InlPrag=NOUSERINLINE CONLIKE]
Exported types: T8958.$fRepresentationala [InlPrag=CONLIKE]
:: forall a. Representational a
[LclIdX[DFunId],
Unf=DFun: \ (@a) -> T8958.C:Representational TYPE: a]
......@@ -88,7 +87,7 @@ AbsBinds [a] []
AbsBinds [a] []
{Exports: [T8958.$fNominala <= $dNominal
wrap: <>]
Exported types: T8958.$fNominala [InlPrag=NOUSERINLINE CONLIKE]
Exported types: T8958.$fNominala [InlPrag=CONLIKE]
:: forall a. Nominal a
[LclIdX[DFunId], Unf=DFun: \ (@a) -> T8958.C:Nominal TYPE: a]
Binds: $dNominal = T8958.C:Nominal @a
......
......@@ -2,6 +2,17 @@ TOP=../../..
include $(TOP)/mk/boilerplate.mk
include $(TOP)/mk/test.mk
# T18815 should not have a non-recursive join-point for 'go'
# Previously we ended up with
# join {go_sPI w_sQ3 = case w_sQ3 of { GHC.Types.I# ww1_sQ6 ->
# jump $wgo_sQ8 ww1_sQ6 } } in
# jump go_sPI x_atE
# With the bug fixed, go is inlined, so the 'join' vanishes
T18815:
$(RM) -f T18815.o T18815.hi
- '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl T18815.hs 2> /dev/null | grep 'join '
T17966:
$(RM) -f T17966.o T17966.hi
- '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-spec T17966.hs 2> /dev/null | grep 'SPEC'
......
......@@ -12,7 +12,7 @@ T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.(##)
end Rec }
-- RHS size: {terms: 4, types: 4, coercions: 0, joins: 0/0}
f [InlPrag=NOUSERINLINE[final]] :: forall a. Int -> a
f [InlPrag=[final]] :: forall a. Int -> a
[GblId,
Arity=1,
Str=<B,A>b,
......@@ -66,7 +66,7 @@ lvl = T13143.$wf @Int GHC.Prim.(##)
Rec {
-- RHS size: {terms: 28, types: 7, coercions: 0, joins: 0/0}
T13143.$wg [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
T13143.$wg [InlPrag=[2], Occ=LoopBreaker]
:: Bool -> Bool -> GHC.Prim.Int# -> GHC.Prim.Int#
[GblId, Arity=3, Str=<S,1*U><S,1*U><L,U>, Unf=OtherCon []]
T13143.$wg
......@@ -86,7 +86,7 @@ T13143.$wg
end Rec }
-- RHS size: {terms: 14, types: 6, coercions: 0, joins: 0/0}
g [InlPrag=NOUSERINLINE[2]] :: Bool -> Bool -> Int -> Int
g [InlPrag=[2]] :: Bool -> Bool -> Int -> Int
[GblId,
Arity=3,
Str=<S,1*U><S,1*U><S,1*U(U)>,
......
module T18815 where
loop :: Int -> Int -> (Int, ())
loop x y = go x
where
go x = if x > y then (x, ()) else go (x*2)
......@@ -41,7 +41,7 @@ T3717.$trModule
Rec {
-- RHS size: {terms: 10, types: 2, coercions: 0, joins: 0/0}
T3717.$wfoo [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
T3717.$wfoo [InlPrag=[2], Occ=LoopBreaker]
:: GHC.Prim.Int# -> GHC.Prim.Int#
[GblId, Arity=1, Str=<S,1*U>, Unf=OtherCon []]
T3717.$wfoo
......@@ -53,7 +53,7 @@ T3717.$wfoo
end Rec }
-- RHS size: {terms: 10, types: 4, coercions: 0, joins: 0/0}
foo [InlPrag=NOUSERINLINE[2]] :: Int -> Int
foo [InlPrag=[2]] :: Int -> Int
[GblId,
Arity=1,
Str=<S(S),1*U(1*U)>,
......
......@@ -62,7 +62,7 @@ T3772.$wfoo
}
-- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0}
foo [InlPrag=NOUSERINLINE[final]] :: Int -> ()
foo [InlPrag=[final]] :: Int -> ()
[GblId,
Arity=1,
Str=<S,1*U(U)>,
......
......@@ -56,7 +56,7 @@ T4908.f_$s$wf
end Rec }
-- RHS size: {terms: 24, types: 13, coercions: 0, joins: 0/0}
T4908.$wf [InlPrag=NOUSERINLINE[2]] :: Int# -> (Int, Int) -> Bool
T4908.$wf [InlPrag=[2]] :: Int# -> (Int, Int) -> Bool
[GblId,
Arity=2,
Str=<S,1*U><L,1*U(A,1*U(1*U))>,
......@@ -78,7 +78,7 @@ T4908.$wf
}
-- RHS size: {terms: 8, types: 6, coercions: 0, joins: 0/0}
f [InlPrag=NOUSERINLINE[2]] :: Int -> (Int, Int) -> Bool
f [InlPrag=[2]] :: Int -> (Int, Int) -> Bool
[GblId,
Arity=2,
Str=<S(S),1*U(1*U)><L,1*U(A,1*U(1*U))>,
......
......@@ -41,7 +41,7 @@ T4930.$trModule
Rec {
-- RHS size: {terms: 17, types: 3, coercions: 0, joins: 0/0}
T4930.$wfoo [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
T4930.$wfoo [InlPrag=[2], Occ=LoopBreaker]
:: GHC.Prim.Int# -> GHC.Prim.Int#
[GblId, Arity=1, Str=<L,U>, Unf=OtherCon []]
T4930.$wfoo
......@@ -53,7 +53,7 @@ T4930.$wfoo
end Rec }
-- RHS size: {terms: 10, types: 4, coercions: 0, joins: 0/0}
foo [InlPrag=NOUSERINLINE[2]] :: Int -> Int
foo [InlPrag=[2]] :: Int -> Int
[GblId,
Arity=1,
Str=<S,1*U(U)>,
......
......@@ -126,7 +126,7 @@ T7360.$tcFoo
GHC.Types.krep$*
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
T7360.$tc'Foo4 [InlPrag=NOUSERINLINE[~]] :: GHC.Types.KindRep
T7360.$tc'Foo4 [InlPrag=[~]] :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
T7360.$tc'Foo4
= GHC.Types.KindRepTyConApp
......@@ -189,7 +189,7 @@ T7360.$tc'Foo2
T7360.$tc'Foo4
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}