fn expressions_used(
module: &Module,
function: &Function,
block: &Block,
extra_roots: impl IntoIterator<Item = Handle<Expression>>,
stop_at: &HandleSet<Expression>,
) -> HandleSet<Expression>Expand description
Return the expressions of function that the code generated for block
and extra_roots will refer to, directly or indirectly.
This is wider than what block needs the values of, because we do no dead
code elimination: Writer::put_block writes out a definition for every
expression it bakes, whether or not anything reads it, and that definition
refers to the expression’s operands. Hence
trace_block_including_emits rather than trace_block. Miss those and
a dead definition would leave its operands un-hoisted, and continuing
would re-evaluate them in place - or, for a statement result, reach the
unreachable! in Writer::put_expression, which has no inline form to
fall back on.
The search does not continue past an expression in stop_at: such an
expression is marked if something refers to it, but the search does not
follow it to its operands. Anything reachable only through it is therefore
left out.