#7114: Cannot recover (good) inlining behaviour from 7.0.2 in 7.4.1
------------------------------+---------------------------------------------
 Reporter:  dreixel           |          Owner:                  
     Type:  bug               |         Status:  new             
 Priority:  normal            |      Component:  Compiler        
  Version:  7.4.1             |       Keywords:                  
       Os:  Unknown/Multiple  |   Architecture:  Unknown/Multiple
  Failure:  None/Unknown      |       Testcase:                  
Blockedby:                    |       Blocking:                  
  Related:                    |  
------------------------------+---------------------------------------------
 (I'm sorry that this test case is so large.)

 The attached module `Code3.hs` is a highly simplified version of a generic
 implementation of enumeration, followed by its instantiation to a datatype
 of lists of integers. The goal is to drive the simplifier to fully
 specialise the generic version to an optimised version for lists, without
 any reference to the generic representation constructors.

 With GHC 7.0.2, the (interesting part of the) attached module compiles to
 the following core code (my renaming):
 {{{
 enumNil :: [Code2.List]
 [GblId, Caf=NoCafRefs]
 enumNil =
   GHC.Types.: @ Code2.List Code2.Nil (GHC.Types.[] @ Code2.List)

 Rec {
 lvl1_roO :: GHC.Types.Int -> [Code2.List]
 [GblId, Arity=1]
 lvl1_roO =
   \ (x_XnO :: GHC.Types.Int) ->
     GHC.Base.map
       @ Code2.List
       @ Code2.List
       (\ (x1_XnN :: Code2.List) -> Code2.Cons x_XnO x1_XnN)
       enumList

 lvl2_roR :: [[Code2.List]]
 [GblId]
 lvl2_roR =
   GHC.Base.map
     @ GHC.Types.Int @ [Code2.List] lvl1_roO enumInt

 enumCons :: [Code2.List]
 [GblId]
 enumCons = Code2.diag @ Code2.List lvl2_roR

 enumList [Occ=LoopBreaker] :: [Code2.List]
 [GblId, Str=DmdType]
 enumList = Code2.||| @ Code2.List enumNil enumCons
 end Rec }
 }}}

 This is exactly what is intended: no more generic representation stuff.
 GHC 7.4.1, however, doesn't quite achieve this, instead leaving us with
 the following:
 {{{
 enumNil :: [Code2.List]
 [GblId, Caf=NoCafRefs]
 enumNil =
   GHC.Types.: @ Code2.List Code2.Nil (GHC.Types.[] @ Code2.List)

 Rec {
 a_rme :: [Code2.K1 Code2.List]
 [GblId, Str=DmdType]
 a_rme =
   GHC.Base.map
     @ Code2.List
     @ (Code2.K1 Code2.List)
     (Code2.K1 @ Code2.List)
     enumList

 lvl1_rmf :: GHC.Types.Int -> [Code2.List]
 [GblId, Arity=1]
 lvl1_rmf =
   \ (x_Xmk :: GHC.Types.Int) ->
     GHC.Base.map
       @ (Code2.K1 Code2.List)
       @ Code2.List
       (\ (x1_Xn9 :: Code2.K1 Code2.List) ->
          case x1_Xn9 of _ { Code2.K1 b_aaM -> Code2.Cons x_Xmk b_aaM })
       a_rme

 lvl2_rmg :: [[Code2.List]]
 [GblId]
 lvl2_rmg =
   GHC.Base.map
     @ GHC.Types.Int @ [Code2.List] lvl1_rmf enumInt

 enumCons :: [Code2.List]
 [GblId]
 enumCons = Code2.diag @ Code2.List lvl2_rmg

 enumList [Occ=LoopBreaker] :: [Code2.List]
 [GblId, Str=DmdType]
 enumList = Code2.||| @ Code2.List enumNil enumCons
 end Rec }
 }}}

 The strange part is the interaction between the `lvl1_rmf` and `a_rme`
 functions: basically `a_rme` maps `K1` over a list, and `lvl1_rmf` maps a
 function that takes this `K1` away.

 I have no idea why 7.4.1 leaves this residue around. I have played with
 different inline pragmas and rewrite rules, but so far have been unable to
 convince GHC 7.4.1 to just do what 7.0.2 did. Turning `K1` into a
 `newtype` doesn't help (we're left with a newtype coercion instead).

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7114>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to