Skip to content

Commit 813cc09

Browse files
vouillonhhugo
authored andcommitted
Add an Event instruction
This is simpler than to associate a location to all instructions. Also, this avoid the issue of locations getting lost because an instruction gets optimized away.
1 parent b0eda00 commit 813cc09

25 files changed

+6161
-5001
lines changed

compiler/lib/code.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ type instr =
446446
| Set_field of Var.t * int * field_type * Var.t
447447
| Offset_ref of Var.t * int
448448
| Array_set of Var.t * Var.t * Var.t
449+
| Event of Parse_info.t
449450

450451
type last =
451452
| Return of Var.t
@@ -604,6 +605,7 @@ module Print = struct
604605
| Offset_ref (x, i) -> Format.fprintf f "%a[0] += %d" Var.print x i
605606
| Array_set (x, y, z) ->
606607
Format.fprintf f "%a[%a] = %a" Var.print x Var.print y Var.print z
608+
| Event loc -> Format.fprintf f "event %s" (Parse_info.to_string loc)
607609

608610
let last f (l, _loc) =
609611
match l with
@@ -905,6 +907,7 @@ let invariant { blocks; start; _ } =
905907
| Set_field (_, _i, _, _) -> ()
906908
| Offset_ref (_x, _i) -> ()
907909
| Array_set (_x, _y, _z) -> ()
910+
| Event _ -> ()
908911
in
909912
let check_last (l, _loc) =
910913
match l with

compiler/lib/code.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ type instr =
229229
| Set_field of Var.t * int * field_type * Var.t
230230
| Offset_ref of Var.t * int
231231
| Array_set of Var.t * Var.t * Var.t
232+
| Event of Parse_info.t
232233

233234
type last =
234235
| Return of Var.t

compiler/lib/deadcode.ml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ and mark_reachable st pc =
9090
List.iter block.body ~f:(fun (i, _loc) ->
9191
match i with
9292
| Let (_, e) -> if not (pure_expr st.pure_funs e) then mark_expr st e
93-
| Assign _ -> ()
93+
| Event _ | Assign _ -> ()
9494
| Set_field (x, _, _, y) -> (
9595
match st.defs.(Var.idx x) with
9696
| [ Expr (Block _) ] when st.live.(Var.idx x) = 0 ->
@@ -125,7 +125,7 @@ let live_instr st i =
125125
match i with
126126
| Let (x, e) -> st.live.(Var.idx x) > 0 || not (pure_expr st.pure_funs e)
127127
| Assign (x, _) | Set_field (x, _, _, _) -> st.live.(Var.idx x) > 0
128-
| Offset_ref _ | Array_set _ -> true
128+
| Event _ | Offset_ref _ | Array_set _ -> true
129129

130130
let rec filter_args st pl al =
131131
match pl, al with
@@ -201,7 +201,8 @@ let f ({ blocks; _ } as p : Code.program) =
201201
match i with
202202
| Let (x, e) -> add_def defs x (Expr e)
203203
| Assign (x, y) -> add_def defs x (Var y)
204-
| Set_field (_, _, _, _) | Array_set (_, _, _) | Offset_ref (_, _) -> ());
204+
| Event _ | Set_field (_, _, _, _) | Array_set (_, _, _) | Offset_ref (_, _) ->
205+
());
205206
match fst block.branch with
206207
| Return _ | Raise _ | Stop -> ()
207208
| Branch cont -> add_cont_dep blocks defs cont
@@ -228,10 +229,16 @@ let f ({ blocks; _ } as p : Code.program) =
228229
pc
229230
{ params = List.filter block.params ~f:(fun x -> st.live.(Var.idx x) > 0)
230231
; body =
231-
List.filter_map block.body ~f:(fun (i, loc) ->
232-
if live_instr st i
233-
then Some (filter_closure all_blocks st i, loc)
234-
else None)
232+
List.fold_left block.body ~init:[] ~f:(fun acc (i, loc) ->
233+
match i, acc with
234+
| Event _, (Event _, _) :: prev ->
235+
(* Avoid consecutive events (keep just the last one) *)
236+
(i, loc) :: prev
237+
| _ ->
238+
if live_instr st i
239+
then (filter_closure all_blocks st i, loc) :: acc
240+
else acc)
241+
|> List.rev
235242
; branch = filter_live_last all_blocks st block.branch
236243
}
237244
blocks)

