From 05b2587b00d0a69ae98b2c4976b85cc3e33a7b49 Mon Sep 17 00:00:00 2001 From: Simon Peyton Jones Date: Fri, 12 Oct 2018 16:04:57 +0100 Subject: Comments about dataToTag# only --- compiler/prelude/primops.txt.pp | 74 +++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 21 deletions(-) (limited to 'compiler/prelude/primops.txt.pp') 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 + gets transformed t + case e of + 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" -- cgit v1.2.1