summaryrefslogtreecommitdiff
path: root/compiler/prelude/primops.txt.pp
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2018-10-12 16:04:57 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2018-10-12 16:05:17 +0100
commit05b2587b00d0a69ae98b2c4976b85cc3e33a7b49 (patch)
treecee6e542f847557d9e5789a65d736d3e58041e85 /compiler/prelude/primops.txt.pp
parentce7a1c4ae4c93f2d0d3d7a0b573ddd876fc855c2 (diff)
downloadhaskell-05b2587b00d0a69ae98b2c4976b85cc3e33a7b49.tar.gz
Comments about dataToTag# only
Diffstat (limited to 'compiler/prelude/primops.txt.pp')
-rw-r--r--compiler/prelude/primops.txt.pp74
1 files changed, 53 insertions, 21 deletions
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index 303c902c83..8b327ddbc4 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"