Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cold continuation handlers in flambda2 #1543

Merged
merged 8 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions backend/CSEgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,16 @@ let insert_move srcs dsts i =
let i1 = array_fold2 insert_single_move i tmps dsts in
array_fold2 insert_single_move i1 srcs tmps

let rec split3 = function
[] -> ([], [], [])
| (x,y,z)::l ->
let (rx, ry, rz) = split3 l in (x::rx, y::ry, z::rz)
let rec split4 = function
[] -> ([], [], [], [])
| (x,y,z,w)::l ->
let (rx, ry, rz, rw) = split4 l in (x::rx, y::ry, z::rz, w::rw)

let rec combine3 l1 l2 l3 =
match (l1, l2, l3) with
([], [], []) -> []
| (a1::l1, a2::l2, a3::l3) -> (a1, a2, a3) :: combine3 l1 l2 l3
| (_, _, _) -> invalid_arg "combine3"
let rec combine4 l1 l2 l3 l4 =
match (l1, l2, l3, l4) with
([], [], [], []) -> []
| (a1::l1, a2::l2, a3::l3, a4::l4) -> (a1, a2, a3, a4) :: combine4 l1 l2 l3 l4
| (_, _, _, _) -> invalid_arg "combine4"

class cse_generic = object (self)

Expand Down Expand Up @@ -372,9 +372,9 @@ method private cse n i k =
self#cse empty_numbering i.next (fun next ->
k { i with desc = Iswitch(index, cases); next; }))
| Icatch(rec_flag, ts, handlers, body) ->
let nfail, t, handler_code = split3 handlers in
let nfail, t, handler_code, is_cold = split4 handlers in
self#cse_list empty_numbering handler_code (fun handler_code ->
let handlers = combine3 nfail t handler_code in
let handlers = combine4 nfail t handler_code is_cold in
self#cse n body (fun body ->
self#cse empty_numbering i.next (fun next ->
k { i with desc = Icatch(rec_flag, ts, handlers, body); next; })))
Expand Down
3 changes: 2 additions & 1 deletion backend/afl_instrument.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ and instrument = function
| Csequence (e1, e2) -> Csequence (instrument e1, instrument e2)
| Ccatch (isrec, cases, body, kind) ->
let cases =
List.map (fun (nfail, ids, e, dbg) -> nfail, ids, instrument e, dbg)
List.map (fun (nfail, ids, e, dbg, is_cold) ->
nfail, ids, instrument e, dbg, is_cold)
cases
in
Ccatch (isrec, cases, instrument body, kind)
Expand Down
2 changes: 1 addition & 1 deletion backend/cfg/cfgize.ml
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ let rec add_blocks :
| Icatch (_rec, _trap_stack, handlers, body) ->
let handlers =
List.map
(fun (handler_id, _trap_stack, handler) ->
(fun (handler_id, _trap_stack, handler, _is_cold) ->
let handler_label = State.add_catch_handler state ~handler_id in
handler_label, handler)
handlers
Expand Down
18 changes: 11 additions & 7 deletions backend/cmm.ml
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ type expression =
| Ccatch of
rec_flag
* (static_label * (Backend_var.With_provenance.t * machtype) list
* expression * Debuginfo.t) list
* expression * Debuginfo.t * bool (* is_cold *)) list
* expression * kind_for_unboxing
| Cexit of exit_label * expression list * trap_action list
| Ctrywith of expression * trywith_kind * Backend_var.With_provenance.t
Expand Down Expand Up @@ -323,8 +323,8 @@ type phrase =
Cfunction of fundecl
| Cdata of data_item list

let ccatch (i, ids, e1, e2, dbg, kind) =
Ccatch(Nonrecursive, [i, ids, e2, dbg], e1, kind)
let ccatch (i, ids, e1, e2, dbg, kind, is_cold) =
Ccatch(Nonrecursive, [i, ids, e2, dbg, is_cold], e1, kind)

