[GHC] #10401: state hack-related regression

GHC ghc-devs at haskell.org
Mon May 11 04:25:56 UTC 2015


#10401: state hack-related regression
-------------------------------------+-------------------------------------
              Reporter:  rwbarton    |             Owner:
                  Type:  bug         |            Status:  new
              Priority:  normal      |         Milestone:
             Component:  Compiler    |           Version:  7.10.1
              Keywords:              |  Operating System:  Unknown/Multiple
          Architecture:              |   Type of failure:  Runtime
  Unknown/Multiple                   |  performance bug
             Test Case:              |        Blocked By:
              Blocking:              |   Related Tickets:
Differential Revisions:              |
-------------------------------------+-------------------------------------
 Consider the following program `exp.hs`:

 {{{
 import Control.Monad
 import Debug.Trace

 expensive :: String -> String
 expensive x = trace "$$$" x
 {-# NOINLINE expensive #-}

 main :: IO ()
 main = do
   str <- fmap expensive getLine
   replicateM_ 3 $ print str
 }}}

 When run as `echo hi | ./exp`, it might print either
 {{{
 $$$
 "hi"
 "hi"
 "hi"
 }}}
 or
 {{{
 $$$
 "hi"
 $$$
 "hi"
 $$$
 "hi"
 }}}
 depending on the compiler version and optimization settings.

 In 7.8.4, building with `-O2` produces the second (bad) output, while
 building with `-O2 -fno-state-hack` produces the first output, not
 surprisingly.

 However in 7.10.1 and in HEAD both `-O2` and `-O2 -fno-state-hack` produce
 the second output.

 It seems this difference in behavior between 7.8.4 and 7.10.1 may be due
 to the following difference in the unfolding for IO's fmap. In 7.8.4
 {{{
 ba867929df0910f70431843781ad014d
   $fFunctorIO2 :: (a -> b)
                   -> GHC.Types.IO a
                   -> GHC.Prim.State# GHC.Prim.RealWorld
                   -> (# GHC.Prim.State# GHC.Prim.RealWorld, b #)
     {- Arity: 3, HasNoCafRefs,
        Strictness: <L,1*C1(U)><C(S),1*C1(U(U,U))><L,U>,
        Unfolding: (\ @ a
                      @ b
                      f :: a -> b
                      x :: GHC.Types.IO a
                      s :: GHC.Prim.State# GHC.Prim.RealWorld ->
                    case x `cast` (GHC.Types.NTCo:IO[0] <a>_R)
                           s of ds { (#,#) ipv ipv1 ->
                    (# ipv, f ipv1 #) }) -}
 }}}
 while in 7.10.1
 {{{
 d645bee15151bb50f2bad5912d533b38
   $fFunctorIO2 ::
     (a -> b) -> IO a -> State# RealWorld -> (# State# RealWorld, b #)
   {- Arity: 3, HasNoCafRefs,
      Strictness: <L,1*C1(U)><C(S),1*C1(U(U,U))><L,U>,
      Unfolding: InlineRule (3, True, False)
                 (\ @ a @ b f :: a -> b x :: IO a s :: State#
 RealWorld[OneShot] ->
 --
 ^^^^^^^
                  case x `cast` (NTCo:IO[0] <a>_R) s of ds { (#,#) ipv ipv1
 ->
                  (# ipv, f ipv1 #) }) -}
 }}}

 I didn't completely confirm this, though, nor determine how that
 difference arose in the first place (I assume the libraries were built
 with `-O2` for both versions?)

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


More information about the ghc-tickets mailing list