[GHC] #11731: Simplifier: Inlining trivial let can lose sharing

GHC ghc-devs at haskell.org
Wed Mar 30 20:25:15 UTC 2016


#11731: Simplifier: Inlining trivial let can lose sharing
-------------------------------------+-------------------------------------
        Reporter:  nomeata           |                Owner:
            Type:  bug               |               Status:  patch
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.1
      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:D2064
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Well that's extremely annoying.  I'd typed a long comment in,
 but Trac has binned it somehow.  Sigh.

 I have concluded that the approach in comment:16 (based on my suggestion
 in comment:5) is too fragile.

 * As Ben points out there are other `exprIsTrivial` variants.

 * We'd probably need to do similar surgery for `exprIsCheap`, lest we
 change sharing by floating something like
 {{{
 x = case v of (p,q) -> p
 }}}
   out, aand then discover we know that `v` is a pair `(x,y)`, so it all
 turns into `x=y`

 in short, I'm just not confident that we can be sure to maintain this
 single-entry property.

 Moreover, ''these restrictions cripple otherwise-useful transformations''.
 For example, we might end up with a function that claims to evaluate its
 argument at most once, but to maintain that claim looks like `\x. let y =
 x in ...body...`.   So now two thunks get allocated for every call, one
 single entry, and one indirection-thunk that does the update. This is bad
 bad.

 Much better, I think, to do this:

 * Allow unrestricted transformation, as now, with no guarantees about
 maintaining single-entry-nes.  Indeed maybe the demand analyser should not
 even record signle-entry-ness in the Ids, since it is so fragile.

 * Just before code generation, perhaps even after `CorePrep`, do demand
 analysis ''but not worker-wrapper''.  So all it does is pin on the single-
 entry-ness to each thunk, just before it is needed in `CoreToStg`.  No
 simplifier pass afterwards to mess it up!

 That should nail it in a robust way.

 Note that this final demand-analysis is there solely to attach single-
 entry-ness.  We might still want to do "late demand analysis" with `-O2`,
 as now, complete with worker/wrapper and subsequent simplification pass,
 to exploit the usual w/w benefits of strictness exposed at later stages of
 the pipeline.  That becomes an independent choice.

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


More information about the ghc-tickets mailing list