#1794: map has strange unfolding, code blowup and performance loss
-------------------------------+--------------------------------------------
  Reporter:  simonmar          |          Owner:         
      Type:  bug               |         Status:  new    
  Priority:  normal            |      Milestone:  6.8.1  
 Component:  Compiler          |        Version:  6.6.1  
  Severity:  normal            |       Keywords:         
Difficulty:  Moderate (1 day)  |             Os:  Unknown
  Testcase:                    |   Architecture:  Unknown
-------------------------------+--------------------------------------------
 {{{
 module Test where
 f xs = map (True:) xs
 }}}

 gives this with ghc-6.8.1 -O -ddump-simpl:

 {{{
 ==================== Tidy Core ====================
 Rec {
 Test.go :: [[GHC.Base.Bool]] -> [[GHC.Base.Bool]]
 [GlobalId]
 [Arity 1
  NoCafRefs
  Str: DmdType S]
 Test.go =
   \ (ds_a6S :: [[GHC.Base.Bool]]) ->
     case ds_a6S of wild_a6T {
       [] -> GHC.Base.[] @ [GHC.Base.Bool];
       : y_a6X ys_a6Y ->
         GHC.Base.:
           @ [GHC.Base.Bool]
           (GHC.Base.: @ GHC.Base.Bool GHC.Base.True y_a6X)
           (Test.go ys_a6Y)
     }
 end Rec }

 Test.f :: [[GHC.Base.Bool]] -> [[GHC.Base.Bool]]
 [GlobalId]
 [Arity 1
  NoCafRefs
  Str: DmdType S]
 Test.f =
   \ (xs_a5B :: [[GHC.Base.Bool]]) ->
     case xs_a5B of wild_a5Q {
       [] -> GHC.Base.[] @ [GHC.Base.Bool];
       : x_a5T xs1_a5U ->
         GHC.Base.:
           @ [GHC.Base.Bool]
           (GHC.Base.: @ GHC.Base.Bool GHC.Base.True x_a5T)
           (Test.go xs1_a5U)
     }
 }}}

 This is not, as I first suspected, that the `mapList` rule is not firing -
 the RULEs are firing as they should.  The problem is that `map` itself has
 this unfolding:

 {{{
 map :: forall a b. (a -> b) -> [a] -> [b]
   {- Arity: 2 HasNoCafRefs Strictness: LS
      Unfolding: (\ @ a @ b ds :: a -> b ds1 :: [a] ->
                  case @ [b] ds1 of wild {
                    [] -> GHC.Base.[] @ b
                    : x xs
                    -> GHC.Base.:
                         @ b
                         (ds x)
                         (GHC.Base.foldr
                            @ a
                            @ [b]
                            (\ x1 :: a ys :: [b] -> GHC.Base.: @ b (ds x1)
 ys)
                            (GHC.Base.[] @ b)
                            xs) }) -}
 }}}

 Highly strange - `map`'s unfolding refers to `foldr`, but `map` itself is
 written with the usual recursive definition in `GHC.Base`.  The only
 explanation I can think of is that the RULEs for `map` must have applied
 in `map`'s definition when `GHC.Base` was compiled.

 This is bad, because of the code blowup and also because performance will
 be badly affected for non-optimised compilation (`map` is defined in terms
 of `foldr`).

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