let reset () =
label_counter := init_label
Expand All @@ -344,7 +344,7 @@ let iter_shallow_tail f = function
Array.iter (fun (e, _dbg) -> f e) el;
true
| Ccatch(_rec_flag, handlers, body, _value_kind) ->
List.iter (fun (_, _, h, _dbg) -> f h) handlers;
List.iter (fun (_, _, h, _dbg, _) -> f h) handlers;
f body;
true
| Ctrywith(e1, _kind, _id, e2, _dbg, _value_kind) ->
Expand Down Expand Up @@ -388,7 +388,9 @@ let map_shallow_tail ?kind f = function
Cswitch(e, tbl, Array.map (fun (e, dbg) -> f e, dbg) el, dbg',
Option.value kind ~default:kind_before)
| Ccatch(rec_flag, handlers, body, kind_before) ->
let map_h (n, ids, handler, dbg) = (n, ids, f handler, dbg) in
let map_h (n, ids, handler, dbg, is_cold) =
(n, ids, f handler, dbg, is_cold)
in
Ccatch(rec_flag, List.map map_h handlers, f body,
Option.value kind ~default:kind_before)
| Ctrywith(e1, kind', id, e2, dbg, kind_before) ->
Expand Down Expand Up @@ -445,7 +447,7 @@ let iter_shallow f = function
| Cswitch (_e, _ia, ea, _dbg, _value_kind) ->
Array.iter (fun (e, _) -> f e) ea
| Ccatch (_rf, hl, body, _value_kind) ->
let iter_h (_n, _ids, handler, _dbg) = f handler in
let iter_h (_n, _ids, handler, _dbg, _is_cold) = f handler in
List.iter iter_h hl; f body
| Cexit (_n, el, _traps) ->
List.iter f el
Expand Down Expand Up @@ -483,7 +485,9 @@ let map_shallow f = function
| Cswitch (e, ia, ea, dbg, kind) ->
Cswitch (e, ia, Array.map (fun (e, dbg) -> f e, dbg) ea, dbg, kind)
| Ccatch (rf, hl, body, kind) ->
let map_h (n, ids, handler, dbg) = (n, ids, f handler, dbg) in
let map_h (n, ids, handler, dbg, is_cold) =
(n, ids, f handler, dbg, is_cold)
in
Ccatch (rf, List.map map_h hl, f body, kind)
| Cexit (n, el, traps) ->
Cexit (n, List.map f el, traps)
Expand Down
3 changes: 2 additions & 1 deletion backend/cmm.mli
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ type expression =
| Ccatch of
rec_flag
* (Lambda.static_label * (Backend_var.With_provenance.t * machtype) list
* expression * Debuginfo.t) list
* expression * Debuginfo.t * bool (* is_cold *)) list
* expression
* kind_for_unboxing
| Cexit of exit_label * expression list * trap_action list
Expand Down Expand Up @@ -340,6 +340,7 @@ type phrase =
val ccatch :
label * (Backend_var.With_provenance.t * machtype) list
* expression * expression * Debuginfo.t * kind_for_unboxing
* bool
-> expression

val reset : unit -> unit
Expand Down
17 changes: 11 additions & 6 deletions backend/cmm_helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ let create_loop body dbg =
let cont = Lambda.next_raise_count () in
let call_cont = Cexit (Lbl cont, [], []) in
let body = Csequence (body, call_cont) in
Ccatch (Recursive, [cont, [], body, dbg], call_cont, Any)
Ccatch (Recursive, [cont, [], body, dbg, false], call_cont, Any)

(* Turning integer divisions into multiply-high then shift. The
[division_parameters] function is used in module Emit for those target
Expand Down Expand Up @@ -773,7 +773,9 @@ let rec remove_unit = function
dbg,
kind )
| Ccatch (rec_flag, handlers, body, kind) ->
let map_h (n, ids, handler, dbg) = n, ids, remove_unit handler, dbg in
let map_h (n, ids, handler, dbg, is_cold) =
n, ids, remove_unit handler, dbg, is_cold
in
Ccatch (rec_flag, List.map map_h handlers, remove_unit body, kind)
| Ctrywith (body, kind, exn, handler, dbg, value_kind) ->
Ctrywith (remove_unit body, kind, exn, remove_unit handler, dbg, value_kind)
Expand Down Expand Up @@ -2191,7 +2193,7 @@ module SArgBlocks = struct
fun body ->
match body with
| Cexit (j, _, _) -> if Lbl i = j then handler else body
| _ -> ccatch (i, [], body, handler, dbg, kind) ))
| _ -> ccatch (i, [], body, handler, dbg, kind, false) ))

