@@ -147,41 +147,61 @@ and rewrite_body
147147 let s =
148148 Var.Set. fold (fun x m -> Var.Map. add x (Var. fork x) m) free_vars Var.Map. empty
149149 in
150- let program = Subst.Excluding_Binders. cont (Subst. from_map s) pc' program in
151- let f' = try Var.Map. find f s with Not_found -> Var. fork f in
152- let s = Var.Map. bindings (Var.Map. remove f s) in
153- let f'' = Var. fork f in
154- if debug ()
155- then
156- Format. eprintf
157- " LIFT %s (depth:%d free_vars:%d inner_depth:%d)@."
158- (Code.Var. to_string f'')
159- depth
160- (Var.Set. cardinal free_vars)
161- (compute_depth program pc');
162- let pc'' = program.free_pc in
163- let bl = { params = [] ; body = [ Let (f', cl) ]; branch = Return f' } in
164- let program =
165- { program with free_pc = pc'' + 1 ; blocks = Addr.Map. add pc'' bl program.blocks }
166- in
167- (* Add to returned list of lifter functions definitions *)
168- let functions =
169- Let (f'', Closure (List. map s ~f: snd, (pc'', [] ), None )) :: functions
170- in
171- let lifters = Var.Map. add f f' lifters in
172- rewrite_body
173- ~to_lift
174- ~inside_lifted
175- ~current_contiguous: []
176- ~st: (program, functions, lifters)
177- ~var_depth
178- ~acc_instr:
179- (* Replace closure with application of the lifter function *)
180- (Let (f, Apply { f = f''; args = List. map ~f: fst s; exact = true }) :: acc_instr)
181- ~depth
182- rem
150+ if not Var.Map. (is_empty (remove f s))
151+ then (
152+ let program = Subst.Excluding_Binders. cont (Subst. from_map s) pc' program in
153+ let f' = try Var.Map. find f s with Not_found -> Var. fork f in
154+ let f'' = Var. fork f in
155+ let s = Var.Map. bindings (Var.Map. remove f s) in
156+ if debug ()
157+ then
158+ Format. eprintf
159+ " LIFT %s (depth:%d free_vars:%d inner_depth:%d)@."
160+ (Code.Var. to_string f'')
161+ depth
162+ (Var.Set. cardinal free_vars)
163+ (compute_depth program pc');
164+ let pc'' = program.free_pc in
165+ let bl = { params = [] ; body = [ Let (f', cl) ]; branch = Return f' } in
166+ let program =
167+ { program with
168+ free_pc = pc'' + 1
169+ ; blocks = Addr.Map. add pc'' bl program.blocks
170+ }
171+ in
172+ (* Add to returned list of lifter functions definitions *)
173+ let functions =
174+ Let (f'', Closure (List. map s ~f: snd, (pc'', [] ), None )) :: functions in
175+ let lifters = Var.Map. add f f' lifters in
176+ rewrite_body
177+ ~to_lift
178+ ~inside_lifted
179+ ~current_contiguous: []
180+ ~st: (program, functions, lifters)
181+ ~var_depth
182+ ~acc_instr:
183+ (* Replace closure with application of the lifter function *)
184+ (Let (f, Apply { f = f''; args = List. map ~f: fst s; exact = true })
185+ :: acc_instr)
186+ ~depth
187+ rem)
188+ else
189+ (* The closure doesn't have free variables, and thus doesn't need a lifter
190+ function. Just make sure it's a top-level function. *)
191+ let functions = Let (f, cl) :: functions in
192+ rewrite_body
193+ ~to_lift
194+ ~inside_lifted
195+ ~var_depth
196+ ~current_contiguous: []
197+ ~st: (program, functions, lifters)
198+ ~acc_instr
199+ ~depth
200+ rem
183201 | Let (cname , Closure (params , (pc' , args ), cloc )) :: rem ->
184- (* More closure definitions follow: accumulate and lift later *)
202+ (* We do not lift an isolated closure: either more closure definitions follow, or
203+ the closure doesn't need to be lifted. In both cases, we accumulate it and will
204+ lift (or not) later. *)
185205 let st =
186206 rewrite_blocks
187207 ~to_lift
0 commit comments