@@ -34,6 +34,23 @@ structure CandidateInfo where
3434 associated : Std.HashSet FVarId
3535 deriving Inhabited
3636
37+ structure FindCtx where
38+ /--
39+ The current definition depth is defined by how many `fun` binders we are
40+ nested in at the current point. Note that this does *not* include `jp`
41+ binders.
42+ -/
43+ definitionDepth : Nat := 0
44+ /--
45+ A map from function declarations that are currently in scope to their
46+ definition depth.
47+ -/
48+ scope : FVarIdMap Nat := {}
49+ /--
50+ The current function binder we are inside of if any.
51+ -/
52+ currentFunction : Option FVarId := none
53+
3754/--
3855The state for the join point candidate finder.
3956-/
@@ -42,15 +59,11 @@ structure FindState where
4259 All current join point candidates accessible by their `FVarId`.
4360 -/
4461 candidates : Std.HashMap FVarId CandidateInfo := ∅
45- /--
46- The `FVarId`s of all `fun` declarations that were declared within the
47- current `fun`.
48- -/
49- scope : Std.HashSet FVarId := ∅
5062
51- abbrev ReplaceCtx := Std.HashMap FVarId Name
5263
53- abbrev FindM := ReaderT (Option FVarId) StateRefT FindState ScopeM
64+ abbrev FindM := ReaderT FindCtx StateRefT FindState CompilerM
65+
66+ abbrev ReplaceCtx := Std.HashMap FVarId Name
5467abbrev ReplaceM := ReaderT ReplaceCtx CompilerM
5568
5669/--
@@ -135,7 +148,7 @@ this. This is because otherwise the calls to `myjp` in `f` and `g` would
135148produce out of scope join point jumps.
136149-/
137150partial def find (decl : Decl) : CompilerM FindState := do
138- let (_, candidates) ← decl.value.forCodeM go |>.run none |>.run {} |>.run' {}
151+ let (_, candidates) ← decl.value.forCodeM go |>.run {} |>.run {}
139152 return candidates
140153where
141154 go : Code → FindM Unit
@@ -148,19 +161,27 @@ where
148161 if valId != decl.fvarId || args.size != candidateInfo.arity then
149162 eraseCandidate fvarId
150163 -- Out of scope join point candidate handling
151- else if let some upperCandidate ← read then
152- if !(← isInScope fvarId) then
153- addDependency fvarId upperCandidate
164+ else
165+ let currDepth := (← read).definitionDepth
166+ let calleeDepth := (← read).scope.get! fvarId
167+ if currDepth == calleeDepth then
168+ return ()
169+ else if calleeDepth + 1 == currDepth then
170+ addDependency fvarId (← read).currentFunction.get!
171+ else
172+ eraseCandidate fvarId
154173 | _, _ =>
155174 removeCandidatesInLetValue decl.value
156175 go k
157176 | .fun decl k => do
158177 addCandidate decl.fvarId decl.getArity
159- withReader (fun _ => some decl.fvarId) do
160- withNewScope do
161- go decl.value
162- addToScope decl.fvarId
163- go k
178+ withReader (fun ctx => {
179+ ctx with
180+ definitionDepth := ctx.definitionDepth + 1 ,
181+ currentFunction := some decl.fvarId }) do
182+ go decl.value
183+ withReader (fun ctx => { ctx with scope := ctx.scope.insert decl.fvarId ctx.definitionDepth }) do
184+ go k
164185 | .jp decl k => do
165186 go decl.value
166187 go k
0 commit comments