#4941: SpecConstr generates functions that do not use their arguments
---------------------------------+------------------------------------------
    Reporter:  simonpj           |        Owner:                         
        Type:  task              |       Status:  new                    
    Priority:  normal            |    Milestone:  _|_                    
   Component:  Compiler          |      Version:  7.0.1                  
    Keywords:                    |     Testcase:                         
   Blockedby:                    |   Difficulty:                         
          Os:  Unknown/Multiple  |     Blocking:                         
Architecture:  Unknown/Multiple  |      Failure:  Runtime performance bug
---------------------------------+------------------------------------------

Comment(by batterseapower):

 Headline numbers for this change after your #4957 fix:

 {{{
             Min          +0.0%     -3.2%     -4.4%     -2.5%     +0.0%
             Max          +0.3%     +4.0%     +4.5%     +4.9%     +0.0%
  Geometric Mean          +0.0%     -0.0%     +0.2%     +0.2%     -0.0%
 }}}

 So a solid reduction in allocations for a few benchmarks (knights,
 parstof, simple and sphere are the biggest winners). However, some
 benchmarks get worse. I looked at the worst offender (crypytarithm2) and
 saw something pretty odd. It looks like the transformation is working
 correctly but the output code (post simplification) contains dead let-
 bindings for SpecConstr specialisations that have been worker/wrappered,
 and those workers have been subsequently inlined into all use sites.

 For example, we have a local specialisation within the final body of
 permute1:

 {{{
 sgo_s1lg [InlPrag=INLINE[0], Occ=LoopBreaker!]
         :: Main.Digits
            -> Main.Digits
            -> [(Main.Digits, Main.Digits)]
            -> [(GHC.Types.Int, Main.Digits)]
       [LclId,
        Arity=3,
        Str=DmdType U(SL)LL,
        Unf=Unf{Src=Worker=$w$sgo_s1mv, TopLvl=False, Arity=3, Value=True,
                ConLike=True, Cheap=True, Expandable=True,
                Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=False)
                Tmpl= \ (w_s1lD [Occ=Once!] :: Main.Digits)
                        (w1_s1lI [Occ=Once] :: Main.Digits)
                        (w2_s1lJ [Occ=Once] :: [(Main.Digits,
 Main.Digits)]) ->
                        case w_s1lD
                        of _ { Main.Digits ww_s1lF [Occ=Once] ww1_s1lG
 [Occ=Once] ->
                        $w$sgo_s1mv ww_s1lF ww1_s1lG w1_s1lI w2_s1lJ
                        }}]
       $sgo_s1lg =
         \ (w_s1lD :: Main.Digits)
           (w1_s1lI :: Main.Digits)
           (w2_s1lJ :: [(Main.Digits, Main.Digits)]) ->
           case w_s1lD of _ { Main.Digits ww_s1lF ww1_s1lG ->
           $w$sgo_s1mv ww_s1lF ww1_s1lG w1_s1lI w2_s1lJ
           };
       $w$sgo_s1mv [Occ=LoopBreaker]
         :: [GHC.Types.Int]
            -> [(GHC.Types.Char, GHC.Types.Int)]
            -> Main.Digits
            -> [(Main.Digits, Main.Digits)]
            -> [(GHC.Types.Int, Main.Digits)]
       [LclId, Arity=4, Str=DmdType SLLL]
       $w$sgo_s1mv = ... big ...
 }}}

 But $sgo_s1lg does not occur anywhere in the code! These bindings are
 probably the source of the increased allocation as their closures will be
 allocated anew for each application of permute1.

 I found that changing the final simplification phase to use at least 3
 iterations (just like the main simplification phase) did not eliminate
 these. Is there any obvious explanation for this behaviour?

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4941#comment:9>
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