
#8326: Place heap checks common in case alternatives before the case -------------------------------------+------------------------------------- Reporter: jstolarek | Owner: Type: task | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.7 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: 8317 Related Tickets: #1498 | Differential Revisions: Phab:D343 -------------------------------------+------------------------------------- Comment (by rwbarton): Attached nofib results are for the patch {{{ ; simple_scrut <- isSimpleScrut scrut alt_type ; let do_gc | not simple_scrut = True - | isSingleton alts = False - | up_hp_usg > 0 = False - | otherwise = True + | otherwise = False -- ticket:8326#comment:27 -- cf Note [Compiling case expressions] gc_plan = if do_gc then GcInAlts alt_regs else NoGcInAlts }}} As can be seen from the fact that very few Module Sizes changed, this actually rarely makes a difference. The reason is that there are two special cases of `cgCase` that always use NoGcInAlts. (I don't know why they do so, perhaps an oversight.) * If the case has algebraic alternatives, then either the scrutinee is not simple and we must GcInAlts, or the scrutinee is an application of `tagToEnum#` and the first special case applies and always uses NoGcInAlts. * If the case has primitive alternatives, then when the scrutinee is simply a variable, the second special case applies and always uses NoGcInAlts. So this patch only makes a difference when all of the following hold: * the case has primitive alternatives * the scrutinee is an application of a primop (that does not allocate, so it is simple, but most primops do not) * there is more than one alternative * there is no upstream heap check already * at least one alternative actually allocates (often CPR analysis has moved an allocation outside of the case) The combination of the second and third items is fairly rare, it means you are comparing the result of a primop against a constant. A typical example would be testing whether an Int is even or odd. Basically my conclusions are that * it's acceptable to apply this patch and always allocate outside the case here, since nofib did not find any significant regressions * it may still be worthwhile to try to make better decisions about whether to do heap checks in the alternatives, but then we should also do so in the special cases of `cgCase` -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8326#comment:34 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler