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