Skip to content

Commit 31d0c04

Browse files
authored
CMM traps (#72)
1 parent cf488b5 commit 31d0c04

30 files changed

+891
-410
lines changed

backend/CSEgen.ml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,17 @@ let insert_move srcs dsts i =
213213
let i1 = array_fold2 insert_single_move i tmps dsts in
214214
array_fold2 insert_single_move i1 srcs tmps
215215

216+
let rec split3 = function
217+
[] -> ([], [], [])
218+
| (x,y,z)::l ->
219+
let (rx, ry, rz) = split3 l in (x::rx, y::ry, z::rz)
220+
221+
let rec combine3 l1 l2 l3 =
222+
match (l1, l2, l3) with
223+
([], [], []) -> []
224+
| (a1::l1, a2::l2, a3::l3) -> (a1, a2, a3) :: combine3 l1 l2 l3
225+
| (_, _, _) -> invalid_arg "combine3"
226+
216227
class cse_generic = object (self)
217228

218229
(* Default classification of operations. Can be overridden in
@@ -256,7 +267,7 @@ method private kill_loads n =
256267

257268
method private cse n i k =
258269
match i.desc with
259-
| Iend | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _)
270+
| Iend | Ireturn _ | Iop(Itailcall_ind) | Iop(Itailcall_imm _)
260271
| Iexit _ | Iraise _ ->
261272
k i
262273
| Iop (Imove | Ispill | Ireload) ->
@@ -352,18 +363,18 @@ method private cse n i k =
352363
self#cse_array n1 cases (fun cases ->
353364
self#cse empty_numbering i.next (fun next ->
354365
k { i with desc = Iswitch(index, cases); next; }))
355-
| Icatch(rec_flag, handlers, body) ->
356-
let nfail, handler_code = List.split handlers in
366+
| Icatch(rec_flag, ts, handlers, body) ->
367+
let nfail, t, handler_code = split3 handlers in
357368
self#cse_list empty_numbering handler_code (fun handler_code ->
358-
let handlers = List.combine nfail handler_code in
369+
let handlers = combine3 nfail t handler_code in
359370
self#cse n body (fun body ->
360371
self#cse empty_numbering i.next (fun next ->
361-
k { i with desc = Icatch(rec_flag, handlers, body); next; })))
362-
| Itrywith(body, handler) ->
372+
k { i with desc = Icatch(rec_flag, ts, handlers, body); next; })))
373+
| Itrywith(body, kind, (ts, handler)) ->
363374
self#cse n body (fun body ->
364375
self#cse empty_numbering handler (fun handler ->
365376
self#cse empty_numbering i.next (fun next ->
366-
k { i with desc = Itrywith(body, handler); next; })))
377+
k { i with desc = Itrywith(body, kind, (ts, handler)); next; })))
367378

368379
method private cse_array n is k =
369380
self#cse_list n (Array.to_list is) (fun is -> k (Array.of_list is))

backend/afl_instrument.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ and instrument = function
6060
| Cifthenelse (cond, t_dbg, t, f_dbg, f, dbg) ->
6161
Cifthenelse (instrument cond, t_dbg, with_afl_logging t t_dbg,
6262
f_dbg, with_afl_logging f f_dbg, dbg)
63-
| Ctrywith (e, ex, handler, dbg) ->
64-
Ctrywith (instrument e, ex, with_afl_logging handler dbg, dbg)
63+
| Ctrywith (e, kind, ex, handler, dbg) ->
64+
Ctrywith (instrument e, kind, ex, with_afl_logging handler dbg, dbg)
6565
| Cswitch (e, cases, handlers, dbg) ->
6666
let handlers =
6767
Array.map (fun (handler, handler_dbg) ->
@@ -87,7 +87,7 @@ and instrument = function
8787
cases
8888
in
8989
Ccatch (isrec, cases, instrument body)
90-
| Cexit (ex, args) -> Cexit (ex, List.map instrument args)
90+
| Cexit (ex, args, traps) -> Cexit (ex, List.map instrument args, traps)
9191

9292
(* these are base cases and have no logging *)
9393
| Cconst_int _ | Cconst_natint _ | Cconst_float _

backend/amd64/proc.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ let destroyed_at_oper = function
330330
| Iconst_int _ | Iconst_float _ | Iconst_symbol _
331331
| Itailcall_ind | Itailcall_imm _ | Istackoffset _ | Iload (_, _)
332332
| Iname_for_debugger _ | Iprobe _| Iprobe_is_enabled _)
333-
| Iend | Ireturn | Iifthenelse (_, _, _) | Icatch (_, _, _)
333+
| Iend | Ireturn _ | Iifthenelse (_, _, _) | Icatch (_, _, _, _)
334334
| Iexit _ | Iraise _
335335
->
336336
if fp then

