Improvements to DmdAnal and WorkWrap
This MR contains two commits: One that fixes #18971 (closed) and the other fixing #18982 (closed). The fix for the former is trivial, I'll focus for the fix on the latter.
#18982 (closed))
DmdAnal + WorkWrap: Unbox constructors with existentials (WorkWrap: Unbox constructors with existentials (#18982 (closed))
Consider
data Ex where
Ex :: e -> Int -> Ex
f :: Ex -> Int
f (Ex e n) = e `seq` n + 1
Worker/wrapper should build the following worker for f
:
$wf :: forall e. e -> Int# -> Int#
$wf e n = e `seq` n +# 1#
But previously it didn't, because Ex
binds an existential.
This patch lifts that condition. That entailed having to instantiate
existential binders in GHC.Core.Opt.WorkWrap.Utils.mkWWstr
via
GHC.Core.Utils.dataConRepFSInstPat
, requiring a bit of a refactoring
around what is now DataConPatContext
.
CPR W/W still won't unbox DataCons with existentials.
See Note [Which types are unboxed?]
for details.
I also refactored the various tyCon*DataCon(s)_maybe
functions in
GHC.Core.TyCon
, deleting some of them which are no longer needed
(isDataProductType_maybe
and isDataSumType_maybe
).
I cleaned up a couple of call sites, some of which weren't very explicit
about whether they cared for existentials or not.
The test output of T18013
changed, because we now unbox the Rule
data type. Its constructor carries existential state and will be
w/w'd now. In the particular example, the worker functions inlines right
back into the wrapper, which then unnecessarily has a (quite big) stable
unfolding. I think this kind of fallout is inevitable;
see also Note [Don't w/w inline small non-loop-breaker things].
There's a new regression test case T18982
.
Fixes #18982 (closed) and #18971 (closed).