@@ -197,6 +197,7 @@ let inline inline_count live_vars closures pc (outer, p) =
197197 make this code unoptimized. (wrt to Jit compilers) *)
198198 && f_size < Config.Param. inlining_limit ()
199199 then (
200+ live_vars.(Var. idx f) < - 0 ;
200201 let blocks, cont_pc, free_pc =
201202 match rem, branch with
202203 | [] , Return y when Var. compare x y = 0 ->
@@ -298,6 +299,48 @@ let stats = Debug.find "stats"
298299
299300let debug_stats = Debug. find " stats-debug"
300301
302+ (* Inlining a function used only once will leave an unused closure
303+ with an initial continuation pointing to a block belonging to
304+ another function. This removes these closures. *)
305+
306+ let remove_dead_closures_from_block ~live_vars p pc block =
307+ let is_dead_closure i =
308+ match i with
309+ | Let (f , Closure _ ) ->
310+ let f = Var. idx f in
311+ f < Array. length live_vars && live_vars.(f) = 0
312+ | _ -> false
313+ in
314+ if List. exists ~f: is_dead_closure block.body
315+ then
316+ { p with
317+ blocks =
318+ Addr.Map. add
319+ pc
320+ { block with
321+ body =
322+ List. fold_left block.body ~init: [] ~f: (fun acc i ->
323+ match i, acc with
324+ | Event _ , Event _ :: prev ->
325+ (* Avoid consecutive events (keep just the last one) *)
326+ i :: prev
327+ | _ -> if is_dead_closure i then acc else i :: acc)
328+ |> List. rev
329+ }
330+ p.blocks
331+ }
332+ else p
333+
334+ let remove_dead_closures ~live_vars p pc =
335+ Code. traverse
336+ { fold = fold_children }
337+ (fun pc p ->
338+ let block = Addr.Map. find pc p.blocks in
339+ remove_dead_closures_from_block ~live_vars p pc block)
340+ pc
341+ p.blocks
342+ p
343+
301344let f p live_vars =
302345 let previous_p = p in
303346 let inline_count = ref 0 in
@@ -309,12 +352,16 @@ let f p live_vars =
309352 p
310353 (fun name cl_params (pc , _ ) _ (closures , p ) ->
311354 let traverse outer =
312- Code. traverse
313- { fold = Code. fold_children }
314- (inline inline_count live_vars closures)
315- pc
316- p.blocks
317- (outer, p)
355+ let outer, p =
356+ Code. traverse
357+ { fold = Code. fold_children }
358+ (inline inline_count live_vars closures)
359+ pc
360+ p.blocks
361+ (outer, p)
362+ in
363+ let p = remove_dead_closures ~live_vars p pc in
364+ outer, p
318365 in
319366 match name with
320367 | None ->
@@ -333,8 +380,8 @@ let f p live_vars =
333380 (* Inlining a raising function can result in empty blocks *)
334381 if times () then Format. eprintf " inlining: %a@." Timer. print t;
335382 if stats () then Format. eprintf " Stats - inline: %d optimizations@." ! inline_count;
383+ let p = Deadcode. remove_unused_blocks p in
336384 if debug_stats ()
337385 then Code. check_updates ~name: " inline" previous_p p ~updates: ! inline_count;
338- let p = Deadcode. remove_unused_blocks p in
339386 Code. invariant p;
340387 p
0 commit comments