#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