compiler/lib/duplicate.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ let instr s i =
4444
| Set_field (x, n, typ, y) -> Set_field (s x, n, typ, s y)
4545
| Offset_ref (x, n) -> Offset_ref (s x, n)
4646
| Array_set (x, y, z) -> Array_set (s x, s y, s z)
47+
| Event _ -> i
4748

4849
let instrs s l = List.map l ~f:(fun (i, loc) -> instr s i, loc)
4950

compiler/lib/effects.ml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ let cps_block ~st ~k pc block =
593593
in
594594
let instrs, branch = f ~k:k' in
595595
body_prefix, constr_cont @ instrs, branch)
596-
| Some (_, ((Set_field _ | Offset_ref _ | Array_set _ | Assign _), _)), _
596+
| Some (_, ((Event _ | Set_field _ | Offset_ref _ | Array_set _ | Assign _), _)), _
597597
| Some _, ((Raise _ | Stop | Cond _ | Switch _ | Pushtrap _ | Poptrap _), _)
598598
| None, _ -> None
599599
in
@@ -901,10 +901,18 @@ let remove_empty_blocks ~live_vars (p : Code.program) : Code.program =
901901
| None -> cont
902902
in
903903
let resolve cont = resolve_rec Addr.Set.empty cont in
904+
let empty_body b =
905+
List.for_all
906+
~f:(fun (i, _) ->
907+
match i with
908+
| Event _ -> true
909+
| _ -> false)
910+
b
911+
in
904912
Addr.Map.iter
905913
(fun pc block ->
906914
match block with
907-
| { params; body = []; branch = Branch cont, _; _ } ->
915+
| { params; body; branch = Branch cont, _; _ } when empty_body body ->
908916
let args =
909917
List.fold_left
910918
~f:(fun args x -> Var.Set.add x args)

compiler/lib/eval.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,11 @@ let rec do_not_raise pc visited blocks =
456456
let b = Addr.Map.find pc blocks in
457457
List.iter b.body ~f:(fun (i, _loc) ->
458458
match i with
459-
| Array_set (_, _, _) | Offset_ref (_, _) | Set_field (_, _, _, _) | Assign _ ->
460-
()
459+
| Event _
460+
| Array_set (_, _, _)
461+
| Offset_ref (_, _)
462+
| Set_field (_, _, _, _)
463+
| Assign _ -> ()
461464
| Let (_, e) -> (
462465
match e with
463466
| Block (_, _, _, _) | Field (_, _, _) | Constant _ | Closure _ -> ()

compiler/lib/flow.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ let program_deps { blocks; _ } =
122122
| Assign (x, y) ->
123123
add_dep deps x y;
124124
add_assign_def vars defs x y
125-
| Set_field _ | Array_set _ | Offset_ref _ -> ());
125+
| Event _ | Set_field _ | Array_set _ | Offset_ref _ -> ());
126126
match fst block.branch with
127127
| Return _ | Raise _ | Stop -> ()
128128
| Branch cont | Poptrap cont -> cont_deps blocks vars deps defs cont
@@ -256,7 +256,7 @@ let program_escape defs known_origins { blocks; _ } =
256256
List.iter block.body ~f:(fun (i, _loc) ->
257257
match i with
258258
| Let (x, e) -> expr_escape st x e
259-
| Assign _ -> ()
259+
| Event _ | Assign _ -> ()
260260
| Set_field (x, _, _, y) | Array_set (x, _, y) ->
261261
Var.Set.iter
262262
(fun y -> Var.ISet.add possibly_mutable y)

compiler/lib/freevars.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ let iter_instr_free_vars f i =
5555
f y;
5656
f z
5757
| Assign (_, y) -> f y
58+
| Event _ -> ()
5859

5960
let iter_last_free_var f l =
6061
match l with
@@ -79,7 +80,7 @@ let iter_block_free_vars f block =
7980
let iter_instr_bound_vars f i =
8081
match i with
8182
| Let (x, _) -> f x
82-
| Set_field _ | Offset_ref _ | Array_set _ | Assign _ -> ()
83+
| Event _ | Set_field _ | Offset_ref _ | Array_set _ | Assign _ -> ()
8384

8485
let iter_last_bound_vars f l =
8586
match l with

compiler/lib/generate.ml

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -345,14 +345,11 @@ let bool e = J.ECond (e, one, zero)
345345

346346
(****)
347347

348-
let source_location debug ?force (pc : Code.loc) =
349-
match Parse_bytecode.Debug.find_loc debug ?force pc with
348+
let source_location ctx position pc =
349+
match Parse_bytecode.Debug.find_loc ctx.Ctx.debug ~position pc with
350350
| Some pi -> J.Pi pi
351351
| None -> J.N
352352

353-
let source_location_ctx ctx ?force (pc : Code.loc) =
354-
source_location ctx.Ctx.debug ?force pc
355-
356353
(****)
357354

358355
let float_const f = J.ENum (J.Num.of_float f)
@@ -1101,14 +1098,14 @@ let rec translate_expr ctx queue loc x e level : _ * J.statement_list =
11011098
let (px, cx), queue = access_queue queue x in
11021099
(Mlvalue.Block.field cx n, or_p px mutable_p, queue), []
11031100
| Closure (args, ((pc, _) as cont)) ->
1104-
let loc = source_location_ctx ctx ~force:After (After pc) in
1101+
let loc = source_location ctx After pc in
11051102
let fv = Addr.Map.find pc ctx.freevars in
11061103
let clo = compile_closure ctx cont in
11071104
let clo =
11081105
match clo with
11091106
| (st, x) :: rem ->
11101107
let loc =
1111-
match x, source_location_ctx ctx (Before pc) with
1108+
match x, source_location ctx Before pc with
11121109
| (J.U | J.N), (J.U | J.N) -> J.U
11131110
| x, (J.U | J.N) -> x
11141111
| (J.U | J.N), x -> x
@@ -1371,18 +1368,16 @@ let rec translate_expr ctx queue loc x e level : _ * J.statement_list =
13711368
in
13721369
res, []
13731370

1374-
and translate_instr ctx expr_queue instr =
1375-
let instr, pc = instr in
1371+
and translate_instr ctx expr_queue loc instr =
1372+
let instr, _ = instr in
13761373
match instr with
13771374
| Assign (x, y) ->
1378-
let loc = source_location_ctx ctx pc in
13791375
let (_py, cy), expr_queue = access_queue expr_queue y in
13801376
flush_queue
13811377
expr_queue
13821378
mutator_p
13831379
[ J.Expression_statement (J.EBin (J.Eq, J.EVar (J.V x), cy)), loc ]
13841380
| Let (x, e) -> (
1385-
let loc = source_location_ctx ctx pc in
13861381
let (ce, prop, expr_queue), instrs = translate_expr ctx expr_queue loc x e 0 in
13871382
let keep_name x =
13881383
match Code.Var.get_name x with
@@ -1408,15 +1403,13 @@ and translate_instr ctx expr_queue instr =
14081403
prop
14091404
(instrs @ [ J.variable_declaration [ J.V x, (ce, loc) ], loc ]))
14101405
| Set_field (x, n, _, y) ->
1411-
let loc = source_location_ctx ctx pc in
14121406
let (_px, cx), expr_queue = access_queue expr_queue x in
14131407
let (_py, cy), expr_queue = access_queue expr_queue y in
14141408
flush_queue
14151409
expr_queue
14161410
mutator_p
14171411
[ J.Expression_statement (J.EBin (J.Eq, Mlvalue.Block.field cx n, cy)), loc ]
14181412
| Offset_ref (x, n) ->
1419-
let loc = source_location_ctx ctx pc in
14201413
(* FIX: may overflow.. *)
14211414
let (_px, cx), expr_queue = access_queue expr_queue x in
14221415
let expr = Mlvalue.Block.field cx 0 in
@@ -1429,20 +1422,20 @@ and translate_instr ctx expr_queue instr =
14291422
in
14301423
flush_queue expr_queue mutator_p [ J.Expression_statement expr', loc ]
14311424
| Array_set (x, y, z) ->
1432-
let loc = source_location_ctx ctx pc in
14331425
let (_px, cx), expr_queue = access_queue expr_queue x in
14341426
let (_py, cy), expr_queue = access_queue expr_queue y in
14351427
let (_pz, cz), expr_queue = access_queue expr_queue z in
14361428
flush_queue
14371429
expr_queue
14381430
mutator_p
14391431
[ J.Expression_statement (J.EBin (J.Eq, Mlvalue.Array.field cx cy, cz)), loc ]
1432+
| Event _ -> [], expr_queue
14401433

1441-
and translate_instrs_rev (ctx : Ctx.t) expr_queue instrs acc_rev muts_map : _ * _ =
1434+
and translate_instrs_rev (ctx : Ctx.t) loc expr_queue instrs acc_rev muts_map =
14421435
match instrs with
1443-
| [] -> acc_rev, expr_queue
1436+
| [] -> loc, acc_rev, expr_queue
14441437
| (Let (_, Closure _), _) :: _ ->
1445-
let names, pcs, all, rem = collect_closures instrs in
1438+
let names, pcs, all, rem, loc = collect_closures loc instrs in
14461439
let fvs =
14471440
List.fold_left pcs ~init:Code.Var.Set.empty ~f:(fun acc pc ->
14481441
Code.Var.Set.union acc (Addr.Map.find pc ctx.freevars))
@@ -1519,13 +1512,13 @@ and translate_instrs_rev (ctx : Ctx.t) expr_queue instrs acc_rev muts_map : _ *
15191512
List.fold_left
15201513
all
15211514
~init:([], [], expr_queue)
1522-
~f:(fun (mut_rec, st_rev, expr_queue) i ->
1515+
~f:(fun (mut_rec, st_rev, expr_queue) (i, loc) ->
15231516
let x' =
15241517
match i with
15251518
| Let (x', _), _ -> x'
15261519
| _ -> assert false
15271520
in
1528-
let l, expr_queue = translate_instr ctx expr_queue i in
1521+
let l, expr_queue = translate_instr ctx expr_queue loc i in
15291522
if Code.Var.Set.mem x' fvs
15301523
then
15311524
let mut_rec =
@@ -1547,17 +1540,19 @@ and translate_instrs_rev (ctx : Ctx.t) expr_queue instrs acc_rev muts_map : _ *
15471540
let acc_rev = vd Let bind_fvs_muts @ acc_rev in
15481541
let acc_rev = funs_rev @ acc_rev in
15491542
let acc_rev = vd Let bind_fvs_rec @ acc_rev in
1550-
translate_instrs_rev ctx expr_queue rem acc_rev muts_map
1543+
translate_instrs_rev ctx loc expr_queue rem acc_rev muts_map
1544+
| (Event loc, _) :: rem ->
1545+
translate_instrs_rev ctx (J.Pi loc) expr_queue rem acc_rev muts_map
15511546
| instr :: rem ->
1552-
let st, expr_queue = translate_instr ctx expr_queue instr in
1547+
let st, expr_queue = translate_instr ctx expr_queue loc instr in
15531548
let acc_rev = List.rev_append st acc_rev in
1554-
translate_instrs_rev ctx expr_queue rem acc_rev muts_map
1549+
translate_instrs_rev ctx loc expr_queue rem acc_rev muts_map
15551550

15561551
and translate_instrs (ctx : Ctx.t) expr_queue instrs =
1557-
let st_rev, expr_queue =
1558-
translate_instrs_rev (ctx : Ctx.t) expr_queue instrs [] Var.Map.empty
1552+
let loc, st_rev, expr_queue =
1553+
translate_instrs_rev (ctx : Ctx.t) J.N expr_queue instrs [] Var.Map.empty
15591554
in
1560-
List.rev st_rev, expr_queue
1555+
loc, List.rev st_rev, expr_queue
15611556

15621557
(* Compile loops. *)
15631558
and compile_block st queue (pc : Addr.t) scope_stack ~fall_through =
@@ -1591,7 +1586,7 @@ and compile_block st queue (pc : Addr.t) scope_stack ~fall_through =
15911586
if debug () then Format.eprintf "}@]@,";
15921587
let for_loop =
15931588
( J.For_statement (J.Left None, None, None, Js_simpl.block body)
1594-
, source_location_ctx st.ctx (Code.location_of_pc pc) )
1589+
, source_location st.ctx Before pc )
15951590
in
15961591
let label = if !lab_used then Some lab else None in
15971592
let for_loop =
@@ -1613,7 +1608,7 @@ and compile_block_no_loop st queue (pc : Addr.t) ~fall_through scope_stack =
16131608
if debug () then Format.eprintf "Compiling block %d@;" pc;
16141609
st.visited_blocks := Addr.Set.add pc !(st.visited_blocks);
16151610
let block = Addr.Map.find pc st.ctx.blocks in
1616-
let seq, queue = translate_instrs st.ctx queue block.body in
1611+
let loc, seq, queue = translate_instrs st.ctx queue block.body in
16171612
let nbbranch =
16181613
match fst block.branch with
16191614
| Switch (_, a) ->
@@ -1635,7 +1630,7 @@ and compile_block_no_loop st queue (pc : Addr.t) ~fall_through scope_stack =
16351630
in
16361631
let rec loop ~scope_stack ~fall_through l =
16371632
match l with
1638-
| [] -> compile_conditional st queue ~fall_through block.branch scope_stack
1633+
| [] -> compile_conditional st queue ~fall_through loc block.branch scope_stack
16391634
| x :: xs -> (
16401635
let l = J.Label.fresh () in
16411636
let used = ref false in
@@ -1679,8 +1674,7 @@ and compile_decision_tree kind st scope_stack loc cx dtree ~fall_through =
16791674
in
16801675
( never1 && never2
16811676
, Js_simpl.if_statement
1682-
~function_end:(fun () ->
1683-
source_location_ctx st.ctx ~force:After (After st.pc))
1677+
~function_end:(fun () -> source_location st.ctx After st.pc)
16841678
e'
16851679
loc
16861680
(Js_simpl.block iftrue)
@@ -1744,8 +1738,8 @@ and compile_decision_tree kind st scope_stack loc cx dtree ~fall_through =
17441738
let never, code = loop cx scope_stack dtree in
17451739
never, binds @ code
17461740

1747-
and compile_conditional st queue ~fall_through last scope_stack : _ * _ =
1748-
let last, pc = last in
1741+
and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
1742+
let last, _ = last in
17491743
(if debug ()
17501744
then
17511745
match last with
@@ -1756,7 +1750,6 @@ and compile_conditional st queue ~fall_through last scope_stack : _ * _ =
17561750
| Stop -> Format.eprintf "stop;@;"
17571751
| Cond (x, _, _) -> Format.eprintf "@[<hv 2>cond(%a){@;" Code.Var.print x
17581752
| Switch (x, _) -> Format.eprintf "@[<hv 2>switch(%a){@;" Code.Var.print x);
1759-
let loc = source_location_ctx st.ctx pc in
17601753
let res =
17611754
match last with
17621755
| Return x ->
@@ -1769,7 +1762,7 @@ and compile_conditional st queue ~fall_through last scope_stack : _ * _ =
17691762
| ECall _ -> (
17701763
(* We usually don't have a good locations for tail
17711764
calls, so use the end of the function instead *)
1772-
match source_location_ctx st.ctx ~force:After (After st.pc) with
1765+
match source_location st.ctx After st.pc with
17731766
| J.N -> loc
17741767
| loc -> loc)
17751768
| _ -> loc
@@ -1940,12 +1933,14 @@ and compile_closure ctx (pc, args) =
19401933
if debug () then Format.eprintf "}@]@;";
19411934
res
19421935

1943-
and collect_closures l =
1936+
and collect_closures loc l =
19441937
match l with
1938+
| (Event loc, _) :: ((Let (_, Closure _), _) :: _ as rem) ->
1939+
collect_closures (J.Pi loc) rem
19451940
| ((Let (x, Closure (_, (pc, _))), _loc) as i) :: rem ->
1946-
let names', pcs', i', rem' = collect_closures rem in
1947-
x :: names', pc :: pcs', i :: i', rem'
1948-
| _ -> [], [], [], l
1941+
let names', pcs', i', rem', loc' = collect_closures loc rem in
1942+
x :: names', pc :: pcs', (i, loc) :: i', rem', loc'
1943+
| _ -> [], [], [], l, loc
19491944

19501945
let generate_shared_value ctx =
19511946
let strings =

compiler/lib/generate.mli

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,3 @@ val f :
3030
-> Javascript.program
3131

3232
val init : unit -> unit
33-
34-
val source_location :
35-
Parse_bytecode.Debug.t
36-
-> ?force:Parse_bytecode.Debug.force
37-
-> Code.loc
38-
-> Javascript.location

0 commit comments

Comments
 (0)