[GHC] #13027: Core lint errors compiling containers HEAD with GHC HEAD
GHC
ghc-devs at haskell.org
Wed Jan 11 09:11:19 UTC 2017
#13027: Core lint errors compiling containers HEAD with GHC HEAD
-------------------------------------+-------------------------------------
Reporter: erikd | Owner:
Type: bug | Status: new
Priority: normal | Milestone: 8.2.1
Component: Compiler | Version: 8.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: Building GHC | Test Case:
failed | simplCore/should_compile/T13027
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
> Is there some way to make this tracking more robust?
Yes: (1) and (2) are precisely about ensuring that when something is
supposed to be evaluated, it really is.
> Is there a reason not to make exprOkForSpeculation more lenient for
reallyUnsafePtrEquality#
No, no big reason. We could consult the primops strictness info; or we
could have a special case in `CoreUtils.app_ok`.
--------
HOWEVER, in answering this question I also came across this (in
`CoreUtils`):
{{{
Note [dataToTag speculation]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Is this OK?
f x = let v::Int# = dataToTag# x
in ...
We say "yes", even though 'x' may not be evaluated. Reasons
* dataToTag#'s strictness means that its argument often will be
evaluated, but FloatOut makes that temporarily untrue
case x of y -> let v = dataToTag# y in ...
-->
case x of y -> let v = dataToTag# x in ...
Note that we look at 'x' instead of 'y' (this is to improve
floating in FloatOut). So Lint complains.
Moreover, it really *might* improve floating to let the
v-binding float out
* CorePrep makes sure dataToTag#'s argument is evaluated, just
before code gen. Until then, it's not guaranteed
}}}
The plot thickens. When I wrote this I clearly intended that (contrary to
(2)) Core would ''not'' guarantee that the argument to `dataToTag#` is
evaluated. Instead, we arrange that it is evaluated to being with; accept
that may not be true forever; but re-establish it in `CorePrep` if
necessary.
That is indeed a viable path. Moreover, the first bullet of the above Note
is persuasive: guaranteeing evaluated-ness is quite hard!
But if we follow that path (an ''alternative'' to the to-dos in
comment:21), then we should do consistently:
* Ensure that `exprOkForSpeculation` on ''any'' primop does not look at
lifted arguments (like the current special case for `dataToTag#`)
What about strict constructors? We could use `CorePrep` to ensure that
arguments to strict constructors are evaluated, just as we do for
`dataToTag#`. But for `dataToTag#` the actual argument must be a pointer
to the evaluated object, otherwise `dataToTag#` will fail (give a bogus
answer). But for strict constructors all we care about is that the
argument has been evaluated (a semantic property), and that is ensured by
the wrapper. To be sure, a bogus Core-to-Core pass could apply the
constructor to a non-evaluated argument, but nothing would actually go
wrong. So arguably it'd be redundant to add extra evals in `CorePrep`.
The third to-do in comment:21 would still be useful. Knowing evaluated-
ness is always a good thing.
Bottom line: this alternative path looks attractive. In summary it would
entail
* Treating all primops with boxed arguments like `dataToTag#` in
`exprOkForSpeculation`.
* Documenting the reasoning along the lines above.
* Make worker/wrapper produce eval'd flags on the wrapper for CPR.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13027#comment:23>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list