[GHC] #8326: Place heap checks common in case alternatives before the case

GHC ghc-devs at haskell.org
Wed Aug 5 20:43:52 UTC 2015


#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


More information about the ghc-tickets mailing list