@@ -27,7 +27,6 @@ type closure_info =
2727 ; args : Code.Var .t list
2828 ; cont : Code .cont
2929 ; tc : Code.Addr.Set .t Code.Var.Map .t
30- ; mutated_vars : Code.Var.Set .t
3130 ; loc : Code .loc
3231 }
3332
@@ -67,24 +66,22 @@ let rec collect_apply pc blocks visited tc =
6766 (fun pc (visited , tc ) -> collect_apply pc blocks visited tc)
6867 (visited, tc)
6968
70- let rec collect_closures blocks mutated_vars l =
69+ let rec collect_closures blocks l =
7170 match l with
7271 | (Let (f_name , Closure (args , ((pc , _ ) as cont ))), loc ) :: rem ->
7372 let _, tc = collect_apply pc blocks Addr.Set. empty Var.Map. empty in
74- let l, rem = collect_closures blocks mutated_vars rem in
75- let mutated_vars = Addr.Map. find pc mutated_vars in
76- { f_name; args; cont; tc; mutated_vars; loc } :: l, rem
73+ let l, rem = collect_closures blocks rem in
74+ { f_name; args; cont; tc; loc } :: l, rem
7775 | rem -> [] , rem
7876
79- let group_closures ~ tc_only closures_map =
77+ let group_closures closures_map =
8078 let names =
8179 Var.Map. fold (fun _ x names -> Var.Set. add x.f_name names) closures_map Var.Set. empty
8280 in
8381 let graph =
8482 Var.Map. fold
8583 (fun _ x graph ->
8684 let calls = Var.Map. fold (fun x _ tc -> Var.Set. add x tc) x.tc Var.Set. empty in
87- let calls = if tc_only then calls else Var.Set. union calls x.mutated_vars in
8885 Var.Map. add x.f_name (Var.Set. inter names calls) graph)
8986 closures_map
9087 Var.Map. empty
278275let rewrite_tc free_pc blocks closures_map component =
279276 let open Config.Param in
280277 let trampoline =
281- (not (Config.Flag. effects () ))
282- &&
283278 match tailcall_optim () with
284279 | TcTrampoline -> true
285280 | TcNone -> false
@@ -288,189 +283,52 @@ let rewrite_tc free_pc blocks closures_map component =
288283 then Trampoline. f free_pc blocks closures_map component
289284 else Ident. f free_pc blocks closures_map component
290285
291- let rewrite_mutable
292- free_pc
293- blocks
294- mutated_vars
295- rewrite_list
296- { int = closures_intern ; ext = closures_extern } =
297- let internal_and_external = closures_intern @ closures_extern in
298- assert (not (List. is_empty closures_extern));
299- let all_mut, names =
300- List. fold_left
301- internal_and_external
302- ~init: (Var.Set. empty, Var.Set. empty)
303- ~f: (fun (all_mut , names ) i ->
304- match i with
305- | Let (x , Closure (_ , (pc , _ ))), _ ->
306- let all_mut =
307- try Var.Set. union all_mut (Addr.Map. find pc mutated_vars)
308- with Not_found -> all_mut
309- in
310- let names = Var.Set. add x names in
311- all_mut, names
312- | _ -> assert false )
313- in
314- let vars = Var.Set. elements (Var.Set. diff all_mut names) in
315- if List. is_empty vars
316- then free_pc, blocks, internal_and_external
317- else
318- match internal_and_external with
319- | [ (Let (x, Closure (params, (pc, pc_args))), loc) ] ->
320- let new_pc = free_pc in
321- let free_pc = free_pc + 1 in
322- let closure = Code.Var. fork x in
323- let args = List. map vars ~f: Code.Var. fork in
324- let new_x = Code.Var. fork x in
325- let mapping = Subst. from_map (Subst. build_mapping (x :: vars) (new_x :: args)) in
326- rewrite_list := (mapping, pc) :: ! rewrite_list;
327- let new_block =
328- { params = []
329- ; body =
330- [ Let (new_x, Closure (params, (pc, List. map pc_args ~f: mapping))), loc ]
331- ; branch = Return new_x, loc
332- }
333- in
334- let blocks = Addr.Map. add new_pc new_block blocks in
335- let body =
336- [ Let (closure, Closure (args, (new_pc, [] ))), noloc
337- ; Let (x, Apply { f = closure; args = vars; exact = true }), loc
338- ]
339- in
340- free_pc, blocks, body
341- | _ ->
342- let new_pc = free_pc in
343- let free_pc = free_pc + 1 in
344- let closure = Code.Var. fresh_n " closures" in
345- let closure' = Code.Var. fresh_n " closures" in
346- let b = Code.Var. fresh_n " block" in
347- let args = List. map vars ~f: Code.Var. fork in
348- let pcs =
349- List. map internal_and_external ~f: (function
350- | Let (_ , Closure (_ , (pc , _ ))), _ -> pc
351- | _ -> assert false )
352- in
353- let old_xs =
354- List. map closures_extern ~f: (function
355- | Let (x , Closure _ ), _ -> x
356- | _ -> assert false )
357- in
358- let new_xs = List. map old_xs ~f: Code.Var. fork in
359- let mapping =
360- Subst. from_map (Subst. build_mapping (old_xs @ vars) (new_xs @ args))
361- in
362- rewrite_list := List. map pcs ~f: (fun pc -> mapping, pc) @ ! rewrite_list;
363- let new_block =
364- let proj =
365- List. map2 closures_extern new_xs ~f: (fun cl new_x ->
366- match cl with
367- | Let (_ , Closure (params , (pc , pc_args ))), loc ->
368- Let (new_x, Closure (params, (pc, List. map pc_args ~f: mapping))), loc
369- | _ -> assert false )
370- in
371- { params = []
372- ; body =
373- closures_intern
374- @ proj
375- @ [ Let (b, Block (0 , Array. of_list new_xs, NotArray )), noloc ]
376- ; branch = Return b, noloc
377- }
378- in
379- let blocks = Addr.Map. add new_pc new_block blocks in
380- let body =
381- [ Let (closure, Closure (args, (new_pc, [] ))), noloc
382- ; Let (closure', Apply { f = closure; args = vars; exact = true }), noloc
383- ]
384- @ List. mapi closures_extern ~f: (fun i x ->
385- match x with
386- | Let (x , Closure _ ), loc -> Let (x, Field (closure', i)), loc
387- | _ -> assert false )
388- in
389- free_pc, blocks, body
390-
391- let rec rewrite_closures mutated_vars rewrite_list free_pc blocks body : int * _ * _ list
392- =
286+ let rec rewrite_closures free_pc blocks body : int * _ * _ list =
393287 match body with
394288 | (Let (_ , Closure _ ), _ ) :: _ ->
395- let closures, rem = collect_closures blocks mutated_vars body in
289+ let closures, rem = collect_closures blocks body in
396290 let closures_map =
397291 List. fold_left closures ~init: Var.Map. empty ~f: (fun closures_map x ->
398292 Var.Map. add x.f_name x closures_map)
399293 in
400- let components = group_closures ~tc_only: false closures_map in
294+ let components = group_closures closures_map in
401295 let free_pc, blocks, closures =
402296 List. fold_left
403297 (Array. to_list components)
404298 ~init: (free_pc, blocks, [] )
405299 ~f: (fun (free_pc , blocks , acc ) component ->
406300 let free_pc, blocks, closures =
407- let components =
408- match component with
409- | SCC. No_loop _ as one -> [ one ]
410- | SCC. Has_loop all ->
411- group_closures
412- ~tc_only: true
413- (Var.Map. filter
414- (fun v _ -> List. exists all ~f: (Var. equal v))
415- closures_map)
416- |> Array. to_list
417- in
418- List. fold_left
419- ~init: (free_pc, blocks, { int = [] ; ext = [] })
420- components
421- ~f: (fun (free_pc , blocks , acc ) component ->
422- let free_pc, blocks, ie =
423- rewrite_tc free_pc blocks closures_map component
424- in
425- free_pc, blocks, { int = ie.int :: acc .int ; ext = ie.ext :: acc .ext })
426- in
427- let closures =
428- { int = List. concat (List. rev closures.int )
429- ; ext = List. concat (List. rev closures.ext)
430- }
431- in
432- let free_pc, blocks, intrs =
433- rewrite_mutable free_pc blocks mutated_vars rewrite_list closures
301+ rewrite_tc free_pc blocks closures_map component
434302 in
435- free_pc, blocks, intrs :: acc)
436- in
437- let free_pc, blocks, rem =
438- rewrite_closures mutated_vars rewrite_list free_pc blocks rem
303+ let intrs = closures.int :: closures.ext :: acc in
304+ free_pc, blocks, intrs)
439305 in
306+ let free_pc, blocks, rem = rewrite_closures free_pc blocks rem in
440307 free_pc, blocks, List. flatten closures @ rem
441308 | i :: rem ->
442- let free_pc, blocks, rem =
443- rewrite_closures mutated_vars rewrite_list free_pc blocks rem
444- in
309+ let free_pc, blocks, rem = rewrite_closures free_pc blocks rem in
445310 free_pc, blocks, i :: rem
446311 | [] -> free_pc, blocks, []
447312
448313let f p : Code.program =
449314 Code. invariant p;
450- let mutated_vars = Freevars. f p in
451- let rewrite_list = ref [] in
452315 let blocks, free_pc =
453316 Addr.Map. fold
454317 (fun pc _ (blocks , free_pc ) ->
455318 (* make sure we have the latest version *)
456319 let block = Addr.Map. find pc blocks in
457- let free_pc, blocks, body =
458- rewrite_closures mutated_vars rewrite_list free_pc blocks block.body
459- in
320+ let free_pc, blocks, body = rewrite_closures free_pc blocks block.body in
460321 Addr.Map. add pc { block with body } blocks, free_pc)
461322 p.blocks
462323 (p.blocks, p.free_pc)
463324 in
464325 (* Code.invariant (pc, blocks, free_pc); *)
465326 let p = { p with blocks; free_pc } in
466- let p =
467- List. fold_left ! rewrite_list ~init: p ~f: (fun program (mapping , pc ) ->
468- Subst. cont mapping pc program)
469- in
470327 Code. invariant p;
471328 p
472329
473330let f p =
331+ assert (not (Config.Flag. effects () ));
474332 let t = Timer. make () in
475333 let p' = f p in
476334 if Debug. find " times" () then Format. eprintf " generate closures: %a@." Timer. print t;
0 commit comments