Reduce seqId magic
In MkId.hs
we see
Note [seqId magic]
~~~~~~~~~~~~~~~~~~
'GHC.Prim.seq' is special in several ways.
a) In source Haskell its second arg can have an unboxed type
x `seq` (v +# w)
But see Note [Typing rule for seq] in TcExpr, which
explains why we give seq itself an ordinary type
seq :: forall a b. a -> b -> b
and treat it as a language construct from a typing point of view.
But nowadays we can handle (a) via levity polymorphism. So we should make its (still wired in) type be
seq :: forall {r::RuntimeRep} (a :: TYPE LiftedRep) (b :: TYPE r). a -> b -> b
Less magic!
Second point. In MkId we see
info = noCafIdInfo `setInlinePragInfo` alwaysInlinePragma
`setUnfoldingInfo` mkCompulsoryUnfolding rhs
Why do we need that alwaysInlinePragma
? After all, the Mighty Simplifier always inlines compulsory things:
activeUnfolding mode id
| isCompulsoryUnfolding (realIdUnfolding id)
= True -- Even sm_inline can't override compulsory unfoldings
But, strangely, the Very Simple Optimiser does not:
simple_app env (Var v) as
...
| let unf = idUnfolding v
, isCompulsoryUnfolding (idUnfolding v)
, isAlwaysActive (idInlineActivation v)
-- See Note [Unfold compulsory unfoldings in LHSs]
= simple_app (soeZapSubst env) (unfoldingTemplate unf) as
So it is a bit less gung-ho about inlining compulsory unfoldings. Why?
The sole reasons is that simpleOptExpr
is applied to the entire LHS of a rule (DsBinds)
where
lhs1 = drop_dicts orig_lhs
lhs2 = simpleOptExpr dflags lhs1 -- See Note [Simplify rule LHS]
(fun2,args2) = collectArgs lhs2
and we don't want to inline seq
here even though it has a compulsory unfolding: see Note [User-defined RULES for seq]
. Gah!
Decision: let's narrow the special case in simple_app
to focus just on seq
, with a suitable pointer:
simple_app env (Var v) as
...
| let unf = idUnfolding v
, isCompulsoryUnfolding (idUnfolding v)
, v `hasKey` seqIdKey -- See Note XXXXX
And then get rid of the inline-pragma stuff on wired-in Ids with compulsory unfoldings.