[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