[GHC] #9509: No automatic specialization of inlinable imports in 7.8

#9509: No automatic specialization of inlinable imports in 7.8
-------------------------------------+-------------------------------------
Reporter: dolio | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.3
Keywords: | Operating System:
Architecture: Unknown/Multiple | Unknown/Multiple
Difficulty: Unknown | Type of failure: Runtime
Blocked By: | performance bug
Related Tickets: | Test Case:
| Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
According to the GHC manual, any uses of an imported definition that is
overloaded and INLINABLE will automatically cause a SPECIALIZE to be
generated for those uses, if appropriate. However, this no longer appears
to be the case in 7.8(.3). Here is a simple test case:
{{{#!hs
module A (foo) where
import Data.IORef
foo :: Ord a => a -> IO a
foo x = newIORef x >>= readIORef >>= \y -> case compare x y of LT ->
return x ; _ -> return y
{-# INLINABLE foo #-}
}}}
{{{#!hs
module Main (main) where
import A
main = foo (5 :: Int) >>= print
}}}
`foo` is constructed to be long enough that GHC 7.8.3 will elect to not
inline it.
When compiling with 7.6.3, the core contains the following:
{{{
Main.$sfoo1
:: GHC.Types.Int
-> GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Types.Int #)
[GblId,
Arity=2,
Caf=NoCafRefs,
Str=DmdType LL,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=2, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=IF_ARGS [20 0] 55 30}]
Main.$sfoo1 =
\ (x_XkE :: GHC.Types.Int)
(eta_B1 :: GHC.Prim.State# GHC.Prim.RealWorld) ->
case GHC.Prim.newMutVar#
@ GHC.Types.Int @ GHC.Prim.RealWorld x_XkE eta_B1
of _ { (# ipv_amT, ipv1_amU #) ->
case GHC.Prim.readMutVar#
@ GHC.Prim.RealWorld @ GHC.Types.Int ipv1_amU ipv_amT
of ds1_amJ { (# ipv2_Xn8, ipv3_Xna #) ->
case x_XkE of wild_axu { GHC.Types.I# x#_axw ->
case ipv3_Xna of _ { GHC.Types.I# y#_axA ->
case GHC.Prim.<# x#_axw y#_axA of _ {
GHC.Types.False -> ds1_amJ;
GHC.Types.True -> (# ipv2_Xn8, wild_axu #)
}
}
}
}
}
Main.$sfoo :: GHC.Types.Int -> GHC.Types.IO GHC.Types.Int
[GblId,
Arity=2,
Caf=NoCafRefs,
Str=DmdType LL,
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
ConLike=True, WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
Main.$sfoo =
Main.$sfoo1
`cast` (

#9509: No automatic specialization of inlinable imports in 7.8 -------------------------------------+------------------------------------- Reporter: dolio | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: Runtime | Blocked By: performance bug | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by alpmestan): * cc: alpmestan@… (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9509#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9509: No automatic specialization of inlinable imports in 7.8 -------------------------------------+------------------------------------- Reporter: dolio | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.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: | -------------------------------------+------------------------------------- Changes (by nfrisby): * cc: nfrisby (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9509#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9509: No automatic specialization of inlinable imports in 7.8 -------------------------------------+------------------------------------- Reporter: dolio | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.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 nfrisby): With no pragma, {{{foo}}} has the following unfolding and gets inlined. {{{ Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True) }}} With the {{{INLINABLE}}} pragma, {{{foo}}} has the following unfolding and does not get inlined. {{{ Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 210 60 }}} In both cases, its RHS is just a cast. I think the inferred {{{IF_ARGS}}} guidance is the cause of this unexpected behavior, because it violates the {{{"Mind you, then 'choose' will be inlined (since RHS is trivial)"}}} assumption in {{{Note [Specialisation shape]}}}, which otherwise anticipated this consequence of the ({{{IO}}}) newtype. https://github.com/ghc/ghc/blob/c36904d66f30d4386a231ce365a056962a881767/com... I did not investigate where the {{{IF_ARGS}}} guidance is coming from for such a trivial declaration. Seems like a leftover from the "actual" RHS (at the newtype's representative type), in this specific example and context. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9509#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9509: No automatic specialization of inlinable imports in 7.8 -------------------------------------+------------------------------------- Reporter: dolio | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.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 nfrisby): I now have a theory. Based on some of the notes I've found in the source code, I'm concluding (/recalling!) that "unfoldings should only be simplified gently" and "gently implies no eta-expansion". Notably, {{{SimplUtils.updModeForStableUnfoldings}}} sets {{{sm_eta_expand = False}}}, and the simplifier invokes that before entering a stable unfolding or a rule. However, in this case, we're seeing eta-expansion in the unfolding! I believe that is due to [https://github.com/ghc/ghc/blob/876b00ba25a615423f48b0cf9d443a9fd5dbd6f4/com... this use] of {{{gopt Opt_DoLambdaEtaExpansion dflags}}} in {{{SimplUtils.mkLam}}} --- it's checking the {{{DynFlag}}} instead of checking the {{{sm_eta_expand}}} flag within the {{{SimplEnv}}} (which is not passed to {{{mkLam}}}). Parts of the simplifier, notably {{{simplLam}}}, call {{{mkLam}}}. I've made "the fix" locally, and it indeed fixes this ticket's example case. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9509#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9509: No automatic specialization of inlinable imports in 7.8 -------------------------------------+------------------------------------- Reporter: dolio | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.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): Nicolas I think you are spot on. I'll fix. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9509#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9509: No automatic specialization of inlinable imports in 7.8
-------------------------------------+-------------------------------------
Reporter: dolio | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.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 Simon Peyton Jones

#9509: No automatic specialization of inlinable imports in 7.8 -------------------------------------+------------------------------------- Reporter: dolio | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Runtime | Test Case: performance bug | simplCore/should_compile/T9509 Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by simonpj): * testcase: => simplCore/should_compile/T9509 * status: new => closed * resolution: => fixed Comment: Thanks for the analysis! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9509#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC