[GHC] #11710: Fusion of a simple listArray call is very fragile

GHC ghc-devs at haskell.org
Tue Mar 15 12:14:35 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 bgamari):

 The reason for this inconsistency appears to be the dynamic prefix log in
 `dsExplicitList`. Let's look at the desugared output that gave rise to
 comment:2,
 {{{#!hs
 arr =
   listArray
     GHC.Arr.$fIxInt
     (GHC.Types.I# 0, GHC.Types.I# 10)
     (GHC.Base.build
        (\ (@ a) (c [OS=OneShot] :: Int -> a -> a) (n [OS=OneShot] :: a) ->
           c (GHC.Types.I# 1)
             (c (GHC.Types.I# 1)
                (c (GHC.Types.I# 1)
                   (c (negate GHC.Num.$fNumInt (GHC.Types.I# 1))
                      (GHC.Base.foldr
                         c
                         n
                         (GHC.Types.:
                            (GHC.Types.I# 1)
                            (GHC.Types.:
                               (GHC.Types.I# 1)
                               (GHC.Types.:
                                  (GHC.Types.I# 1)
                                  (GHC.Types.:
                                     (GHC.Types.I# 1)
                                     (GHC.Types.:
                                        (GHC.Types.I# 1)
                                        (GHC.Types.: (GHC.Types.I# 1)
 (GHC.Types.[])))))))))))))
 }}}

 We see that the desugarer took everything up to and including the `-1`
 element as the dynamic prefix.

 The dynamic prefix is defined in `dsExplicitList` as,
 {{{#!hs
 is_static :: CoreExpr -> Bool
 is_static e = all is_static_var (varSetElems (exprFreeVars e))

 is_static_var :: Var -> Bool
 is_static_var v
   | isId v = isExternalName (idName v)  -- Top-level things are given
 external names
   | otherwise = False                   -- Type variables

 (dynamic_prefix, static_suffix) = spanTail is_static xs'
 }}}

 That is, anything expression having a free variable with an external name
 (e.g. `negate` in the current example) is considered to be non-static,
 even if it will eventually be resolved to something static during
 simplification.

 If we consider that `foldr`/`build` is an optimization, the above behavior
 seems reasonable, preserving potential optimization opportunities by
 liberally applying `build` desugaring. This does, however, lead to
 slightly longer compilation times even in the case where fusion didn't
 fire as we need to rewrite `build` to a plain list during simplification.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11710#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list