backend/amd64/selection.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ method! select_store is_assign addr exp =
210210
| Cvar _ | Clet (_, _, _) | Clet_mut (_, _, _, _) | Cphantom_let (_, _, _)
211211
| Cassign (_, _) | Ctuple _ | Cop (_, _, _) | Csequence (_, _)
212212
| Cifthenelse (_, _, _, _, _, _) | Cswitch (_, _, _, _) | Ccatch (_, _, _)
213-
| Cexit (_, _) | Ctrywith (_, _, _, _)
213+
| Cexit (_, _, _) | Ctrywith (_, _, _, _, _)
214214
->
215215
super#select_store is_assign addr exp
216216

backend/cmm.ml

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ let negate_float_comparison = Lambda.negate_float_comparison
109109
let swap_float_comparison = Lambda.swap_float_comparison
110110
type label = int
111111

112+
type exit_label =
113+
| Return_lbl
114+
| Lbl of label
115+
112116
let init_label = 99
113117

114118
let label_counter = ref init_label
@@ -138,6 +142,16 @@ type phantom_defining_expr =
138142
| Cphantom_read_symbol_field of { sym : string; field : int; }
139143
| Cphantom_block of { tag : int; fields : Backend_var.t list; }
140144

145+
type trywith_shared_label = int
146+
147+
type trap_action =
148+
| Push of trywith_shared_label
149+
| Pop
150+
151+
type trywith_kind =
152+
| Regular
153+
| Delayed of trywith_shared_label
154+
141155
type memory_chunk =
142156
Byte_unsigned
143157
| Byte_signed
@@ -202,12 +216,12 @@ type expression =
202216
* Debuginfo.t
203217
| Ccatch of
204218
rec_flag
205-
* (int * (Backend_var.With_provenance.t * machtype) list
219+
* (label * (Backend_var.With_provenance.t * machtype) list
206220
* expression * Debuginfo.t) list
207221
* expression
208-
| Cexit of int * expression list
209-
| Ctrywith of expression * Backend_var.With_provenance.t * expression
210-
* Debuginfo.t
222+
| Cexit of exit_label * expression list * trap_action list
223+
| Ctrywith of expression * trywith_kind * Backend_var.With_provenance.t
224+
* expression * Debuginfo.t
211225

212226
type codegen_option =
213227
| Reduce_code_size
@@ -263,7 +277,7 @@ let iter_shallow_tail f = function
263277
List.iter (fun (_, _, h, _dbg) -> f h) handlers;
264278
f body;
265279
true
266-
| Ctrywith(e1, _id, e2, _dbg) ->
280+
| Ctrywith(e1, _kind, _id, e2, _dbg) ->
267281
f e1;
268282
f e2;
269283
true
@@ -301,8 +315,8 @@ let rec map_tail f = function
301315
| Ccatch(rec_flag, handlers, body) ->
302316
let map_h (n, ids, handler, dbg) = (n, ids, map_tail f handler, dbg) in
303317
Ccatch(rec_flag, List.map map_h handlers, map_tail f body)
304-
| Ctrywith(e1, id, e2, dbg) ->
305-
Ctrywith(map_tail f e1, id, map_tail f e2, dbg)
318+
| Ctrywith(e1, kind, id, e2, dbg) ->
319+
Ctrywith(map_tail f e1, kind, id, map_tail f e2, dbg)
306320
| Cexit _ | Cop (Craise _, _, _) as cmm ->
307321
cmm
308322
| Cconst_int _
@@ -337,10 +351,10 @@ let map_shallow f = function
337351
| Ccatch (rf, hl, body) ->
338352
let map_h (n, ids, handler, dbg) = (n, ids, f handler, dbg) in
339353
Ccatch (rf, List.map map_h hl, f body)
340-
| Cexit (n, el) ->
341-
Cexit (n, List.map f el)
342-
| Ctrywith (e1, id, e2, dbg) ->
343-
Ctrywith (f e1, id, f e2, dbg)
354+
| Cexit (n, el, traps) ->
355+
Cexit (n, List.map f el, traps)
356+
| Ctrywith (e1, kind, id, e2, dbg) ->
357+
Ctrywith (f e1, kind, id, f e2, dbg)
344358
| Cconst_int _
345359
| Cconst_natint _
346360
| Cconst_float _

backend/cmm.mli

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ val new_label: unit -> label
9696
val set_label: label -> unit
9797
val cur_label: unit -> label
9898

99+
type exit_label =
100+
| Return_lbl
101+
| Lbl of label
102+
99103
type rec_flag = Nonrecursive | Recursive
100104

101105
type effects = No_effects | Arbitrary_effects
@@ -128,6 +132,24 @@ type phantom_defining_expr =
128132
(** The phantom-let-bound variable points at a block with the given
129133
structure. *)
130134

135+
type trywith_shared_label = int (* Same as Ccatch handlers *)
136+
137+
type trap_action =
138+
| Push of trywith_shared_label
139+
(** Add the corresponding handler to the trap stack. *)
140+
| Pop
141+
(** Remove the last handler from the trap stack. *)
142+
143+
type trywith_kind =
144+
| Regular
145+
(** Regular trywith: an uncaught exception from the body will always be
146+
handled by this handler. *)
147+
| Delayed of trywith_shared_label
148+
(** The body starts with the previous exception handler, and only after going
149+
through an explicit Push-annotated Cexit will this handler become active.
150+
This allows for sharing a single handler in several places, or having
151+
multiple entry and exit points to a single trywith block. *)
152+
131153
type memory_chunk =
132154
Byte_unsigned
133155
| Byte_signed
@@ -203,12 +225,12 @@ and expression =
203225
* Debuginfo.t
204226
| Ccatch of
205227
rec_flag
206-
* (int * (Backend_var.With_provenance.t * machtype) list
228+
* (label * (Backend_var.With_provenance.t * machtype) list
207229
* expression * Debuginfo.t) list
208230
* expression
209-
| Cexit of int * expression list
210-
| Ctrywith of expression * Backend_var.With_provenance.t * expression
211-
* Debuginfo.t
231+
| Cexit of exit_label * expression list * trap_action list
232+
| Ctrywith of expression * trywith_kind * Backend_var.With_provenance.t
233+
* expression * Debuginfo.t
212234

213235
type codegen_option =
214236
| Reduce_code_size
@@ -241,7 +263,7 @@ type phrase =
241263
| Cdata of data_item list
242264

243265
val ccatch :
244-
int * (Backend_var.With_provenance.t * machtype) list
266+
label * (Backend_var.With_provenance.t * machtype) list
245267
* expression * expression * Debuginfo.t
246268
-> expression
247269

backend/cmm_helpers.ml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ let mk_compare_floats dbg a1 a2 =
319319

320320
let create_loop body dbg =
321321
let cont = Lambda.next_raise_count () in
322-
let call_cont = Cexit (cont, []) in
322+
let call_cont = Cexit (Lbl cont, [], []) in
323323
let body = Csequence (body, call_cont) in
324324
Ccatch (Recursive, [cont, [], body, dbg], call_cont)
325325

@@ -605,15 +605,15 @@ let rec remove_unit = function
605605
| Ccatch(rec_flag, handlers, body) ->
606606
let map_h (n, ids, handler, dbg) = (n, ids, remove_unit handler, dbg) in
607607
Ccatch(rec_flag, List.map map_h handlers, remove_unit body)
608-
| Ctrywith(body, exn, handler, dbg) ->
609-
Ctrywith(remove_unit body, exn, remove_unit handler, dbg)
608+
| Ctrywith(body, kind, exn, handler, dbg) ->
609+
Ctrywith(remove_unit body, kind, exn, remove_unit handler, dbg)
610610
| Clet(id, c1, c2) ->
611611
Clet(id, c1, remove_unit c2)
612612
| Cop(Capply _mty, args, dbg) ->
613613
Cop(Capply typ_void, args, dbg)
614614
| Cop(Cextcall c, args, dbg) ->
615615
Cop(Cextcall {c with ret = typ_void; }, args, dbg)
616-
| Cexit (_,_) as c -> c
616+
| Cexit (_,_,_) as c -> c
617617
| Ctuple [] as c -> c
618618
| c -> Csequence(c, Ctuple [])
619619

@@ -1541,7 +1541,7 @@ struct
15411541
let bind arg body = bind "switcher" arg body
15421542

15431543
let make_catch handler = match handler with
1544-
| Cexit (i,[]) -> i,fun e -> e
1544+
| Cexit (Lbl i,[],[]) -> i,fun e -> e
15451545
| _ ->
15461546
let dbg = Debuginfo.none in
15471547
let i = Lambda.next_raise_count () in
@@ -1552,12 +1552,12 @@ struct
15521552
*)
15531553
i,
15541554
(fun body -> match body with
1555-
| Cexit (j,_) ->
1556-
if i=j then handler
1555+
| Cexit (j,_,_) ->
1556+
if Lbl i = j then handler
15571557
else body
15581558
| _ -> ccatch (i,[],body,handler, dbg))
15591559

1560-
let make_exit i = Cexit (i,[])
1560+
let make_exit i = Cexit (Lbl i,[],[])
15611561

15621562
end
15631563

@@ -1576,7 +1576,7 @@ module StoreExpForSwitch =
15761576
let make_key index expr =
15771577
let continuation =
15781578
match expr with
1579-
| Cexit (i,[]) -> Some i
1579+
| Cexit (Lbl i,[],[]) -> Some i
15801580
| _ -> None
15811581
in
15821582
Some (continuation, index)
@@ -1593,7 +1593,7 @@ module StoreExp =
15931593
type t = expression
15941594
type key = int
15951595
let make_key = function
1596-
| Cexit (i,[]) -> Some i
1596+
| Cexit (Lbl i,[],[]) -> Some i
15971597
| _ -> None
15981598
let compare_key = Stdlib.compare
15991599
end)
@@ -1778,7 +1778,7 @@ let cache_public_method meths tag cache dbg =
17781778
dbg),
17791779
Cifthenelse
17801780
(Cop(Ccmpi Cge, [Cvar li; Cvar hi], dbg),
1781-
dbg, Cexit (raise_num, []),
1781+
dbg, Cexit (Lbl raise_num, [], []),
17821782
dbg, Ctuple [],
17831783
dbg))))
17841784
dbg,

0 commit comments

Comments
 (0)