#2884: Compiled code performance worsens when module names are long enough
-----------------------------------------+----------------------------------
    Reporter:  jcpetruzza                |        Owner:                  
        Type:  run-time performance bug  |       Status:  new             
    Priority:  normal                    |    Milestone:  6.12 branch     
   Component:  Compiler                  |      Version:  6.10.1          
    Severity:  normal                    |   Resolution:                  
    Keywords:                            |   Difficulty:  Unknown         
    Testcase:                            |           Os:  Unknown/Multiple
Architecture:  Unknown/Multiple          |  
-----------------------------------------+----------------------------------
Changes (by simonmar):

  * difficulty:  => Unknown
  * type:  bug => run-time performance bug
  * milestone:  => 6.12 branch

Comment:

 I think this is another example that we can trace back to optimisation
 problems with record selectors.  If we look at the Core for `nodeFor`:

 {{{
 VeryLongModuleName.nodeFor :: GHC.Types.Int
                               -> VeryLongModuleName.T
                               -> VeryLongModuleName.T
 [GlobalId]
 [Arity 2
  Str: DmdType LS]
 VeryLongModuleName.nodeFor =
   \ (ds_dhX :: GHC.Types.Int) (ds1_dhY :: VeryLongModuleName.T) ->
     case ds1_dhY of wild_B1 {
       VeryLongModuleName.Nil -> VeryLongModuleName.Nil;
       VeryLongModuleName.Node ipv_ski ipv1_skj ipv2_skk ipv3_skl ->
         case ds_dhX of wild1_alg { GHC.Types.I# x#_ali ->
         case VeryLongModuleName.val wild_B1
         of wild11_alk { GHC.Types.I# y#_alm ->
         case GHC.Prim.<# x#_ali y#_alm of wild2_alq {
           GHC.Bool.False ->
             case GHC.Prim.==# x#_ali y#_alm of wild12_alt {
               GHC.Bool.False -> VeryLongModuleName.right wild_B1;
               GHC.Bool.True -> wild_B1
             };
           GHC.Bool.True -> VeryLongModuleName.left wild_B1
         }
         }
         }
     }
 }}}

 The record selector `VeryLongModuleName.val` has not been inlined, whereas
 in the `ShortM` version it has:

 {{{
 ShortM.nodeFor :: GHC.Types.Int -> ShortM.T -> ShortM.T
 [GlobalId]
 [Arity 2
  NoCafRefs
  Str: DmdType LS]
 ShortM.nodeFor =
   \ (ds_di1 :: GHC.Types.Int) (ds1_di2 :: ShortM.T) ->
     case ds1_di2 of wild_B1 {
       ShortM.Nil -> ShortM.Nil;
       ShortM.Node ipv_skm ipv1_skn ipv2_sko ipv3_skp ->
         case ds_di1 of wild1_alk { GHC.Types.I# x#_alm ->
         case GHC.Prim.<# x#_alm ipv_skm of wild2_alu {
           GHC.Bool.False ->
             case GHC.Prim.==# x#_alm ipv_skm of wild11_alx {
               GHC.Bool.False -> ipv2_sko; GHC.Bool.True -> wild_B1
             };
           GHC.Bool.True -> ipv1_skn
         }
         }
     }
 }}}

 This is almost certainly because the length of the error string pushes the
 definition of `val` just over the size limit for inlining (in this case
 the error string will disappear after inlining, but the inliner isn't
 clever enough to know this).

 What's more, this wouldn't be a problem if the inliner was using the
 optimised definition of the record selector, in which the error string had
 been pulled out to the top level.

 We've encountered a few cases like this recently - I sent one to Simon a
 few weeks ago (I don't think I ticketed it, though).

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