@@ -147,39 +147,57 @@ 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 = 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
+ )
181
197
| 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. *)
183
201
let st =
184
202
rewrite_blocks
185
203
~to_lift
0 commit comments