#14998: Sort out the strictness mess for exceptions -------------------------------------+------------------------------------- Reporter: simonpj | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.3 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Exceptions Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by sgraf): Replying to [comment:7 simonpj]:
reverse-complement allocates 11.6% more
That's remarkable. I expected it to be virtually nothing. I suppose that some investigation is called for.
Long story short, there was no difference in generated Core for both `reverse-complement` and `sphere`. The difference is is due to the [https://hackage.haskell.org/package/base-4.11.0.0/docs/src/GHC.IO.Handle.Int... do_operation function] that has a call to `catchException`. When I compare the strictness signatures when compiling `GHC.IO.Handle.Internal` there is a notable difference for the `withHandle*` family of functions which calls `do_operation`: {{{ 36,38c36,38 < GHC.IO.Handle.Internals.withAllHandles__: <L,U><S,1*U><L,C(C1(U))><S,U> < GHC.IO.Handle.Internals.withHandle: <L,U><S,1*U><L,C(C1(U))><S,U> < GHC.IO.Handle.Internals.withHandle': <L,U><L,U><S(S),U(U)><L,C(C1(U))><S,U> ---
GHC.IO.Handle.Internals.withAllHandles__: <L,U><S,1*U><C(S),C(U)><S,U> GHC.IO.Handle.Internals.withHandle: <L,U><S,1*U><C(S),C(U)><S,U> GHC.IO.Handle.Internals.withHandle': <L,U><L,U><S(S),U(U)><C(S),C(U)><S,U> 41c41 < GHC.IO.Handle.Internals.withHandle__': <L,U><L,U><S(S),U(U)><L,C(C1(U))><S,U>
GHC.IO.Handle.Internals.withHandle__': <L,U><L,U><S(S),U(U)><C(S),C(U)><S,U> 80,82c80,82 < GHC.IO.Handle.Internals.withAllHandles__: <L,U><S,1*U><L,C(C1(U))><S,U> < GHC.IO.Handle.Internals.withHandle: <L,U><S,1*U><L,C(C1(U))><S,U> < GHC.IO.Handle.Internals.withHandle': <L,U><L,U><S(S),1*U(U)><L,C(C1(U))><S,U>
GHC.IO.Handle.Internals.withAllHandles__: <L,U><S,1*U><C(S),C(U)><S,U> GHC.IO.Handle.Internals.withHandle: <L,U><S,1*U><C(S),C(U)><S,U> GHC.IO.Handle.Internals.withHandle': <L,U><L,U><S(S),1*U(U)><C(S),C(U)><S,U> 85c85 < GHC.IO.Handle.Internals.withHandle__': <L,U><L,U><S(S),1*U(U)><L,C(C1(U))><S,U>
GHC.IO.Handle.Internals.withHandle__': <L,U><L,U><S(S),1*U(U)><C(S),C(U)><S,U> }}}
These are called transitively by `hGetBuf` and `hPutBuf`. We could annotate the IO action passed to `do_operation` for an easy fix: {{{ diff --git a/libraries/base/GHC/IO/Handle/Internals.hs b/libraries/base/GHC/IO/Handle/Internals.hs index 48ece1dc5e..3d58f3d3bc 100644 --- a/libraries/base/GHC/IO/Handle/Internals.hs +++ b/libraries/base/GHC/IO/Handle/Internals.hs @@ -163,7 +163,8 @@ do_operation :: String -> Handle -> (Handle__ -> IO a) -> MVar Handle__ -> IO a do_operation fun h act m = do h_ <- takeMVar m checkHandleInvariants h_ - act h_ `catchException` handler h_ + let !io = act h_ + io `catchException` handler h_ where handler h_ e = do putMVar m h_ }}} I'm not sure if that's just navigating around the problem, but this brings strictness signatures on par and fixes `sphere` and `reverse-complement`. I'll re-run benchmarks now. Also, without this patch, T12996 (#12996) broke in `./validate`. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14998#comment:10> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler