[GHC] #11710: Fusion of a simple listArray call is very fragile
GHC
ghc-devs at haskell.org
Wed Mar 16 16:08:56 UTC 2016
#11710: Fusion of a simple listArray call is very fragile
-------------------------------------+-------------------------------------
Reporter: bgamari | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.3
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Runtime | Unknown/Multiple
performance bug | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Yes, see `Note [Desugaring explicit lists]` in `DsExpr`, about the "static
tail" of
a list.
For `listArray (1,100) [1,2` we get
{{{
let {
$dIx_aHr :: Ix Integer
[LclId, Str=DmdType]
$dIx_aHr = GHC.Arr.$fIxInteger } in
let {
$dNum_aSd :: Num Integer
[LclId, Str=DmdType]
$dNum_aSd = GHC.Num.$fNumInteger } in
let {
$dNum_aSh :: Num Integer
[LclId, Str=DmdType]
$dNum_aSh = $dNum_aSd } in
let {
$dNum_aSj :: Num Integer
[LclId, Str=DmdType]
$dNum_aSj = $dNum_aSh } in
let {
$dNum_aSf :: Num Integer
[LclId, Str=DmdType]
$dNum_aSf = $dNum_aSd } in
letrec {
alex_table_aSk :: Array Integer Integer
[LclId, Str=DmdType]
alex_table_aSk =
listArray
@ Integer
@ Integer
$dIx_aHr
(0, 100)
(GHC.Types.:
@ Integer
1
(GHC.Types.: @ Integer 2 (GHC.Types.[] @ Integer))); }
}}}
(The dead `Num` dictionaries happen because the desugarer short-circuits
the calls to `fromInteger @ Integer`.)
Notice that the list has no free vars, so via the "static tail" trick in
`DsExpr` we generate an explicit list.
But for `listArray (0,100) [-1,2]` we get
{{{
let {
$dIx_aHs :: Ix Integer
[LclId, Str=DmdType]
$dIx_aHs = GHC.Arr.$fIxInteger } in
let {
$dNum_aSe :: Num Integer
[LclId, Str=DmdType]
$dNum_aSe = GHC.Num.$fNumInteger } in
let {
$dNum_aSi :: Num Integer
[LclId, Str=DmdType]
$dNum_aSi = $dNum_aSe } in
let {
$dNum_aSm :: Num Integer
[LclId, Str=DmdType]
$dNum_aSm = $dNum_aSi } in
let {
$dNum_aSk :: Num Integer
[LclId, Str=DmdType]
$dNum_aSk = $dNum_aSi } in
let {
$dNum_aSg :: Num Integer
[LclId, Str=DmdType]
$dNum_aSg = $dNum_aSe } in
letrec {
alex_table_aSn :: Array Integer Integer
[LclId, Str=DmdType]
alex_table_aSn =
listArray
@ Integer
@ Integer
$dIx_aHs
(0, 100)
(GHC.Base.build
@ Integer
(\ (@ a_d22o)
(c_d22p :: Integer -> a_d22o -> a_d22o)
(n_d22q :: a_d22o) ->
c_d22p
(negate @ Integer $dNum_aSi 1)
(GHC.Base.foldr
@ Integer
@ a_d22o
c_d22p
n_d22q
(GHC.Types.: @ Integer 2 (GHC.Types.[] @ Integer)))));
} in
}}}
Now the calls to `negate` have a dictionary `$dNum_asi` which isn't top-
level,
so the "static tail" stuff fails and we generate a `build`.
**This is obviously far too fragile. I think we should just drop the
"static tail" idea entirely.**
It's never bad to generate the build form, except for generating bloated
code; see #11707.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11710#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list