let make_exit i = Cexit (Lbl i, [], [])
end
Expand Down Expand Up @@ -2475,7 +2477,8 @@ let cache_public_method meths tag cache dbg =
dbg,
Ctuple [],
dbg,
Any ),
Any,
false ),
Clet
( VP.create tagged,
Cop
Expand Down Expand Up @@ -3862,7 +3865,8 @@ let entry_point namelist =
dbg,
Ctuple [],
dbg,
Any ) )
Any,
false ) )
in
let fun_name = global_symbol "caml_program" in
let fun_dbg = placeholder_fun_dbg ~human_name:fun_name in
Expand Down Expand Up @@ -4151,8 +4155,9 @@ type static_handler =
* (Backend_var.With_provenance.t * Cmm.machtype) list
* Cmm.expression
* Debuginfo.t
* bool

let handler ~dbg id vars body = id, vars, body, dbg
let handler ~dbg id vars body is_cold = id, vars, body, dbg, is_cold

let cexit id args trap_actions = Cmm.Cexit (Cmm.Lbl id, args, trap_actions)

Expand Down
3 changes: 2 additions & 1 deletion backend/cmm_helpers.mli
Original file line number Diff line number Diff line change
Expand Up @@ -1053,13 +1053,14 @@ val trywith :
(** Opaque type for static handlers. *)
type static_handler

(** [handler id vars body] creates a static handler for exit number [id],
(** [handler id vars body is_cold] creates a static handler for exit number [id],
binding variables [vars] in [body]. *)
val handler :
dbg:Debuginfo.t ->
Lambda.static_label ->
(Backend_var.With_provenance.t * Cmm.machtype) list ->
Cmm.expression ->
bool ->
static_handler

(** [cexit id args] creates the cmm expression for static to a static handler
Expand Down
4 changes: 2 additions & 2 deletions backend/cmm_invariants.ml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ let rec check env (expr : Cmm.expression) =
| Ccatch (rec_flag, handlers, body, _) ->
let env_extended =
List.fold_left
(fun env (cont, args, _, _) ->
(fun env (cont, args, _, _, _) ->
Env.handler env ~cont ~arg_num:(List.length args))
env
handlers
Expand All @@ -166,7 +166,7 @@ let rec check env (expr : Cmm.expression) =
| Recursive -> env_extended
| Nonrecursive -> env
in
List.iter (fun (_, _, handler, _) -> check env_handler handler) handlers
List.iter (fun (_, _, handler, _, _) -> check env_handler handler) handlers
| Cexit (exit_label, args, _trap_actions) ->
Env.jump env ~exit_label ~arg_num:(List.length args)
| Ctrywith (body, _trywith_kind, _, handler, _, _) ->
Expand Down
12 changes: 6 additions & 6 deletions backend/cmmgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ let rec is_unboxed_number_cmm = function
List.fold_left
(join_unboxed_number_kind ~strict)
(is_unboxed_number_cmm body)
(List.map (fun (_, _, e, _) -> is_unboxed_number_cmm e) handlers)
(List.map (fun (_, _, e, _, _) -> is_unboxed_number_cmm e) handlers)

(* Translate an expression *)

Expand Down Expand Up @@ -796,7 +796,7 @@ let rec transl env e =
)
dbg,
Ctuple [],
dbg, Any))
dbg, Any, false))
| Ufor(id, low, high, dir, body) ->
let dbg = Debuginfo.none in
let tst = match dir with Upto -> Cgt | Downto -> Clt in
Expand Down Expand Up @@ -831,7 +831,7 @@ let rec transl env e =
dbg,
dbg, Any),
Ctuple [],
dbg, Any))))
dbg, Any, false))))
| Uassign(id, exp) ->
let dbg = Debuginfo.none in
let cexp = transl env exp in
Expand Down Expand Up @@ -882,7 +882,7 @@ and transl_catch (kind : Cmm.kind_for_unboxing) env nfail ids body handler dbg =
in
if env == new_env then
(* No unboxing *)
ccatch (nfail, ids, body, transl env handler, dbg, kind)
ccatch (nfail, ids, body, transl env handler, dbg, kind, false)
else
(* allocate new "nfail" to catch errors more easily *)
let new_nfail = next_raise_count () in
Expand All @@ -896,7 +896,7 @@ and transl_catch (kind : Cmm.kind_for_unboxing) env nfail ids body handler dbg =
in
aux body
in
ccatch (new_nfail, ids, body, transl new_env handler, dbg, kind)
ccatch (new_nfail, ids, body, transl new_env handler, dbg, kind, false)

