#1885: Improve CPR analysis
----------------------+-----------------------------------------------------
Reporter: simonpj | Owner: simonpj
Type: task | Status: new
Priority: normal | Milestone: 6.10 branch
Component: Compiler | Version: 6.8.1
Severity: normal | Resolution:
Keywords: | Difficulty: Unknown
Testcase: | Architecture: Unknown
Os: Unknown |
----------------------+-----------------------------------------------------
Old description:
> When a function returns a ''nested'' data structure, GHC should expose
> that fact to the caller. This can make a very big difference in inner
> loops. A good example is the following message (from GHC users).
>
> Compile the attached files thus:
> {{{
> ghc --make Unpacked.hs -O2 -cpp -DPOLY_SAME
> }}}
> and similarly with `DPOLY_OTHER`. The `POLY_OTHER` case does a lot more
> allocation because a key function isn't inlined.
> {{{
> $wa_r1Wb :: GHC.Prim.Addr#
> -> GHC.Prim.State# GHC.Prim.RealWorld
> -> (# GHC.Prim.State# GHC.Prim.RealWorld,
> OtherP.C
> GHC.Float.Double (OtherP.C GHC.Float.Double
> (OtherP.C GHC.Float.Double ()))
> #)
> [GlobalId]
> [Arity 2
> NoCafRefs
> Str: DmdType LL]
> $wa_r1Wb =
> \ (ww_s1S5 :: GHC.Prim.Addr#) (w_s1S7 :: GHC.Prim.State#
> GHC.Prim.RealWorld) ->
> case GHC.Prim.readDoubleOffAddr# @ GHC.Prim.RealWorld ww_s1S5 0
> w_s1S7
> of wild2_a1xI { (# s2_a1xK, x_a1xL #) ->
> let {
> ipv_XGd [Just L] :: GHC.Prim.Addr#
> [Str: DmdType]
> ipv_XGd = GHC.Prim.plusAddr# ww_s1S5 8 } in
> case GHC.Prim.readDoubleOffAddr# @ GHC.Prim.RealWorld ipv_XGd 0
> s2_a1xK
> of wild21_X1yK { (# s21_X1yN, x1_X1yP #) ->
> case GHC.Prim.readDoubleOffAddr#
> @ GHC.Prim.RealWorld (GHC.Prim.plusAddr# ipv_XGd 8) 0 s21_X1yN
> of wild22_X1yU { (# s22_X1yX, x2_X1yZ #) ->
> (# s22_X1yX,
> OtherP.C
> @ GHC.Float.Double
> @ (OtherP.C GHC.Float.Double (OtherP.C GHC.Float.Double ()))
> (GHC.Float.D# x_a1xL)
> (OtherP.C
> @ GHC.Float.Double
> @ (OtherP.C GHC.Float.Double ())
> (GHC.Float.D# x1_X1yP)
> (OtherP.C @ GHC.Float.Double @ ()
> (GHC.Float.D# x2_X1yZ) GHC.Base.())) #)
> } } }
> }}}
New description:
When a function returns a ''nested'' data structure, GHC should expose
that fact to the caller. This can make a very big difference in inner
loops. A good example is the following message (from GHC users
http://www.haskell.org/pipermail/glasgow-haskell-
users/2007-November/013454.html).
Compile the attached files thus:
{{{
ghc --make Unpacked.hs -O2 -cpp -DPOLY_SAME
}}}
and similarly with `DPOLY_OTHER`. The `POLY_OTHER` case does a lot more
allocation because a key function isn't inlined.
{{{
$wa_r1Wb :: GHC.Prim.Addr#
-> GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld,
OtherP.C
GHC.Float.Double (OtherP.C GHC.Float.Double
(OtherP.C GHC.Float.Double ()))
#)
[GlobalId]
[Arity 2
NoCafRefs
Str: DmdType LL]
$wa_r1Wb =
\ (ww_s1S5 :: GHC.Prim.Addr#) (w_s1S7 :: GHC.Prim.State#
GHC.Prim.RealWorld) ->
case GHC.Prim.readDoubleOffAddr# @ GHC.Prim.RealWorld ww_s1S5 0 w_s1S7
of wild2_a1xI { (# s2_a1xK, x_a1xL #) ->
let {
ipv_XGd [Just L] :: GHC.Prim.Addr#
[Str: DmdType]
ipv_XGd = GHC.Prim.plusAddr# ww_s1S5 8 } in
case GHC.Prim.readDoubleOffAddr# @ GHC.Prim.RealWorld ipv_XGd 0
s2_a1xK
of wild21_X1yK { (# s21_X1yN, x1_X1yP #) ->
case GHC.Prim.readDoubleOffAddr#
@ GHC.Prim.RealWorld (GHC.Prim.plusAddr# ipv_XGd 8) 0 s21_X1yN
of wild22_X1yU { (# s22_X1yX, x2_X1yZ #) ->
(# s22_X1yX,
OtherP.C
@ GHC.Float.Double
@ (OtherP.C GHC.Float.Double (OtherP.C GHC.Float.Double ()))
(GHC.Float.D# x_a1xL)
(OtherP.C
@ GHC.Float.Double
@ (OtherP.C GHC.Float.Double ())
(GHC.Float.D# x1_X1yP)
(OtherP.C @ GHC.Float.Double @ ()
(GHC.Float.D# x2_X1yZ) GHC.Base.())) #)
} } }
}}}
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1885#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs