#1498: Optimisation: eliminate unnecessary heap check in recursive function
-------------------------------------------+--------------------------------
Reporter: simonmar | Owner:
Type: bug | Status: new
Priority: low | Milestone: 7.6.1
Component: Compiler | Version: 6.6.1
Keywords: | Os: Unknown/Multiple
Architecture: Unknown/Multiple | Failure: Runtime performance
bug
Difficulty: Moderate (less than a day) | Testcase:
Blockedby: 4258 | Blocking:
Related: |
-------------------------------------------+--------------------------------
Comment(by batterseapower):
Simon: agreed that the in-branch heap check should just reuse the
immediately dominating procpoint rather than creating a new one. This is
what I was getting at in my previous comment. We just have to be careful
about code like:
{{{
f x y = case sideEffectingPrimOp of _ -> case (x ># y) of True -> let a =
D# x in ...; False -> f (x +# 1#) y
}}}
Because we don't want to reexecute sideEffectingPrimOp if the heap check
in the True branch fails. I've attached a patch that attempts to implement
this (it applies on top of the result of merging
7a7f6d703a99045cb9f590c819b795409a090022 into your newcg branch), but I
cant' benchmark it because newcg seems to be broken at the moment (the
built stage2 compiler crashes?).
The implementation is very hacky and awkward. I added a new field to the
FCode's state which carries around information about the last procpoint
(if any), and we can then use that procpoint as the target of our heap
check when generating code for certain alts.
One reason the implementation is not very nice because you have to be very
careful to zap this last-procpoint info wherever you emit any code which
it is not safe to duplicate the evaluation of (and where you do not
immediately establish a new procpoint). Currently I zap only when emitting
a tick or a call to a non-cheap inline primop, but there may be more cases
where zapping should happen (in fact, now I think about I should also have
zapped at any point where heapCheck was called but none was required
because virtHP didn't move). In particular, I'm not 100% sure if we should
allow heap allocation itself to be duplicated, e.g. in code like:
{{{
f x y = let z = D# x in case x ># y of ...
}}}
Perhaps there is a nicer way to implement it that I'm missing. I'm not
100% comfortable with how the codegen is written, so I consider this quite
likely.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1498#comment:15>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs