[GHC] #7114: Cannot recover (good) inlining behaviour from 7.0.2 in 7.4.1
GHC
cvs-ghc at haskell.org
Fri Aug 3 15:06:41 CEST 2012
#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
More information about the Glasgow-haskell-bugs
mailing list