
#10844: CallStack should not be inlined -------------------------------------+------------------------------------- Reporter: nomeata | Owner: gridaphobe Type: task | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.10.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D1259 -------------------------------------+------------------------------------- Comment (by gridaphobe): Thanks, that makes sense. I see two ways to think about this: 1. The real problem is the interaction between `INLINE` and the invisible CallStacks. Normally the programmer can see the entire definition that would be inlined because he just wrote it. So GHC can expect the programmer to make an informed decision about whether a given definition should be unconditionally inlined. CallStacks change this because they're invisible to the programmer, GHC inserts them automatically. Worse, they're a sizeable datatype containing three Strings per call-site. For example, a simple call to `error` goes from the source-level {{{ error "bad" }}} to something like {{{ error [("error", SrcLoc 1 1 1 8 "file.hs" "Main")] "bad" }}} We can't reasonably expect programmers to account for such invisible expressions when deciding whether to add an `INLINE` pragma. So perhaps a reasonable principle would be that '''GHC should not inline terms that the programmer did not write'''. At the moment I think this would only apply to CallStacks and dictionaries, but dictionaries are already top-level values so they shouldn't be dragged along the way CallStacks are. 2. Perhaps inlining the code to build the CallStack is not so bad (I don't really know how to judge that), but the real problem is inlining the three string literals. It does seem quite silly to inline string literals, why should we need more than one copy? GHC already floats string literals to top-level binders, but it doesn't know that it can reuse literals from imported modules. In this case the principle would be that '''there should only be one copy of any given string literal''' (per package?). So perhaps a Module could export a list of all string literals it allocated. Then a final simplification pass could replace literals with references to the literals that were already allocated in imported modules. This would leave the unfoldings unchanged and should not affect any opportunities for optimization, while still allowing us to clean up after the inliner. These both seem like reasonable principles to me, but only the second would help with my callstack-free example in comment:9. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10844#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler