[GHC] #8275: Loopification breaks profiling

GHC ghc-devs at haskell.org
Thu Sep 19 17:56:59 CEST 2013


#8275: Loopification breaks profiling
----------------------------------------+----------------------------------
        Reporter:  jstolarek            |            Owner:  jstolarek
            Type:  bug                  |           Status:  new
        Priority:  highest              |        Milestone:
       Component:  Profiling            |          Version:  7.7
      Resolution:                       |         Keywords:
Operating System:  Unknown/Multiple     |     Architecture:
 Type of failure:  Building GHC failed  |  Unknown/Multiple
       Test Case:                       |       Difficulty:  Unknown
        Blocking:  8298                 |       Blocked By:
                                        |  Related Tickets:
----------------------------------------+----------------------------------

Comment (by jstolarek):

 Edward, there is some progress. There is a single test in the testsuite
 that fails when loopification is turned on, but works if it is off. That
 test is T1735. Assuming that you built GHC with profiling libraries you
 can run this test from `testsuite/tests` with:
 {{{
 make WAY=normal EXTRA_HC_OPTS="-prof -fprof-auto -rtsopts" TEST=T1735
 }}}
 and it should pass. Including `-floopification` on the list of extra
 options should make the test fail. Examining the Cmm dumps is a pain -
 they are over 200k lines - but I found a single place where loopification
 occurs. Attached are the dumps of this single function with and without
 loopification. `-input` suffix denotes code produced by the code
 generator, `-output` suffix denotes code after it has gone through all
 optimisations in Cmm pipeline.

 If you look at the output code you will notice one incorrect
 transformation in the loopified version: stack check gets duplicated and
 inserted at the end of function, right before making a tail call. There
 are two issues here:

   1) Correctness. Cmm pipeline performs an incorrect transformation on a
 valid Cmm input program. It duplicates stack check at the end of a
 function, which violates assumption that stack checks are made only at the
 entry to a function (see !CmmLayoutStack, line 208). Putting stack check
 at the end makes it invalid, because we set required amount of stack to be
 a fixed value. As a result at the end of a function we are checking for
 more stack that we actually need (becuase we have moved the stack
 pointer). Simon proposes to fix that by referring to `<old + 0>` instead
 of `Sp` (before stack layout). To me it is not clear whether this stack
 check is direct cause of a segfault, though it certainly is not correct.

   2) Performance. Putting stack check right before making a call makes no
 sense. This is probably the direct result of control flow optimisations
 pass, but there is a deeper problem here. When making a loopified tail
 call we want to avoid re-doing the stack check because it is not necessary
 to do it again, but we want to perform heap check. So loopified tail call
 should make a jump in between those two. Currently generation of stack and
 heap checks is closely coupled with each other in the code generator and
 it will probably take some work to separate them. Surprisingly, sometimes
 we get good code (loopification jumps between stack and heap checks) and
 sometimes we don't. Neither I nor Simon know why this happens - I need to
 look at the code and solve that mystery.

 I wasn't able to figure out one thing. The loopified tail call omits one
 block of code related to profiling (the one with magic numbers). I don't
 know whether this is correct or not. Edward, are you able to tell whether
 this can be done or not?

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8275#comment:11>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the ghc-tickets mailing list