[GHC] #14687: Investigate differences in Int-In/Outlining
GHC
ghc-devs at haskell.org
Wed Jan 31 23:20:35 UTC 2018
#14687: Investigate differences in Int-In/Outlining
-------------------------------------+-------------------------------------
Reporter: AndreasK | Owner: mpickering
Type: task | Status: new
Priority: lowest | Milestone:
Component: Compiler | Version: 8.2.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by mpickering):
Here is what is happening. I don't know if there are any bugs here or not.
The core for `func` looks like
{{{
-- RHS size: {terms: 17, types: 4, coercions: 0, joins: 0/0}
func :: Int# -> Int# -> Int
[LclIdX,
Arity=2,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [50 40] 90 0}]
func
= \ (ds_dWL :: Int#) (ds_dWM :: Int#) ->
case ds_dWL of {
__DEFAULT -> fail_sXf void#;
1# ->
case ds_dWM of {
__DEFAULT -> fail_sXf void#;
1# -> lvl_sXg;
2# -> lvl_sXh
}
}
}}}
whilst the core for `foo` looks like
{{{
-- RHS size: {terms: 23, types: 5, coercions: 0, joins: 0/0}
foo :: Int# -> Int# -> Int
[LclIdX,
Arity=2,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [100 60] 130 0}]
foo
= \ (ds_dWG :: Int#) (ds_dWH :: Int#) ->
case ds_dWG of {
__DEFAULT -> fail_sXk void#;
1# ->
case ds_dWH of {
__DEFAULT -> fail_sXk void#;
1# -> lvl_sXl
};
2# ->
case ds_dWH of {
__DEFAULT -> fail_sXk void#;
1# -> lvl_sXm
}
}
}}}
It is key to note at this stage that the size of `func` is 90 whilst the
size of `foo` is 130.
GHC has already dutifully floated out the integers at this stage so how do
they reappear?
`foo` is then W/W but `func` is not. The reason for this is that GHC
decides that `func` will certainly get inlined due to the following line
in `CoreUnfold`
{{{
, size - (10 * (arity + 1)) <= ufUseThreshold dflags
}}}
As the size of `func` is 90, this condition returns `True` (90-30 = 60,
ufUseThreshold=60).
So then what happens to `foo`? Well it is W/Wed and then the constants
appear in the worker immediately in `post-worker-wrapper` simplifier run.
It looks likely because the worker has a case-of-case opportunity which
then leaves the variable in a case position. However I didn't verify
exactly why the variable is inlined as it didn't appear in `-ddump-
inlinings`.
The worker is then inlined back into the wrapper and thus they reappear in
the definition.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14687#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list