
#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 Wiki Page: | -------------------------------------+------------------------------------- Comment (by gridaphobe): I'm not very impressed with the performance metrics on Phab:D1259 ([https://gist.github.com/gridaphobe/0657f02571e6df4588f7 nofib diff]), and I have a small example that I think may illustrate the problem. {{{ foo x = "foo" ++ x boo = "foo" }}} Compare what ghc-master does {{{ % ghc -O -fforce-recomp -ddump-simpl -dsuppress-all Foo.hs [1 of 1] Compiling Foo ( Foo.hs, Foo.o ) ==================== Tidy Core ==================== Result size of Tidy Core = {terms: 8, types: 8, coercions: 0} boo boo = unpackCString# "foo"# foo foo = \ x_amS -> unpackAppendCString# "foo"# x_amS }}} to what my branch does {{{ % ./inplace/bin/ghc-stage2 -O -fforce-recomp -ddump-simpl -dsuppress-all Foo.hs [1 of 1] Compiling Foo ( Foo.hs, Foo.o ) ==================== Tidy Core ==================== Result size of Tidy Core = {terms: 8, types: 9, coercions: 0} -- RHS size: {terms: 2, types: 0, coercions: 0} boo boo = unpackCString# "foo"# -- RHS size: {terms: 4, types: 3, coercions: 0} foo foo = \ x_anI -> ++ boo x_anI }}} Lifting the boxed string literal to a top-level binder prevents ghc from rewriting the `++` to `unpackAppendCString#`. Why? Because `boo` is a `String` not an `Addr#`, so applying the rewrite would require inlining the `"foo"#` string literal, which ghc does not want to do. What we really want (I think) is to make a top-level binder for `"foo"# :: Addr#`, so we'd end up with something like {{{ foo# = "foo"# boo = unpackCString# foo# foo = \ x_amS -> unpackAppendCString# foo# x_amS }}} Concretely, I propose that the desugarer-specific `mkStringExpr` function create '''two''' top-level binders, one for the `Addr#` and one for the `String`. That should let us share the unboxed string '''and''' the boxed string. Does this seem reasonable? Or is my sample program simply a non-issue? (Sorry to keep jumping back and forth between phab and trac, but this seemed to fit better on the ticket than on the diff.) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10844#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler