[GHC] #14816: Missed Called Arity opportunity?
GHC
ghc-devs at haskell.org
Tue Feb 20 10:09:38 UTC 2018
#14816: Missed Called Arity opportunity?
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: Compiler | Version: 8.2.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Runtime | Unknown/Multiple
performance bug | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by sgraf):
Hey, it seems I'm lucky I subscribed to ghc-ticket just yesterday :)
I investigated a little.
So, it turns out that Demand Analysis doesn't recognize
`insertModifyingArr`s argument `f` to be called once (has usage `C(U(U)`).
That's really weird, actually the analysis should be able to figure that
out. The fact that `-ddump-stranal` doesn't mention `f` in the demand type
as a free variable to `go` makes me feel like there is some conservative
approximation at play here. And in fact, I believe that's how fix-pointing
works for functions in DmdAnal: Completely forget about free variables and
assume the most pessimistic result.
You can circumvent that if you make `f` an argument to `go` (reverse
static arg transform, essentially):
{{{
insertModifyingArr :: Int -> (a -> (# a #))
-> STArray s Int a -> ST s (STArray s Int a)
insertModifyingArr i0 f arr0 = do
rng <- range <$> getBounds arr0
go f i0 rng arr0
where
go f i [] arr = pure arr
go f i (k : ks) arr
| i == k = do
old <- readArray arr i
case f old of (# new #) -> writeArray arr i new
return arr
| otherwise = go f i ks arr
}}}
This makes DmdAnal propagate the usage information to the top-level: The
demand signature for `inserModifyingArr` mentions `f` with usage
`1*C1(U(U))`, which in theory should be enough information for the
simplifier to eta-expand the `blink` expression.
And sure enough, it does (somewhere inside `test`:
{{{
Fish.insertModifyingArr_$spoly_go
@ a_a3IX
@ s_a3IY
w_s4pP
ww6_s4s2
ww8_s4s5
ww3_s4q2
ww4_s4q3
(GHC.Enum.eftInt ww6_s4s2 ww8_s4s5)
k_a15T
(\ (a2_a15S [OS=OneShot] :: a_a3IX) ->
(# f_a15V a1_a15U a2_a15S #))
}}}
The interactions between free vars and static args are a little counter-
intuitive, I suppose...
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14816#comment:7>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list