Skip to content

Commit 645ae96

Browse files
committed
Compiler: no longer split blocks at fun call to propagate location
Tests: Accept test for gh747
1 parent a524cae commit 645ae96

28 files changed

+1080
-808
lines changed

compiler/bin-js_of_ocaml/compile.ml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,11 @@ let run
162162
let var_k = Code.Var.fresh () in
163163
let var_v = Code.Var.fresh () in
164164
Code.
165-
[ Let (var_k, Prim (Extern "caml_jsstring_of_string", [ Pc (String k) ]))
166-
; Let (var_v, Prim (Extern "caml_jsstring_of_string", [ Pc (String v) ]))
167-
; Let (Var.fresh (), Prim (Extern "caml_set_static_env", [ Pv var_k; Pv var_v ]))
165+
[ Let (var_k, Prim (Extern "caml_jsstring_of_string", [ Pc (String k) ])), noloc
166+
; Let (var_v, Prim (Extern "caml_jsstring_of_string", [ Pc (String v) ])), noloc
167+
; ( Let
168+
(Var.fresh (), Prim (Extern "caml_set_static_env", [ Pv var_k; Pv var_v ]))
169+
, noloc )
168170
])
169171
in
170172
let output (one : Parse_bytecode.one) ~source_map ~linkall ~standalone output_file =

compiler/lib/code.ml

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,11 @@ let rec constant_equal a b =
326326
| Int _, (String _ | NativeString _ | Float_array _ | Int64 _ | Tuple (_, _, _)) ->
327327
Some false
328328

329+
type loc =
330+
| No
331+
| Before of Addr.t
332+
| After of Addr.t
333+
329334
type prim_arg =
330335
| Pv of Var.t
331336
| Pc of constant
@@ -361,8 +366,8 @@ type last =
361366

362367
type block =
363368
{ params : Var.t list
364-
; body : instr list
365-
; branch : last
369+
; body : (instr * loc) list
370+
; branch : last * loc
366371
}
367372

368373
type program =
@@ -371,6 +376,9 @@ type program =
371376
; free_pc : Addr.t
372377
}
373378

379+
let noloc = No
380+
381+
let location_of_pc pc = Before pc
374382
(****)
375383

376384
module Print = struct
@@ -478,7 +486,7 @@ module Print = struct
478486
| Constant c -> Format.fprintf f "CONST{%a}" constant c
479487
| Prim (p, l) -> prim f p l
480488

481-
let instr f i =
489+
let instr f (i, _loc) =
482490
match i with
483491
| Let (x, e) -> Format.fprintf f "%a = %a" Var.print x expr e
484492
| Assign (x, y) -> Format.fprintf f "(assign) %a = %a" Var.print x Var.print y
@@ -487,7 +495,7 @@ module Print = struct
487495
| Array_set (x, y, z) ->
488496
Format.fprintf f "%a[%a] = %a" Var.print x Var.print y Var.print z
489497

