[commit: ghc] master: Mark reallyUnsafePtrEquality# as can_fail (b3576ed)
git at git.haskell.org
git at git.haskell.org
Tue Jan 31 23:49:44 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/b3576ed22570364f917c620a3cd29709355e4d51/ghc
>---------------------------------------------------------------
commit b3576ed22570364f917c620a3cd29709355e4d51
Author: David Feuer <david.feuer at gmail.com>
Date: Tue Jan 31 18:44:14 2017 -0500
Mark reallyUnsafePtrEquality# as can_fail
As described in the note, floating `reallyUnsafePtrEquality#`
out can make it much less precise. Marking it `can_fail` will
prevent it from floating out, which I believe is particularly
important in light of 5a9a1738023aeb742e537fb4a59c4aa8fecc1f8a,
and should also help prevent let/app invariant failures as seen
in #11444 and #13027.
Reviewers: simonpj, austin, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2987
GHC Trac Issues: #13027, #11444
>---------------------------------------------------------------
b3576ed22570364f917c620a3cd29709355e4d51
compiler/prelude/primops.txt.pp | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index 6795ca7..5245272 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -2542,6 +2542,41 @@ section "Unsafe pointer equality"
primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp
a -> a -> Int#
+ { Returns 1# if the given pointers are equal and 0# otherwise. }
+ with
+ can_fail = True -- See Note [reallyUnsafePtrEquality#]
+
+
+-- Note [reallyUnsafePtrEquality#]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- reallyUnsafePtrEquality# can't actually fail, per se, but we mark it can_fail
+-- anyway. Until 5a9a1738023a, GHC considered primops okay for speculation only
+-- when their arguments were known to be forced. This was unnecessarily
+-- conservative, but it prevented reallyUnsafePtrEquality# from floating out of
+-- places where its arguments were known to be forced. Unfortunately, GHC could
+-- sometimes lose track of whether those arguments were forced, leading to let/app
+-- invariant failures (see Trac 13027 and the discussion in Trac 11444). Now that
+-- ok_for_speculation skips over lifted arguments, we need to explicitly prevent
+-- reallyUnsafePtrEquality# from floating out. The reasons are closely related
+-- to those described in Note [dataToTag#], although the consequences are less
+-- severe. Imagine if we had
+--
+-- \x y . case x of x'
+-- DEFAULT ->
+-- case y of y'
+-- DEFAULT ->
+-- let eq = reallyUnsafePtrEquality# x' y'
+-- in ...
+--
+-- If the let floats out, we'll get
+--
+-- \x y . let eq = reallyUnsafePtrEquality# x y
+-- in case x of ...
+--
+-- The trouble is that pointer equality between thunks is very different
+-- from pointer equality between the values those thunks reduce to, and the latter
+-- is typically much more precise.
------------------------------------------------------------------------
section "Parallelism"
More information about the ghc-commits
mailing list