[commit: ghc] master: Comments about dataToTag# only (05b2587)
git at git.haskell.org
git at git.haskell.org
Fri Oct 12 15:06:07 UTC 2018
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/05b2587b00d0a69ae98b2c4976b85cc3e33a7b49/ghc
>---------------------------------------------------------------
commit 05b2587b00d0a69ae98b2c4976b85cc3e33a7b49
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Fri Oct 12 16:04:57 2018 +0100
Comments about dataToTag# only
>---------------------------------------------------------------
05b2587b00d0a69ae98b2c4976b85cc3e33a7b49
compiler/prelude/PrelRules.hs | 4 ++-
compiler/prelude/primops.txt.pp | 74 +++++++++++++++++++++++++++++------------
2 files changed, 56 insertions(+), 22 deletions(-)
diff --git a/compiler/prelude/PrelRules.hs b/compiler/prelude/PrelRules.hs
index 28c0628..3d419ba 100644
--- a/compiler/prelude/PrelRules.hs
+++ b/compiler/prelude/PrelRules.hs
@@ -1020,7 +1020,7 @@ tagToEnumRule = do
------------------------------
dataToTagRule :: RuleM CoreExpr
--- Rules for dataToTag#
+-- See Note [dataToTag#] in primops.txt.pp
dataToTagRule = a `mplus` b
where
-- dataToTag (tagToEnum x) ==> x
@@ -2105,6 +2105,8 @@ Instead, we deal with turning one branch into DEFAULT in SimplUtils
Note [caseRules for dataToTag]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+See also Note [dataToTag#] in primpops.txt.pp
+
We want to transform
case dataToTag x of
DEFAULT -> e1
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index 303c902..8b327dd 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -2992,27 +2992,59 @@ primop DataToTagOp "dataToTag#" GenPrimOp
primop TagToEnumOp "tagToEnum#" GenPrimOp
Int# -> a
--- Note [dataToTag#]
--- ~~~~~~~~~~~~~~~~~
--- dataToTag# evaluates its argument, so we don't want to float it out.
--- Consider:
---
--- \z. case x of y -> let v = dataToTag# y in ...
---
--- To improve floating, the FloatOut pass (deliberately) does a
--- binder-swap on the case, to give
---
--- \z. case x of y -> let v = dataToTag# x in ...
---
--- Now FloatOut might float that v-binding outside the \z
---
--- let v = dataToTag# x in \z. case x of y -> ...
---
--- But that is bad because that might mean x gets evaluated much too early!
---
--- Solution: make dataToTag# into a can_fail primop. That will stop it floating
--- (see Note [PrimOp can_fail and has_side_effects] in PrimOp). It's a bit of
--- a hack but never mind.
+{- Note [dataToTag#]
+~~~~~~~~~~~~~~~~~~~~
+The primop dataToTag# is unusual because it evaluates its argument.
+Only `SeqOp` shares that property. (Other primops do not do anything
+as fancy as argument evaluation.) The special handling for dataToTag#
+is:
+
+* CoreUtils.exprOkForSpeculation has a special case for DataToTagOp,
+ (actually in app_ok). Most primops with lifted arguments do not
+ evaluate those arguments, but DataToTagOp and SeqOp are two
+ exceptions. We say that they are /never/ ok-for-speculation,
+ regardless of the evaluated-ness of their argument.
+ See CoreUtils Note [PrimOps that evaluate their arguments]
+
+* There is a special case for DataToTagOp in StgCmmExpr.cgExpr,
+ that evaluates its argument and then extracts the tag from
+ the returned value.
+
+* An application like (dataToTag# (Just x)) is optimised by
+ dataToTagRule in PrelRules.
+
+* A case expression like
+ case (dataToTag# e) of <alts>
+ gets transformed t
+ case e of <transformed alts>
+ by PrelRules.caseRules; see Note [caseRules for dataToTag]
+
+See Trac #15696 for a long saga.
+
+Note [dataToTag# hack]
+~~~~~~~~~~~~~~~~~~~~~~
+(This a temporary hack: see Trac #15696 commment:60.)
+
+dataToTag# evaluates its argument, so we don't want to float it out.
+Consider:
+
+ \z. case x of y -> let v = dataToTag# y in ...
+
+To improve floating, the FloatOut pass (deliberately) does a
+binder-swap on the case, to give
+
+ \z. case x of y -> let v = dataToTag# x in ...
+
+Now FloatOut might float that v-binding outside the \z
+
+ let v = dataToTag# x in \z. case x of y -> ...
+
+But that is bad because that might mean x gets evaluated much too early!
+
+Solution: make dataToTag# into a can_fail primop. That will stop it floating
+(see Note [PrimOp can_fail and has_side_effects] in PrimOp). It's a bit of
+a hack but never mind.
+-}
------------------------------------------------------------------------
section "Bytecode operations"
More information about the ghc-commits
mailing list