#4267: Strictness analyser is to conservative about passing a boxed parameter
---------------------------------+------------------------------------------
    Reporter:  tibbe             |        Owner:              
        Type:  bug               |       Status:  new         
    Priority:  normal            |    Milestone:  7.4.1       
   Component:  Compiler          |      Version:  6.13        
    Keywords:                    |     Testcase:              
   Blockedby:                    |   Difficulty:              
          Os:  Unknown/Multiple  |     Blocking:              
Architecture:  Unknown/Multiple  |      Failure:  None/Unknown
---------------------------------+------------------------------------------

Comment(by simonpj):

 I took a little look at this.  As you say, you get the loop
 {{{
 sumTree_go :: Int -> Fold.Tree Int -> Int
 sumTree_go =
   \ (z :: Int) (ds_ddX :: Fold.Tree Int) ->
     case ds_ddX of _ {
       Fold.Leaf -> z;
       Fold.Node a l r ->
         case sumTree_go z l of _ { I# z' ->
         case a of _ { I# a# ->
         sumTree_go (I# (+# z' a#)) r
         } } }
 }}}
 Notice that this loop is ''strict'' in z, but does not actually ''unbox''
 z.  The strictness analyser conservatively passes the boxed version under
 such circumstances, to avoid the possiblity of unboxing it, passing it to
 the function, which immediately reboxes it.

 It turns out that adding a "!" to the defn of `go` is enough to fix this:
 {{{
     go z Leaf = z
     go !z (Node a l r)   -- NOTE THE "!"
         = let z'  = go z l
               z'' = f z' a
           in z' `seq` z'' `seq` go z'' r
 }}}
 In fact the `seq`s are redundant because `go` is strict in both args, so
 this gives the same resulting code
 {{{
     go z Leaf = z
     go !z (Node a l r)   -- NOTE THE "!"
         = go (f z' a) (go z l)
 }}}
 The code (in the `sumTree` call) is lovely
 {{{
 T4267.$wgo :: GHC.Prim.Int# -> T4267.Tree GHC.Types.Int -> GHC.Prim.Int#
 T4267.$wgo =
   \ (ww_sps :: GHC.Prim.Int#) (w_spu :: T4267.Tree GHC.Types.Int) ->
     case w_spu of _ {
       T4267.Leaf -> ww_sps;
       T4267.Node ipv_soP ipv1_soQ ipv2_soR ->
         case T4267.$wgo ww_sps ipv1_soQ of ww1_spx { __DEFAULT ->
         case ipv_soP of _ { GHC.Types.I# y_ap5 ->
         T4267.$wgo (GHC.Prim.+# ww1_spx y_ap5) ipv2_soR
         } } }

 }}}
 So that's a workaround.

 Meanwhile I think the strictness analyser should be a bit cleverer, so
 I'll keep the ticket open for that reason.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4267#comment:7>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to