[GHC] #13479: Core Lint issues during slowtest
GHC
ghc-devs at haskell.org
Tue Mar 28 20:13:27 UTC 2017
#13479: Core Lint issues during slowtest
-------------------------------------+-------------------------------------
Reporter: bgamari | Owner: nomeata
Type: bug | Status: new
Priority: high | Milestone: 8.2.1
Component: Compiler | Version: 8.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Compile-time | Unknown/Multiple
crash or panic | Test Case:
Blocked By: | Blocking:
Related Tickets: #10181 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by nomeata):
The problem is that Call Arity has not been changed to know about the
special semantics of join points. This is the code for in question:
{{{
f :: forall a. [Int] -> a
[LclIdX,
Arity=1,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 128 0}]
f = \ (@ a_a1iy) (a_XX6 :: [Int]) ->
let {
z_a34C :: Integer -> a_a1iy
[LclId,
CallArity=1,
Unf=Unf{Src=<vanilla>, TopLvl=False, Value=False, ConLike=False,
WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 28
0}]
z_a34C
= joinrec {
go_a34D [Occ=LoopBreaker] :: [Int] -> Integer -> a_a1iy
[LclId[JoinId(1)],
Arity=1,
CallArity=2,
Unf=Unf{Src=<vanilla>, TopLvl=False, Value=True,
ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS
[30] 24 0}]
go_a34D (ds_a34E :: [Int])
= case ds_a34E of {
[] -> case lvl_s4VT of wild_00 { };
: y_a34J ys_a34K -> jump go_a34D ys_a34K
}; } in
jump go_a34D a_XX6 } in
letrec {
go_a34D [Occ=LoopBreaker] :: [Int] -> Integer -> a_a1iy
[LclId,
Arity=1,
CallArity=2,
Unf=Unf{Src=<vanilla>, TopLvl=False, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 40
0}]
go_a34D
= \ (ds_a34E :: [Int]) ->
case ds_a34E of {
[] -> z_a34C;
: y_a34J ys_a34K -> go_a34D ys_a34K
}; } in
go_a34D a_XX6 lvl_s4VV
}}}
Call Arity (which analyzes things from bottom to top) correctly finds out
that the bottom `go_a34D` should have arity 2 (it is called with two
arguments, and keeps passing the second one around). This implies that
`z_a34C` is called with one argument, so that gets `CallArity=1`. From
this Call Arity follows that to first `go_a34D` (the join point) should
also have arity two, and it records it so.
The subsequent simplification then eta-expands the `go_a34D` function,
which turns it into a join point (yay!). But it does not *not* eta-expand
the join point `go_a34D` (which gets renamed to `go_X45x`):
{{{
f = \ (@ a_a1iy) (a_XX6 :: [Int]) ->
joinrec {
go_a34D [Occ=LoopBreaker] :: [Int] -> Integer -> a_a1iy
[LclId[JoinId(2)],
Arity=2,
CallArity=2,
Unf=Unf{Src=<vanilla>, TopLvl=False, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [36 0]
54 0}]
go_a34D (ds_a34E :: [Int]) (eta_B1 :: Integer)
= case ds_a34E of {
[] ->
joinrec {
go_X35x [Occ=LoopBreaker] :: [Int] -> a_a1iy
[LclId[JoinId(1)],
Arity=1,
CallArity=2,
Unf=Unf{Src=<vanilla>, TopLvl=False, Value=True,
ConLike=True,
WorkFree=True, Expandable=True,
Guidance=IF_ARGS [30] 24 0}]
go_X35x (ds_X35z :: [Int])
= case ds_X35z of {
[] -> case lvl_s4VT of wild_00 { };
: y_a34J ys_a34K -> jump go_X35x ys_a34K
}; } in
jump go_X35x a_XX6;
: y_a34J ys_a34K -> jump go_a34D ys_a34K eta_B1
}; } in
jump go_a34D a_XX6 lvl_s4VV
}}}
At this point, something went wrong. The now named `go_X45x` is still
marked as having CallArity=2, but it does not actually have that arity!
Where did the argument `eta_B1`, which I would have expected to be passed
to `go_X35x`, disappear? Was it “pushed into the branches”, and then into
the empty set branches of the empty case there?
So the simplifier uses the function `tryEtaExpandRhs` to try to eta-expand
if Call Arity tells it to do so, but it does not even try that for join
points (see `completeBind` in `Simplify`). I am a bit lost in the code
right now and cannot quite reproduce what precisely is happening here.
Something related to `simplJoinRHS` and “Context goes *inside* the
lambdas.” Certainly, Luke’s opinion would be welcome.
In any case, I believe the fix is to have the simplifier to simply zap
Call Arity information. It is the only place where it is actually used,
and as this demonstrates, the simplifier does not preserve Call Arity
information. I will prepare a PR for this.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13479#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list