depending on whether we have to use a case or let
binding for the expression (see needsCaseBinding).
It's used by the desugarer to avoid building bindings
that give Core Lint a heart attack, although actually
the simplifier deals with them perfectly well. See
also mkCoreLet

So, it does not treat variables as evaluated, unless they say they are.
However, it does treat partial applications and constructor applications
as values, even if their arguments are non-trivial, provided the argument
type is lifted. For example, both of these are values:

Safe to evaluate even if normal order eval might not
evaluate the expression at all, or

Safe not to evaluate even if normal order would do so

It is usually called on arguments of unlifted type, but not always
In particular, Simplify.rebuildCase calls it on lifted types
when a 'case' is a plain seq. See the example in
Note [exprOkForSpeculation: case expressions] below

Precisely, it returns True iff:

The expression guarantees to terminate,
* soon,
* without raising an exception,
* without causing a side effect (e.g. writing a mutable variable)

Note that if exprIsHNF e, then exprOkForSpecuation e.
As an example of the considerations in this test, consider:

let x = case y# +# 1# of { r# -> I# r# }
in E

being translated to:

case y# +# 1# of { r# ->
let x = I# r#
in E
}

We can only do this if the y + 1 is ok for speculation: it has no
side effects, and can't diverge or raise an exception.

Safe to evaluate even if normal order eval might not
evaluate the expression at all, or

Safe not to evaluate even if normal order would do so

It is usually called on arguments of unlifted type, but not always
In particular, Simplify.rebuildCase calls it on lifted types
when a 'case' is a plain seq. See the example in
Note [exprOkForSpeculation: case expressions] below

Precisely, it returns True iff:

The expression guarantees to terminate,
* soon,
* without raising an exception,
* without causing a side effect (e.g. writing a mutable variable)

Note that if exprIsHNF e, then exprOkForSpecuation e.
As an example of the considerations in this test, consider:

let x = case y# +# 1# of { r# -> I# r# }
in E

being translated to:

case y# +# 1# of { r# ->
let x = I# r#
in E
}

We can only do this if the y + 1 is ok for speculation: it has no
side effects, and can't diverge or raise an exception.

Expression and bindings size

A measure of the size of the expressions, strictly greater than 0
It also forces the expression pretty drastically as a side effect
Counts *leaves*, not internal nodes. Types and coercions are not counted.