[GHC] #13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures

GHC ghc-devs at haskell.org
Tue Jan 3 16:30:21 UTC 2017


#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures
-------------------------------------+-------------------------------------
        Reporter:  hvr               |                Owner:
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.0.2
       Component:  Compiler          |              Version:  8.0.2-rc2
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  crash or panic                     |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #12595            |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by bgamari):

 I did a bit of digging into what is happening here: early in
 simplification we have the core,
 {{{#!hs
 scServerState [InlPrag=NOINLINE] :: SCServerState
 scServerState = ...

 foo_s1Sx :: State# RealWorld -> (# State# RealWorld, Int #)
 foo_s1Sx =
   \ (eta_B1 [OS=OneShot] :: State# RealWorld) ->
     case case scServerState
          of _ [InlPrag=NOINLINE, Occ=Dead] { SCServerState ipv_s1S8 ->
          GHC.Tuple.()
          }
     of _ [Occ=Dead] { () -> ...
 }}}

 Eventually case-of-case (and perhaps something else) fires, giving us,
 {{{#!hs
 foo_s1Sx =
   \ (eta_B1 [OS=OneShot] :: State# GHC.Prim.RealWorld) ->
     case scServerState
     of scServerState [InlPrag=NOINLINE] { SCServerState ipv_s1S8 ->
     case scServerState of _ [Occ=Dead] { SCServerState ds_d1Qj -> ...
 }}}
 Note that we are now shadowing the `scServerState` binder. This already
 seems suspicious.

 This then gets transformed to a `let` by the lifted case elimination
 simplification (see `Note [Case elimination: lifted case]`),
 {{{#!hs
 -- from phase
 foo_s1Sx =
   \ (eta_B1 [Dmd=<S,U>, OS=OneShot] :: State# GHC.Prim.RealWorld) ->
     let {
       scServerState [InlPrag=NOINLINE, Dmd=<S(S(S)),1*U(1*U(U))>]
         :: SCServerState
       [LclId,
        Str=DmdType,
        Unf=Unf{Src=<vanilla>, TopLvl=False, Value=False, ConLike=False,
                WorkFree=True, Expandable=True,
                Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}]
       scServerState = scServerState } in
     case scServerState
     of _ [Occ=Dead, Dmd=<L,A>]
     { SCServerState ds_d1Qj [Dmd=<S(S),1*U(U)>] -> ...
 }}}

 The let-bound `scServerState` is then floated to the top-level, resulting
 in the
 duplicate closures we see here.

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


More information about the ghc-tickets mailing list