#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

Reply via email to