@@ -147,41 +147,61 @@ and rewrite_body
147
147
let s =
148
148
Var.Set. fold (fun x m -> Var.Map. add x (Var. fork x) m) free_vars Var.Map. empty
149
149
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
183
201
| 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. *)
185
205
let st =
186
206
rewrite_blocks
187
207
~to_lift
0 commit comments