@@ -13,6 +13,18 @@ public section
1313
1414namespace Lean.IR
1515
16+ /--
17+ This function implements a simple heuristic for let values that we know may be dropped because they
18+ are pure.
19+ -/
20+ private def safeToElim (e : Expr) : Bool :=
21+ match e with
22+ | .ctor .. | .reset .. | .reuse .. | .proj .. | .uproj .. | .sproj .. | .box .. | .unbox ..
23+ | .lit .. | .isShared .. | .pap .. => true
24+ -- 0-ary full applications are considered constants
25+ | .fap _ args => args.isEmpty
26+ | .ap .. => false
27+
1628partial def reshapeWithoutDead (bs : Array FnBody) (term : FnBody) : FnBody :=
1729 let rec reshape (bs : Array FnBody) (b : FnBody) (used : IndexSet) :=
1830 if bs.isEmpty then b
@@ -23,13 +35,20 @@ partial def reshapeWithoutDead (bs : Array FnBody) (term : FnBody) : FnBody :=
2335 let used := curr.collectFreeIndices used
2436 let b := curr.setBody b
2537 reshape bs b used
26- let keepIfUsed (vidx : Index) :=
27- if used.contains vidx then keep ()
28- else reshape bs b used
38+ let keepIfUsedJp (vidx : Index) :=
39+ if used.contains vidx then
40+ keep ()
41+ else
42+ reshape bs b used
43+ let keepIfUsedLet (vidx : Index) (val : Expr) :=
44+ if used.contains vidx || !safeToElim val then
45+ keep ()
46+ else
47+ reshape bs b used
2948 match curr with
30- | FnBody.vdecl x _ _ _ => keepIfUsed x.idx
49+ | FnBody.vdecl x _ e _ => keepIfUsedLet x.idx e
3150 -- TODO: we should keep all struct/union projections because they are used to ensure struct/union values are fully consumed.
32- | FnBody.jdecl j _ _ _ => keepIfUsed j.idx
51+ | FnBody.jdecl j _ _ _ => keepIfUsedJp j.idx
3352 | _ => keep ()
3453 reshape bs term term.freeIndices
3554
0 commit comments