and transl_make_array dbg env kind mode args =
match kind with
Expand Down Expand Up @@ -1385,7 +1385,7 @@ and transl_let env str (layout : Lambda.layout) id exp transl_body =
and make_catch (kind : Cmm.kind_for_unboxing) ncatch body handler dbg =
match body with
| Cexit (Lbl nexit,[],[]) when nexit=ncatch -> handler
| _ -> ccatch (ncatch, [], body, handler, dbg, kind)
| _ -> ccatch (ncatch, [], body, handler, dbg, kind, false)

and is_shareable_cont exp =
match exp with
Expand Down
2 changes: 1 addition & 1 deletion backend/comballoc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ let rec combine i allocstate =
let (newbody, s') = combine body allocstate in
let newhandlers =
List.map
(fun (io, ts, handler) -> io, ts, combine_restart handler)
(fun (io, ts, handler, is_cold) -> io, ts, combine_restart handler, is_cold)
handlers
in
let newnext = combine_restart i.next in
Expand Down
6 changes: 3 additions & 3 deletions backend/dataflow.ml
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,19 @@ let analyze ?(exnhandler = fun x -> x) ?(exnescape = D.bot)
begin match rc with
| Cmm.Nonrecursive ->
List.iter
(fun (n, trap_stack, h) ->
(fun (n, trap_stack, h, _) ->
let exnh = exn_from_trap_stack exn trap_stack in
set_lbl n (before bx exnh h))
handlers
| Cmm.Recursive ->
List.iter (fun (n, _, _) -> add_rc_lbl n) handlers;
List.iter (fun (n, _, _, _) -> add_rc_lbl n) handlers;
(* If [transfer] is monotonic and [D.t] satisfies
the finite ascending chains condition,
then the [while] loop below is guaranteed to terminate
with [lbls] at the least fixed point of [before bx exnh h].
Labels that retain their initial value at fixed point
may be implicitly represented and absent from [lbls]. *)
let update changed (n, trap_stack, h) =
let update changed (n, trap_stack, h, _) =
let b0 = get_lbl n in
let exnh = exn_from_trap_stack exn trap_stack in
let b1 = before bx exnh h in
Expand Down
14 changes: 7 additions & 7 deletions backend/deadcode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ let rec deadcode i =
let s = deadcode i.next in
let handlers' =
List.fold_left
(fun map (nfail, ts, handler) ->
Int.Map.add nfail (ts, deadcode handler) map)
(fun map (nfail, ts, handler, is_cold) ->
Int.Map.add nfail (ts, deadcode handler, is_cold) map)
Int.Map.empty handlers
in
(* Previous passes guarantee that indexes of handlers are unique
Expand All @@ -94,8 +94,8 @@ let rec deadcode i =
let live_exits = Int.Set.add nfail live_exits in
match Int.Map.find_opt nfail handlers' with
| None -> (live_exits, used_handlers)
| Some (ts, handler) ->
let used_handlers = (nfail, ts, handler) :: used_handlers in
| Some (ts, handler, is_cold) ->
let used_handlers = (nfail, ts, handler, is_cold) :: used_handlers in
match rec_flag with
| Cmm.Nonrecursive -> (live_exits, used_handlers)
| Cmm.Recursive ->
Expand All @@ -106,7 +106,7 @@ let rec deadcode i =
in
(* Remove exits that are going out of scope. *)
let used_handler_indexes =
List.fold_left (fun acc (n, _, _) -> Int.Set.add n acc)
List.fold_left (fun acc (n, _, _, _) -> Int.Set.add n acc)
Int.Set.empty used_handlers
in
let live_exits = Int.Set.diff live_exits used_handler_indexes in
Expand All @@ -115,7 +115,7 @@ let rec deadcode i =
match rec_flag with
| Cmm.Recursive -> live_exits
| Cmm.Nonrecursive ->
List.fold_left (fun exits (_,_,h) -> Int.Set.union h.exits exits)
List.fold_left (fun exits (_,_,h,_) -> Int.Set.union h.exits exits)
live_exits
used_handlers
in
Expand All @@ -127,7 +127,7 @@ let rec deadcode i =
exits;
}
| _ ->
let handlers = List.map (fun (n,ts,h) -> (n,ts,h.i)) used_handlers in
let handlers = List.map (fun (n,ts,h,is_cold) -> (n,ts,h.i,is_cold)) used_handlers in
{ i = { i with desc = Icatch(rec_flag, ts, handlers, body'.i);
next = s.i };
regs = i.live;
Expand Down
Loading