490-
let last f l =
498+
let last f (l, _loc) =
491499
match l with
492500
| Return x -> Format.fprintf f "return %a" Var.print x
493501
| Raise (x, `Normal) -> Format.fprintf f "raise %a" Var.print x
@@ -516,8 +524,8 @@ module Print = struct
516524
| Poptrap c -> Format.fprintf f "poptrap %a" cont c
517525

518526
type xinstr =
519-
| Instr of instr
520-
| Last of last
527+
| Instr of (instr * loc)
528+
| Last of (last * loc)
521529

522530
let block annot pc block =
523531
Format.eprintf "==== %d (%a) ====@." pc var_list block.params;
@@ -536,7 +544,7 @@ end
536544
let fold_closures p f accu =
537545
Addr.Map.fold
538546
(fun _ block accu ->
539-
List.fold_left block.body ~init:accu ~f:(fun accu i ->
547+
List.fold_left block.body ~init:accu ~f:(fun accu (i, _loc) ->
540548
match i with
541549
| Let (x, Closure (params, cont)) -> f (Some x) params cont accu
542550
| _ -> accu))
@@ -557,12 +565,12 @@ let prepend ({ start; blocks; free_pc } as p) body =
557565
| exception Not_found ->
558566
let new_start = free_pc in
559567
let blocks =
560-
Addr.Map.add new_start { params = []; body; branch = Stop } blocks
568+
Addr.Map.add new_start { params = []; body; branch = Stop, noloc } blocks
561569
in
562570
let free_pc = free_pc + 1 in
563571
{ start = new_start; blocks; free_pc })
564572

565-
let empty_block = { params = []; body = []; branch = Stop }
573+
let empty_block = { params = []; body = []; branch = Stop, noloc }
566574

567575
let empty =
568576
let start = 0 in
@@ -575,16 +583,17 @@ let is_empty p =
575583
| 1 -> (
576584
let _, v = Addr.Map.choose p.blocks in
577585
match v with
578-
| { body; branch = Stop; params = _ } -> (
586+
| { body; branch = Stop, _; params = _ } -> (
579587
match body with
580-
| ([] | [ Let (_, Prim (Extern "caml_get_global_data", _)) ]) when true -> true
588+
| ([] | [ (Let (_, Prim (Extern "caml_get_global_data", _)), _) ]) when true ->
589+
true
581590
| _ -> false)
582591
| _ -> false)
583592
| _ -> false
584593

585594
let fold_children blocks pc f accu =
586595
let block = Addr.Map.find pc blocks in
587-
match block.branch with
596+
match fst block.branch with
588597
| Return _ | Raise _ | Stop -> accu
589598
| Branch (pc', _) | Poptrap (pc', _) -> f pc' accu
590599
| Pushtrap ((pc', _), _, (pc_h, _), _) ->
@@ -648,7 +657,7 @@ let fold_closures_innermost_first { start; blocks; _ } f accu =
648657
let block = Addr.Map.find pc blocks in
649658
List.fold_left block.body ~init:accu ~f:(fun accu i ->
650659
match i with
651-
| Let (x, Closure (params, cont)) ->
660+
| Let (x, Closure (params, cont)), _ ->
652661
let accu = visit blocks (fst cont) f accu in
653662
f (Some x) params cont accu
654663
| _ -> accu))
@@ -704,7 +713,8 @@ let invariant { blocks; start; _ } =
704713
| Constant _ -> ()
705714
| Prim (_, _) -> ()
706715
in
707-
let check_instr = function
716+
let check_instr (i, _loc) =
717+
match i with
708718
| Let (x, e) ->
709719
define x;
710720
check_expr e
@@ -713,7 +723,8 @@ let invariant { blocks; start; _ } =
713723
| Offset_ref (_x, _i) -> ()
714724
| Array_set (_x, _y, _z) -> ()
715725
in
716-
let check_last = function
726+
let check_last (l, _loc) =
727+
match l with
717728
| Return _ -> ()
718729
| Raise _ -> ()
719730
| Stop -> ()

compiler/lib/code.mli

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ type constant =
163163

164164
val constant_equal : constant -> constant -> bool option
165165

166+
type loc =
167+
| No
168+
| Before of Addr.t
169+
| After of Addr.t
170+
171+
val noloc : loc
172+
173+
val location_of_pc : int -> loc
174+
166175
type prim_arg =
167176
| Pv of Var.t
168177
| Pc of constant
@@ -198,8 +207,8 @@ type last =
198207

199208
type block =
200209
{ params : Var.t list
201-
; body : instr list
202-
; branch : last
210+
; body : (instr * loc) list
211+
; branch : last * loc
203212
}
204213

205214
type program =
@@ -210,18 +219,18 @@ type program =
210219

211220
module Print : sig
212221
type xinstr =
213-
| Instr of instr
214-
| Last of last
222+
| Instr of (instr * loc)
223+
| Last of (last * loc)
215224

216225
val var_list : Format.formatter -> Var.t list -> unit
217226

218-
val instr : Format.formatter -> instr -> unit
227+
val instr : Format.formatter -> instr * loc -> unit
219228

220229
val block : (Addr.Map.key -> xinstr -> string) -> int -> block -> unit
221230

222231
val program : (Addr.Map.key -> xinstr -> string) -> program -> unit
223232

224-
val last : Format.formatter -> last -> unit
233+
val last : Format.formatter -> last * loc -> unit
225234

226235
val cont : Format.formatter -> cont -> unit
227236
end
@@ -244,7 +253,7 @@ val traverse :
244253
val preorder_traverse :
245254
fold_blocs_poly -> (Addr.t -> 'c -> 'c) -> Addr.t -> block Addr.Map.t -> 'c -> 'c
246255

247-
val prepend : program -> instr list -> program
256+
val prepend : program -> (instr * loc) list -> program
248257

249258
val empty : program
250259

compiler/lib/deadcode.ml

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ and mark_reachable st pc =
7777
then (
7878
st.reachable_blocks <- Addr.Set.add pc st.reachable_blocks;
7979
let block = Addr.Map.find pc st.blocks in
80-
List.iter block.body ~f:(fun i ->
80+
List.iter block.body ~f:(fun (i, _loc) ->
8181
match i with
8282
| Let (_, e) -> if not (pure_expr st.pure_funs e) then mark_expr st e
8383
| Assign _ -> ()
@@ -89,7 +89,7 @@ and mark_reachable st pc =
8989
mark_var st y;
9090
mark_var st z
9191
| Offset_ref (x, _) -> mark_var st x);
92-
match block.branch with
92+
match fst block.branch with
9393
| Return x | Raise (x, _) -> mark_var st x
9494
| Stop -> ()
9595
| Branch cont | Poptrap cont -> mark_cont_reachable st cont
@@ -129,25 +129,27 @@ let filter_closure blocks st i =
129129
| Let (x, Closure (l, cont)) -> Let (x, Closure (l, filter_cont blocks st cont))
130130
| _ -> i
131131

132-
let filter_live_last blocks st l =
133-
match l with
134-
| Return _ | Raise _ | Stop -> l
135-
| Branch cont -> Branch (filter_cont blocks st cont)
136-
| Cond (x, cont1, cont2) ->
137-
Cond (x, filter_cont blocks st cont1, filter_cont blocks st cont2)
138-
| Switch (x, a1, a2) ->
139-
Switch
140-
( x
141-
, Array.map a1 ~f:(fun cont -> filter_cont blocks st cont)
142-
, Array.map a2 ~f:(fun cont -> filter_cont blocks st cont) )
143-
| Pushtrap (cont1, x, cont2, pcs) ->
144-
Pushtrap
145-
( filter_cont blocks st cont1
146-
, x
147-
, filter_cont blocks st cont2
148-
, Addr.Set.inter pcs st.reachable_blocks )
149-
| Poptrap cont -> Poptrap (filter_cont blocks st cont)
150-
132+
let filter_live_last blocks st (l, loc) =
133+
let l =
134+
match l with
135+
| Return _ | Raise _ | Stop -> l
136+
| Branch cont -> Branch (filter_cont blocks st cont)
137+
| Cond (x, cont1, cont2) ->
138+
Cond (x, filter_cont blocks st cont1, filter_cont blocks st cont2)
139+
| Switch (x, a1, a2) ->
140+
Switch
141+
( x
142+
, Array.map a1 ~f:(fun cont -> filter_cont blocks st cont)
143+
, Array.map a2 ~f:(fun cont -> filter_cont blocks st cont) )
144+
| Pushtrap (cont1, x, cont2, pcs) ->
145+
Pushtrap
146+
( filter_cont blocks st cont1
147+
, x
148+
, filter_cont blocks st cont2
149+
, Addr.Set.inter pcs st.reachable_blocks )
150+
| Poptrap cont -> Poptrap (filter_cont blocks st cont)
151+
in
152+
l, loc
151153
(****)
152154

153155
let ref_count st i =
@@ -161,7 +163,7 @@ let annot st pc xi =
161163
else
162164
match (xi : Code.Print.xinstr) with
163165
| Last _ -> " "
164-
| Instr i ->
166+
| Instr (i, _) ->
165167
let c = ref_count st i in
166168
if c > 0 then Format.sprintf "%d" c else if live_instr st i then " " else "x"
167169

@@ -191,12 +193,12 @@ let f ({ blocks; _ } as p : Code.program) =
191193
let pure_funs = Pure_fun.f p in
192194
Addr.Map.iter
193195
(fun _ block ->
194-
List.iter block.body ~f:(fun i ->
196+
List.iter block.body ~f:(fun (i, _loc) ->
195197
match i with
196198
| Let (x, e) -> add_def defs x (Expr e)
197199
| Assign (x, y) -> add_def defs x (Var y)
198200
| Set_field (_, _, _) | Array_set (_, _, _) | Offset_ref (_, _) -> ());
199-
match block.branch with
201+
match fst block.branch with
200202
| Return _ | Raise _ | Stop -> ()
201203
| Branch cont -> add_cont_dep blocks defs cont
202204
| Cond (_, cont1, cont2) ->
@@ -225,8 +227,8 @@ let f ({ blocks; _ } as p : Code.program) =
225227
{ params = List.filter block.params ~f:(fun x -> st.live.(Var.idx x) > 0)
226228
; body =
227229
List.map
228-
(List.filter block.body ~f:(fun i -> live_instr st i))
229-
~f:(fun i -> filter_closure all_blocks st i)
230+
(List.filter block.body ~f:(fun (i, _loc) -> live_instr st i))
231+
~f:(fun (i, loc) -> filter_closure all_blocks st i, loc)
230232
; branch = filter_live_last all_blocks st block.branch
231233
}
232234
blocks)

0 commit comments

Comments
 (0)