#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

Reply via email to