Skip to content

Commit

Permalink
Effects: use global flow analysis to detect more exact calls
Browse files Browse the repository at this point in the history
  • Loading branch information
vouillon authored and hhugo committed Jan 25, 2023
1 parent dde36fe commit d773062
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
16 changes: 12 additions & 4 deletions compiler/lib/effects.ml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ type st =
; matching_exn_handler : (Addr.t, Addr.t) Hashtbl.t
; block_order : (Addr.t, int) Hashtbl.t
; live_vars : Deadcode.variable_uses
; flow_info : Global_flow.info
; cps_calls : cps_calls ref
}

Expand Down Expand Up @@ -361,6 +362,7 @@ let cps_instr ~st (instr : instr) : instr =
| Let (x, Apply { f; args; _ }) when not (Var.Set.mem x st.cps_needed) ->
(* At the moment, we turn into CPS any function not called with
the right number of parameter *)
assert (Global_flow.exact_call st.flow_info f (List.length args));
Let (x, Apply { f; args; exact = true })
| Let (_, (Apply _ | Prim (Extern ("%resume" | "%perform" | "%reperform"), _))) ->
assert false
Expand Down Expand Up @@ -412,15 +414,20 @@ let cps_block ~st ~k pc block =
in
match e with
| Apply { f; args; exact } when Var.Set.mem x st.cps_needed ->
Some (fun ~k -> tail_call ~st ~exact ~check:true ~f (args @ [ k ]))
Some
(fun ~k ->
let exact =
exact || Global_flow.exact_call st.flow_info f (List.length args)
in
tail_call ~st ~exact ~check:true ~f (args @ [ k ]))
| Prim (Extern "%resume", [ Pv stack; Pv f; Pv arg ]) ->
Some
(fun ~k ->
let k' = Var.fresh_n "cont" in
tail_call
~st
~instrs:[ Let (k', Prim (Extern "caml_resume_stack", [ Pv stack; Pv k ])) ]
~exact:false
~exact:(Global_flow.exact_call st.flow_info f 1)
~check:true
~f
[ arg; k' ])
Expand Down Expand Up @@ -496,7 +503,7 @@ let cps_block ~st ~k pc block =
; branch = last
}

let cps_transform ~live_vars ~cps_needed p =
let cps_transform ~live_vars ~flow_info ~cps_needed p =
let closure_info = Hashtbl.create 16 in
let cps_calls = ref Var.Set.empty in
let p =
Expand Down Expand Up @@ -553,6 +560,7 @@ let cps_transform ~live_vars ~cps_needed p =
; is_continuation
; matching_exn_handler
; block_order = cfg.block_order
; flow_info
; live_vars
; cps_calls
}
Expand Down Expand Up @@ -818,6 +826,6 @@ let f (p, live_vars) =
let cps_needed = Partial_cps_analysis.f p flow_info in
let p, cps_needed = rewrite_toplevel ~cps_needed p in
let p = split_blocks ~cps_needed p in
let p, cps_calls = cps_transform ~live_vars ~cps_needed p in
let p, cps_calls = cps_transform ~live_vars ~flow_info ~cps_needed p in
if Debug.find "times" () then Format.eprintf " effects: %a@." Timer.print t;
p, cps_calls
6 changes: 3 additions & 3 deletions compiler/tests-compiler/effects_call_opt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ let%expect_test "test-compiler/lib-effects/effects_call_opt.ml" =
return cont(0)}
//end
function test2(param,cont)
{function f(g,x,cont){return caml_cps_call2(g,x,cont)}
{function f(g,x,cont){return caml_cps_exact_call2(g,x,cont)}
var _f_=7;
function _g_(x,cont){return cont(x + 1 | 0)}
return caml_cps_exact_call3
Expand All @@ -89,6 +89,6 @@ let%expect_test "test-compiler/lib-effects/effects_call_opt.ml" =
{function f(x,cont){return caml_cps_call3(Stdlib_Printf[2],_a_,x,cont)}
return [0,f]}
var M1=F([0]),M2=F([0]),_b_=1,_c_=M1[1];
return caml_cps_call2
(_c_,_b_,function(_d_){return caml_cps_call2(M2[1],2,cont)})}
return caml_cps_exact_call2
(_c_,_b_,function(_d_){return caml_cps_exact_call2(M2[1],2,cont)})}
//end |}]

0 comments on commit d773062

Please sign in to comment.