[GHC] #14610: newtype wrapping of a monadic stack kills performance
GHC
ghc-devs at haskell.org
Tue Dec 26 01:08:09 UTC 2017
#14610: newtype wrapping of a monadic stack kills performance
-------------------------------------+-------------------------------------
Reporter: mrkkrp | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.2.2
Resolution: | Keywords:
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 dfeuer):
I haven't yet been able to reproduce quite the same behavior, but this
small example looks like it could be related. If I write
{{{#!hs
foo :: forall a. (Int -> Bool) -> Int -> a -> a
foo p = go
where
go :: Int -> a -> a
go !n a
| p n = a
| otherwise = go (n + 1) a
}}}
then I get
{{{
foo
= \ (@ a_aYZ)
(p_aWO :: Int -> Bool)
(eta_B2 :: Int)
(eta1_B1 :: a_aYZ) ->
case eta_B2 of { GHC.Types.I# ww1_s1bZ ->
joinrec {
$wgo_s1c1 [InlPrag=NOUSERINLINE[0], Occ=LoopBreaker]
:: GHC.Prim.Int# -> a_aYZ -> a_aYZ
[LclId[JoinId(2)], Arity=2, Str=<L,U><S,1*U>, Unf=OtherCon []]
$wgo_s1c1 (ww2_X1cu :: GHC.Prim.Int#) (w_s1bW :: a_aYZ)
= case p_aWO (GHC.Types.I# ww2_X1cu) of {
False -> jump $wgo_s1c1 (GHC.Prim.+# ww2_X1cu 1#) w_s1bW;
True -> w_s1bW
}; } in
jump $wgo_s1c1 ww1_s1bZ eta1_B1
}
}}}
But if I make `go` polymorphic,
{{{#!hs
foo :: (Int -> Bool) -> Int -> a -> a
foo p = go
where
go :: Int -> b -> b
go !n a
| p n = a
| otherwise = go (n + 1) a
}}}
I get a wrapper and this worker:
{{{#!hs
T14610.$wfoo
= \ (@ a_s1cm)
(w_s1cn :: Int -> Bool)
(ww_s1cs :: GHC.Prim.Int#)
(w1_s1cp :: a_s1cm) ->
letrec {
$wgo_s1cl [InlPrag=NOUSERINLINE[0], Occ=LoopBreaker]
:: forall b. GHC.Prim.Int# -> b -> b
[LclId, Arity=2, Str=<L,U><S,1*U>, Unf=OtherCon []]
$wgo_s1cl
= \ (@ b_s1ce) (ww1_s1cj :: GHC.Prim.Int#) (w2_s1cg :: b_s1ce)
->
case w_s1cn (GHC.Types.I# ww1_s1cj) of {
False -> $wgo_s1cl @ b_s1ce (GHC.Prim.+# ww1_s1cj 1#)
w2_s1cg;
True -> w2_s1cg
}; } in
$wgo_s1cl @ a_s1cm ww_s1cs w1_s1cp
}}}
This distinction remains as `let` vs. `let-no-escape` in STG.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14610#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list