The decision of the float mechanism.
- arm: Lean.Name → Lean.Compiler.LCNF.FloatLetIn.Decision
Push into the arm with name
name
. - default: Lean.Compiler.LCNF.FloatLetIn.Decision
Push into the default arm.
- dont: Lean.Compiler.LCNF.FloatLetIn.Decision
Dont move this declaration it is needed where it is right now.
- unknown: Lean.Compiler.LCNF.FloatLetIn.Decision
No decision has been made yet.
Instances For
The context for BaseFloatM
.
- decls : List Lean.Compiler.LCNF.CodeDecl
All the declarations that were collected in the current LCNF basic block up to the current statement (in reverse order for efficiency).
Instances For
The state for FloatM
A map from identifiers of declarations to their current decision.
A map from decisions (excluding
unknown
) to the declarations with these decisions (in correct order). Basically:- Which declarations do we not move
- Which declarations do we move into a certain arm
- Which declarations do we move into the default arm
Instances For
Use to collect relevant declarations for the floating mechanism.
Equations
Instances For
Use to compute the actual floating.
Equations
Instances For
Add decl
to the list of declarations and run x
with that updated context.
Equations
- Lean.Compiler.LCNF.FloatLetIn.withNewCandidate decl x = withReader (fun (r : Lean.Compiler.LCNF.FloatLetIn.BaseFloatContext) => { decls := decl :: r.decls }) x
Instances For
Run x
with an empty list of declarations.
Equations
- Lean.Compiler.LCNF.FloatLetIn.withNewScope x = withReader (fun (x : Lean.Compiler.LCNF.FloatLetIn.BaseFloatContext) => { decls := [] }) x
Instances For
Whether to ignore decl
for the floating mechanism. We want to do this if:
decl
' is storing a typeclass instancedecl
is a projection from a variable that is storing a typeclass instance
Equations
- One or more equations did not get rendered due to their size.
Instances For
Compute the initial decision for all declarations that BaseFloatM
collected
up to this point, with respect to cs
. The initial decisions are:
dont
if the declaration is detected byignore?
dont
if the declaration is the discriminant ofcs
since we obviously need the discriminant to be computed before the match.dont
if we see the declaration being used in more than one cases armarm
ordefault
if we see the declaration only being used in exactly one cases armunknown
otherwise
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Instances For
Compute the initial new arms. This will just set up a map from all arms of
cs
to empty Array
s, plus one additional entry for dont
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Will:
- put
decl
into thedont
arm - decide that any free variable that occurs in
decl
and is a declaration of interest as not getting moved either.
let x := ...
let y := ...
let z := x + y
cases z with
| n => z * x
| m => z * y
Here x
and y
are originally marked as getting floated into n
and m
respectively but since z
can't be moved we don't want that to move x
and y
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Will:
- put
decl
into the arm it is marked to be moved into - for any variables that might occur in
decl
and are of interest:- if they are already meant to be floated into the same arm or not at all leave them untouched:
If we are atlet x := ... let y := x + z cases z with | n => x * y | m => z
y
x
is already marked to be floated inton
as well. - if there hasn't be a decision yet, that is they are marked with
.unknown
we float them into the same arm as the current value:
Herelet x := .. let y := x + 2 cases z with | n => y | m => z
x
is initially marked as.unknown
since it occurs in no branch, however since we want to movey
into then
branch we can also decide to movex
into then
branch. Note that this decision might be revoked later on in the case of:
When we visitlet x := .. let a := x + 1 let y := x + 2 cases z with | n => y | m => a
a
x
is now marked as getting moved inton
but since it also occurs ina
which wants to be moved somewhere else we will instead decide to not movex
at all. - if they are meant to be floated somewhere else decide that they won't get floated:
If we are atlet x := ... let y := x + z cases z with | n => y | m => x
y
x
is still marked to be moved but we don't want that.
- if they are already meant to be floated into the same arm or not at all leave them untouched:
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Iterate through decl
, pushing local declarations that are only used in one
control flow arm into said arm in order to avoid useless computations.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Iterate through the collected declarations, determining from the bottom up whether they (and the declarations they refer to) should get moved down into the arms of the cases statement or not.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- decl.floatLetIn = Lean.Compiler.LCNF.FloatLetIn.floatLetIn decl
Instances For
Equations
- Lean.Compiler.LCNF.floatLetIn phase occurrence = Lean.Compiler.LCNF.Pass.mkPerDeclaration `floatLetIn Lean.Compiler.LCNF.Decl.floatLetIn phase occurrence