[GHC] #14068: Loopification using join points
GHC
ghc-devs at haskell.org
Wed Feb 21 15:56:11 UTC 2018
#14068: Loopification using join points
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner: nomeata
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.0.1
Resolution: | Keywords: JoinPoints
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: #13966 #14067 | Differential Rev(s): Phab:D3811
#14827 |
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by nomeata):
Is it possible that this happens (using the examle from the top of
`SpecConstr`)?
Before:
{{{
Rec {
drop n xs = case xs of
[] -> []
(y:ys) -> case n of
I# n# -> case n# of
0 -> []
_ -> drop (I# (n# -# 1#)) xs
}
}}}
here SpecConstr kicks, creating a rule and specializing, yielding the nice
{{{
Rec {
$sdrop n# xs = case xs of
[] -> []
(y:ys) -> case n# of
0 -> []
_ -> $sdrop (n# -# 1#) xs
}
RULE drop (I# n) xs = $sdrop n xs
}}}
But with loopification, we start with
{{{
drop n xs =
joinrec j n xs = case xs of
[] -> []
(y:ys) -> case n of
I# n# -> case n# of
0 -> []
_ -> call j (I# (n# -# 1#)) xs
in j n xs
}}}
(yay!), and now we liberate case can do its work, and we get (I think)
{{{
drop n xs =
case xs of
[] -> []
(y:ys) -> case n of
I# n# ->
joinrec j n xs = case xs of
[] -> []
(y:ys) -> case n# of
0 -> []
_ -> call j (I# (n# -# 1#)) xs
in j n (y:ys)
}}}
but now spec-constr no longer kicks! It’s comments say (abbreviated):
> So we look for a self-recursive function AND at a recursive call,
> one or more parameters is an explicit constructor application AND
> that same parameter is scrutinised by a case somewhere in the RHS
> of the function
This used to be true for the original, recursive `drop`, but not for the
loopified: `drop` is not recursive, `j` does not scrutinize the parameter.
So we don’t create a specialization for `drop`, causing extra allocations
when there are calls to `drop (I$ n)` somewhere.
Now in some cases this might be ok, namely when we can inline `drop`
(which is no longer recursive). But `drop` contains this big `joinrec`, so
it’s too big to be inlined?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14068#comment:28>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list