[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