refactor: tame down dead let eliminator in lambda RC (#10626)
This PR reduces the aggressiveness of the dead let eliminator from lambda RC. The motivation for this is that all other passes in lambda RC respect impurity but the dead let eliminator still operates under the assumption of purity. There is a couple of motivations for the elim dead let elaborator: - unused projections introduced by the ToIR translation - the elim dead branch pass introducing new opportunities - closed term extraction introducing new opportunities
This commit is contained in:
parent
dfd3d18530
commit
d88e417cda
1 changed files with 24 additions and 5 deletions
|
|
@ -13,6 +13,18 @@ public section
|
|||
|
||||
namespace Lean.IR
|
||||
|
||||
/--
|
||||
This function implements a simple heuristic for let values that we know may be dropped because they
|
||||
are pure.
|
||||
-/
|
||||
private def safeToElim (e : Expr) : Bool :=
|
||||
match e with
|
||||
| .ctor .. | .reset .. | .reuse .. | .proj .. | .uproj .. | .sproj .. | .box .. | .unbox ..
|
||||
| .lit .. | .isShared .. | .pap .. => true
|
||||
-- 0-ary full applications are considered constants
|
||||
| .fap _ args => args.isEmpty
|
||||
| .ap .. => false
|
||||
|
||||
partial def reshapeWithoutDead (bs : Array FnBody) (term : FnBody) : FnBody :=
|
||||
let rec reshape (bs : Array FnBody) (b : FnBody) (used : IndexSet) :=
|
||||
if bs.isEmpty then b
|
||||
|
|
@ -23,13 +35,20 @@ partial def reshapeWithoutDead (bs : Array FnBody) (term : FnBody) : FnBody :=
|
|||
let used := curr.collectFreeIndices used
|
||||
let b := curr.setBody b
|
||||
reshape bs b used
|
||||
let keepIfUsed (vidx : Index) :=
|
||||
if used.contains vidx then keep ()
|
||||
else reshape bs b used
|
||||
let keepIfUsedJp (vidx : Index) :=
|
||||
if used.contains vidx then
|
||||
keep ()
|
||||
else
|
||||
reshape bs b used
|
||||
let keepIfUsedLet (vidx : Index) (val : Expr) :=
|
||||
if used.contains vidx || !safeToElim val then
|
||||
keep ()
|
||||
else
|
||||
reshape bs b used
|
||||
match curr with
|
||||
| FnBody.vdecl x _ _ _ => keepIfUsed x.idx
|
||||
| FnBody.vdecl x _ e _ => keepIfUsedLet x.idx e
|
||||
-- TODO: we should keep all struct/union projections because they are used to ensure struct/union values are fully consumed.
|
||||
| FnBody.jdecl j _ _ _ => keepIfUsed j.idx
|
||||
| FnBody.jdecl j _ _ _ => keepIfUsedJp j.idx
|
||||
| _ => keep ()
|
||||
reshape bs term term.freeIndices
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue