lean4-htt/tests/lean/run/more_jps.lean
Henrik Böving cc046e0c18
perf: improve join point finding (#10999)
This PR improves join point finding in the compiler through two means:
1. We now handle situations where a function `f` can only become a join
point when a function `g`
   becomes a join point as well correctly.
2. We introduce a second join point finding pass after specialisation
and before the following
simplification pass, as the specialiser might have introduced new join
point opportunities for
   the simplifier to exploit.

Notably in the code from #10995 we now correctly detect the missing join
point which required both
of these changes to be made.

Closes: #10995
2025-10-30 15:05:11 +00:00

80 lines
2.5 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@[specialize 3 4] def List.foldrNonTR (f : α → β → β) (init : β) : (l : List α) → β
| [] => init
| a :: l => f a (foldrNonTR f init l)
@[always_inline, inline]
def List.forBreak_ {α : Type u} {m : Type w → Type x} [Monad m] (xs : List α) (s : σ) (body : α → OptionT (StateT σ (ExceptT ρ m)) PUnit) (kreturn : ρ → m γ) (kbreak : σ → m γ) : m γ :=
List.foldrNonTR
(fun a acc s => do
let e ← body a s
match e with
| .error r => kreturn r
| .ok (.some _, s) => acc s
| .ok (none, s) => kbreak s)
kbreak
xs
s
/--
trace: [Compiler.saveBase] size: 25
def List.foldrNonTR._at_._example.spec_0 x.1 _y.2 : Nat :=
jp _jp.3 x : Nat :=
let _x.4 := 13;
let x := Nat.add x _x.4;
let x := Nat.add x _x.4;
let x := Nat.add x _x.4;
let x := Nat.add x _x.4;
let x := Nat.add x _x.4;
let x := Nat.add x _x.4;
let x := Nat.add x _x.4;
return x;
cases x.1 : Nat
| List.nil =>
goto _jp.3 _y.2
| List.cons head.5 tail.6 =>
let _x.7 := 0;
let _x.8 := instDecidableEqNat _y.2 _x.7;
cases _x.8 : Nat
| Decidable.isFalse x.9 =>
let _x.10 := 10;
let _x.11 := Nat.decLt _x.10 _y.2;
cases _x.11 : Nat
| Decidable.isFalse x.12 =>
let _x.13 := Nat.add _y.2 head.5;
let _x.14 := List.foldrNonTR._at_._example.spec_0 tail.6 _x.13;
return _x.14
| Decidable.isTrue x.15 =>
goto _jp.3 _y.2
| Decidable.isTrue x.16 =>
return _y.2
[Compiler.saveBase] size: 9
def _example : Nat :=
let x := 42;
let _x.1 := 1;
let _x.2 := 2;
let _x.3 := 3;
let _x.4 := @List.nil _;
let _x.5 := @List.cons _ _x.3 _x.4;
let _x.6 := @List.cons _ _x.2 _x.5;
let _x.7 := @List.cons _ _x.1 _x.6;
let _x.8 := List.foldrNonTR._at_._example.spec_0 _x.7 x;
return _x.8
-/
#guard_msgs in
set_option trace.Compiler.saveBase true in
example := Id.run do
let x := 42;
List.forBreak_ (m:=Id) (ρ := Nat) [1, 2, 3] x (fun i => do
let x ← get
if x = 0 then throw (m := ExceptT Nat Id) x -- return
else if x > 10 then failure (f := OptionT _) -- break
else set (x + i) >>= fun _ => pure ()) -- continue
pure fun x => do
let x := x + 13;
let x := x + 13;
let x := x + 13;
let x := x + 13;
let x := x + 13;
let x := x + 13;
let x := x + 13;
return x