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:
Henrik Böving 2025-09-30 21:51:16 +02:00 committed by GitHub
parent dfd3d18530
commit d88e417cda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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