#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