[GHC] #10148: Optimization causes repeated computation

GHC ghc-devs at haskell.org
Tue Mar 10 10:28:22 UTC 2015


#10148: Optimization causes repeated computation
-------------------------------------+-------------------------------------
        Reporter:  akio              |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.10.1-rc1
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
 Type of failure:  Runtime           |  Unknown/Multiple
  performance bug                    |               Test Case:
      Blocked By:                    |                Blocking:
 Related Tickets:                    |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by akio):

 Looking at Core and STG outputs for `repeated2.hs`, it looks like
 incorrect demand information is causing the problem.

 ghc 7.10.20150123 produces the following core for `gstep` when invoked
 with `-O1 -fno-state-hack`:

 {{{
 Rec {
 Main.$wgstep [InlPrag=[0], Occ=LoopBreaker]
   :: GHC.Types.Int
      -> GHC.Prim.Int#
      -> (# GHC.Types.Int -> Main.Machine, GHC.Types.Int #)
 [GblId, Arity=2, Str=DmdType <L,U(U)><L,U>, Unf=OtherCon []]
 Main.$wgstep =
   \ (ww :: GHC.Types.Int) (ww1 [Occ=Once] :: GHC.Prim.Int#) ->
     case GHC.Prim.<# ww1 0 of sat { __DEFAULT ->
     case GHC.Prim.tagToEnum# @ GHC.Types.Bool sat of _ [Occ=Dead] {
       GHC.Types.False ->
         let {
           ipv [Occ=OnceL, Dmd=<L,A>] :: GHC.Types.Int
           [LclId, Str=DmdType]
           ipv =
             let {
               sat [Occ=Once, Dmd=<L,1*U>] :: GHC.Base.String
               [LclId, Str=DmdType]
               sat =
                 let {
                   sat [Occ=Once] :: [GHC.Types.Char]
                   [LclId, Str=DmdType]
                   sat =
                     case ww of _ [Occ=Dead] { GHC.Types.I# ww3 [Occ=Once]
 ->
                     case GHC.Show.$wshowSignedInt 0 ww3 (GHC.Types.[] @
 GHC.Types.Char)
                     of _ [Occ=Dead] { (# ww5 [Occ=Once], ww6 [Occ=Once] #)
 ->
                     GHC.Types.: @ GHC.Types.Char ww5 ww6
                     }
                     } } in
                 GHC.CString.unpackAppendCString# "adj "# sat } in
             Debug.Trace.trace @ GHC.Types.Int sat ww } in
         let {
           sat [Occ=Once] :: GHC.Types.Int -> Main.Machine
           [LclId, Str=DmdType]
           sat =
             \ (w [Occ=Once!] :: GHC.Types.Int) ->
               case w of _ [Occ=Dead] { GHC.Types.I# ww3 [Occ=Once] ->
               case Main.$wgstep ipv ww3
               of _ [Occ=Dead] { (# ww5 [Occ=Once], ww6 [Occ=Once] #) ->
               Main.Machine ww5 ww6
               }
               } } in
         (# sat, ww #);
       GHC.Types.True -> case GHC.Err.undefined of _ [Occ=Dead] { }
     }
     }
 end Rec }
 }}}

 Note the `ipv [Occ=OnceL, Dmd=<L,A>]` part. If I understand it correctly,
 `Dmd<L,A>` claims that `ipv` will not be used at all. However, this is
 wrong and `ipv` will be used in the recursive call to `Main.$wgstep`.

 This demand info then causes a single-entry closure (`\s`) to be generated
 for `ipv` in the STG.

 If I replace the `undefined i` with just `undefined` in the source file,
 the corresponding definition has no demand information, and its closure is
 marked as updatable (`\u`) rather than single-entry.

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


More information about the ghc-tickets mailing list