[GHC] #11095: -O0 -g slows GHC down on list literals (compared to -O0 without -g)
GHC
ghc-devs at haskell.org
Mon Jan 23 21:35:56 UTC 2017
#11095: -O0 -g slows GHC down on list literals (compared to -O0 without -g)
-------------------------------------+-------------------------------------
Reporter: slyfox | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Compile-time | Unknown/Multiple
performance bug | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): phab:D3001
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by niteria):
I suspect (I have yet to read the paper!) that the resulting term has
quadratic size.
We're building:
{{{
() : () : () : () : () : () : () : []
}}}
which becomes:
{{{
a = () : []
b = () : a
c = () : b
d = () : c
e = () : d
f = () : e
g = () : f
}}}
We then construct ticks for each of `a..g`:
{{{
ticks(a) = SrcLoc(a)
ticks(b) = ticks(a) ++ SrcLoc(b)
ticks(c) = ticks(b) ++ SrcLoc(c)
ticks(d) = ticks(c) ++ SrcLoc(d)
ticks(e) = ticks(d) ++ SrcLoc(e)
ticks(f) = ticks(e) ++ SrcLoc(f)
ticks(g) = ticks(f) ++ SrcLoc(g)
-- the order of arguments here is important,
-- we end up doing an equivalent of appending one element to a list
-- we do that over all the expressions, for each SrcLoc
}}}
The reason my patch helped is this part of `mkTick'`:
{{{
-- For annotations this is where we make sure to not introduce
-- redundant ticks.
| tickishContains t t2 -> mkTick' top rest e
| tickishContains t2 t -> orig_expr
| otherwise -> mkTick' top (rest . Tick t2)
e
}}}
We almost always reach the `otherwise` case because the source locations
are disjoint, so `tickishContains` is quite hot.
Not only the result is quadratic, the function `wrapTicks` is quadratic as
well:
{{{
wrapTicks (Floats flag floats0) expr = (Floats flag floats1, expr')
where (floats1, expr') = foldrOL go (nilOL, expr) floats0
-- ^ iterate over floats0
go (FloatTick t) (fs, e) = ASSERT(tickishPlace t == PlaceNonLam)
(mapOL (wrap t) fs, mkTick t e)
-- ^ map over fs, proportional in size
to floats0
go other (fs, e) = (other `consOL` fs, e)
-- ^ fs can grow proportional in size to floats0
wrap t (FloatLet bind) = FloatLet (wrapBind t bind)
wrap t (FloatCase b r ok) = FloatCase b (mkTick t r) ok
wrap _ other = pprPanic "wrapTicks: unexpected
float!"
(ppr other)
wrapBind t (NonRec binder rhs) = NonRec binder (mkTick t rhs)
wrapBind t (Rec pairs) = Rec (mapSnd (mkTick t) pairs)
}}}
Sorry I can't explain it better, the important point I believe is that the
result has quadratic size.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11095#comment:8>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list