Note [exprOkForSpeculation and evaluated variables]

GHC/Core/Utils.hs:2100 compiler

Consider these examples:
 * case x of y { DEFAULT -> ....y.... }
   Should 'y' (alone) be considered ok-for-speculation?

 * case x of y { DEFAULT -> ....let z = dataToTagLarge# y... }
   Should (dataToTagLarge# y) be considered ok-for-spec? Recall that
     dataToTagLarge# :: forall a. a -> Int#
   must always evaluate its argument. (See also Note [DataToTag overview].)

You could argue 'yes', because in the case alternative we know that
'y' is evaluated.  But the binder-swap transformation, which is
extremely useful for float-out, changes these expressions to
   case x of y { DEFAULT -> ....x.... }
   case x of y { DEFAULT -> ....let z = dataToTagLarge# x... }

And now the expression does not obey the let-can-float invariant!  Yikes!
Moreover we really might float (dataToTagLarge# x) outside the case,
and then it really, really doesn't obey the let-can-float invariant.

The solution is simple: exprOkForSpeculation does not try to take
advantage of the evaluated-ness of (lifted) variables.  And it returns
False (always) for primops that perform evaluation.  We achieve the latter
by marking the relevant primops as "ThrowsException" or
"ReadWriteEffect"; see also Note [Classifying primop effects] in
GHC.Builtin.PrimOps.

Note that exprIsHNF /can/ and does take advantage of evaluated-ness;
it doesn't have the trickiness of the let-can-float invariant to worry about.

************************************************************************
*                                                                      *
             exprIsHNF, exprIsConLike
*                                                                      *
************************************************************************

References 2

Referenced by 6