#7240: Stack trace truncated too much with indirect recursion
------------------------------+---------------------------------------------
 Reporter:  nomeata           |          Owner:  nomeata         
     Type:  bug               |         Status:  new             
 Priority:  normal            |      Component:  Profiling       
  Version:  7.4.1             |       Keywords:                  
       Os:  Unknown/Multiple  |   Architecture:  Unknown/Multiple
  Failure:  None/Unknown      |       Testcase:                  
Blockedby:                    |       Blocking:                  
  Related:                    |  
------------------------------+---------------------------------------------

Comment(by nomeata):

 In comment:1 I wondered if there are already unexpected effects when
 combining the current truncation policy with the ```enterFunCCS``` logic,
 and there are. Consider this program:

 {{{
 module Main where
 import GHC.Stack

 f 0  = currentCallStack >>= putStrLn . renderStack
 main = boringCombinator (interestingFunction1)  0
 interestingFunction1 x = interestingFunction2 x
 interestingFunction2 x = case genFun x of Just g -> boringCombinator g x
 boringCombinator f x = f x
 genFun x = Just $ \y -> f y
 }}}

 With no truncating policy at all, this is the stack trace:

 {{{
 Stack trace:
   Main.f (callstack005.hs:4:8-50)
   Main.genFun (callstack005.hs:9:25-27)
   Main.genFun (callstack005.hs:9:12-27)
   Main.interestingFunction2 (callstack005.hs:7:31-38)
   Main.boringCombinator (callstack005.hs:8:24-26)
   Main.interestingFunction2 (callstack005.hs:7:53-72)
   Main.interestingFunction1 (callstack005.hs:6:26-47)
   Main.boringCombinator (callstack005.hs:8:24-26)
   Main.main (callstack005.hs:5:8-49)
   Main.CAF (<entire-module>)
 }}}

 Note that when, in the second invocation of ```boringCombinator```, the
 thunk generated by ```genFun``` is called and ```interestingFunction1```
 is on both the stack of the call site and the function (part of the common
 prefix), so it is not appended to the stack. But with the current output,
 the result is

 {{{
 Stack trace:
   Main.f (callstack005.hs:4:8-50)
   Main.genFun (callstack005.hs:9:25-27)
   Main.genFun (callstack005.hs:9:12-27)
   Main.interestingFunction2 (callstack005.hs:7:31-38)
   Main.interestingFunction1 (callstack005.hs:6:26-47)
   Main.boringCombinator (callstack005.hs:8:24-26)
   Main.main (callstack005.hs:5:8-49)
   Main.CAF (<entire-module>)
 }}}

 Here, ```interestingFunction1``` was truncated from the stack between the
 first and the second invocation of  ```boringCombinator```. But it still
 lies on the stack of the thunk, so it is appended after the second
 invocation of ```boringCombinator```, suddenly reversing the order of
 things on the stack.

 So I conclude that both policies, the one in place and the one I am
 suggesting, do not behave perfectly WRT to the stack merging. (Ideally, a
 stack truncating function should commute with ```++>```, but it is not
 clear to me if that is even possible without storing the whole stack).

 That leads us to the question what policy is more desired. I would argue
 that the current policy truncates too much, i.e. in the example in
 comment:3, the interesting functions would neither show up in the stack
 trace nor get cost allocated for ```f```.

 What effects would my policy have on the profiles? It would be more
 accurate about the now truncated functions: Because it only truncates
 duplicate segments, any function that is on the stack without any
 truncation will be on the stack with my policy.

 OTOH functions who appear several times will inherit the cost several
 times (```inheritCosts``` in Profiling.c). Is that acceptable? Maybe even
 desirable? ```inheritCosts``` does not seem to be time-critical, so one
 could add code that only adds the current cc’s values to the ccs if this
 cc is not already present on the ccs above (and hence was already
 counted).

 If that is algorithmically to slow we can use the information in
 ```pushCostCentre``` (where we already have it, due to ```checkLoop```)
 and save it in the ccs via ```actualPush```.

 Ok, enough analysis for now; I should now wait for feedback.

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

_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to