Remark: the insertResetReuse transformation is applied before we have
inserted inc/dec
instructions, and performed lower level optimizations
that introduce the instructions release
and set
.
Remark: the functions S
, D
and R
defined here implement the
corresponding functions in the paper "Counting Immutable Beans"
Here are the main differences:
- We use the State monad to manage the generation of fresh variable names.
- Support for join points, and
uset
andsset
instructions for unboxed data. D
uses the auxiliary functionDmain
.Dmain
returns a pair(b, found)
to avoid quadratic behavior when checking the last occurrence of the variablex
.- Because we have join points in the actual implementation, a variable may be live even if it
does not occur in a function body. See example at
livevars.lean
.
- lctx : Lean.IR.LocalContext
- alreadyFound : Lean.PHashSet Lean.IR.VarId
Contains all variables in
cases
statements in the current path and variables that are already inreset
statements when we invokeR
.We use this information to prevent double-reset in code such as
case x_i : obj of Prod.mk → case x_i : obj of Prod.mk → ...
A variable can already be in a
reset
statement when we invokeR
because we execute it with and withoutrelaxedReuse
. - relaxedReuse : Bool
If
relaxedReuse := true
, then allow memory cells from different constructors to be reused. For example, we can reuse aPSigma.mk
to allocate aProd.mk
. To avoid counterintuitive behavior, we first tryrelaxedReuse := false
, and thenrelaxedReuse := true
.