@@ -277,3 +277,67 @@ let build_graph blocks pc =
277277 let g = build_graph blocks pc in
278278 shrink_loops blocks g;
279279 g
280+
281+ (* Ensure that all loops have a predecessor block. Function
282+ shrink_loops assumes this. *)
283+ let norm p =
284+ let free_pc = ref p.free_pc in
285+ let visited = BitSet. create' p.free_pc in
286+ let rec mark_used ~function_start pc =
287+ if not (BitSet. mem visited pc)
288+ then (
289+ if not function_start then BitSet. set visited pc;
290+ let block = Addr.Map. find pc p.blocks in
291+ List. iter
292+ ~f: (fun i ->
293+ match i with
294+ | Let (_ , Closure (_ , (pc' , _ ), _ )) -> mark_used ~function_start: true pc'
295+ | _ -> () )
296+ block.body;
297+ fold_children p.blocks pc (fun pc' () -> mark_used ~function_start: false pc') () )
298+ in
299+ mark_used ~function_start: true p.start;
300+ let closure_need_update = function
301+ | Let (_ , Closure (_ , (pc , _ ), _ )) -> BitSet. mem visited pc
302+ | _ -> false
303+ in
304+ let rewrite_cont cont blocks =
305+ let npc = ! free_pc in
306+ incr free_pc;
307+ let body =
308+ let b = Addr.Map. find (fst cont) blocks in
309+ match b.body with
310+ | (Event _ as e ) :: _ -> [ e ]
311+ | _ -> []
312+ in
313+ let blocks = Addr.Map. add npc { body; params = [] ; branch = Branch cont } blocks in
314+ (npc, [] ), blocks
315+ in
316+ let blocks =
317+ Addr.Map. fold
318+ (fun pc block blocks ->
319+ if List. exists block.body ~f: closure_need_update
320+ then
321+ let blocks = ref blocks in
322+ let body =
323+ List. map block.body ~f: (function
324+ | Let (x , Closure (params , cont , loc )) as i when closure_need_update i ->
325+ let cont', blocks' = rewrite_cont cont ! blocks in
326+ blocks := blocks';
327+ Let (x, Closure (params, cont', loc))
328+ | i -> i)
329+ in
330+ Addr.Map. add pc { block with body } ! blocks
331+ else blocks)
332+ p.blocks
333+ p.blocks
334+ in
335+ if BitSet. mem visited p.start
336+ then (
337+ let npc = ! free_pc in
338+ incr free_pc;
339+ let blocks =
340+ Addr.Map. add npc { body = [] ; params = [] ; branch = Branch (p.start, [] ) } blocks
341+ in
342+ { blocks; free_pc = ! free_pc; start = npc })
343+ else { blocks; free_pc = ! free_pc; start = p.start }
0 commit comments