Skip to content

Commit acf8bb0

Browse files
hhugovouillon
andauthored
Compiler: disconnect closure cont from closure location. (#1947)
* Compiler: use explicit locations for closures - Store Parse_info.t inside closure - Debug infos are no longer needed after parsing bytecode --------- Co-authored-by: Jérôme Vouillon <[email protected]>
1 parent 33fac4f commit acf8bb0

34 files changed

+200
-211
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* Lib: make the Wasm version of Json.output work with native ints and JavaScript objects (#1872)
2626
* Compiler: static evaluation of more primitives (#1912)
2727
* Compiler: faster compilation by stopping sooner when optimizations become unproductive (#1939)
28+
* Compiler: improve debug/sourcemap location of closures (#1947)
2829
* Runtime: use Dataview to convert between floats and bit representation
2930

3031
## Bug fixes

compiler/bin-js_of_ocaml/build_fs.ml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ function jsoo_create_file_extern(name,content){
8282
~link:`Needed
8383
~formatter:pfs_fmt
8484
~source_map:false
85-
(Parse_bytecode.Debug.create ~include_cmis:false false)
8685
code
8786
in
8887
())

compiler/bin-js_of_ocaml/compile.ml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@ let run
277277
~wrap_with_fun
278278
~source_map:(source_map_enabled source_map)
279279
~formatter
280-
one.debug
281280
code
282281
| `File, formatter ->
283282
let fs_instr1, fs_instr2 =
@@ -301,22 +300,14 @@ let run
301300
~wrap_with_fun
302301
~source_map:(source_map_enabled source_map)
303302
~formatter
304-
one.debug
305303
code
306304
in
307305
Option.iter fs_output ~f:(fun file ->
308306
Filename.gen_file file (fun chan ->
309307
let instr = fs_instr2 in
310308
let code = Code.prepend Code.empty instr in
311309
let pfs_fmt = Pretty_print.to_out_channel chan in
312-
Driver.f'
313-
~standalone
314-
~link:`Needed
315-
?profile
316-
~wrap_with_fun
317-
pfs_fmt
318-
one.debug
319-
code));
310+
Driver.f' ~standalone ~link:`Needed ?profile ~wrap_with_fun pfs_fmt code));
320311
res
321312
in
322313
if times () then Format.eprintf "compilation: %a@." Timer.print t;

compiler/bin-wasm_of_ocaml/compile.ml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,13 @@ let generate_prelude ~out_file =
240240
Driver.optimize ~profile code
241241
in
242242
let context = Generate.start () in
243-
let debug = Parse_bytecode.Debug.create ~include_cmis:false false in
244243
let _ =
245244
Generate.f
246245
~context
247246
~unit_name:(Some "prelude")
248247
~live_vars:variable_uses
249248
~in_cps
250249
~deadcode_sentinal
251-
~debug
252250
program
253251
in
254252
Generate.output ch ~context;
@@ -404,15 +402,13 @@ let run
404402
Driver.optimize ~profile code
405403
in
406404
let context = Generate.start () in
407-
let debug = one.debug in
408405
let toplevel_name, generated_js =
409406
Generate.f
410407
~context
411408
~unit_name
412409
~live_vars:variable_uses
413410
~in_cps
414411
~deadcode_sentinal
415-
~debug
416412
program
417413
in
418414
if standalone then Generate.add_start_function ~context toplevel_name;

compiler/lib-wasm/closure_conversion.ml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ let iter_closures ~f instrs =
3535
let l = f clos_acc in
3636
List.rev_map
3737
~f:(fun g ->
38-
let params, cont = Var.Map.find g clos_acc in
39-
Let (g, Closure (params, cont)))
38+
let params, cont, cloc = Var.Map.find g clos_acc in
39+
Let (g, Closure (params, cont, cloc)))
4040
l
4141
@ instr_acc
4242
in
4343
match instrs with
4444
| [] -> List.rev (push_closures clos_acc instr_acc)
45-
| Let (g, Closure (params, cont)) :: rem ->
46-
iter_closures_rec f instr_acc (Var.Map.add g (params, cont) clos_acc) rem
45+
| Let (g, Closure (params, cont, cloc)) :: rem ->
46+
iter_closures_rec f instr_acc (Var.Map.add g (params, cont, cloc) clos_acc) rem
4747
| i :: rem ->
4848
iter_closures_rec f (i :: push_closures clos_acc instr_acc) Var.Map.empty rem
4949
in
@@ -79,7 +79,7 @@ let mark_bound_variables var_depth block depth =
7979
Freevars.iter_block_bound_vars (fun x -> var_depth.(Var.idx x) <- depth) block;
8080
List.iter block.body ~f:(fun i ->
8181
match i with
82-
| Let (_, Closure (params, _)) ->
82+
| Let (_, Closure (params, _, _)) ->
8383
List.iter params ~f:(fun x -> var_depth.(Var.idx x) <- depth + 1)
8484
| _ -> ())
8585

@@ -93,7 +93,7 @@ let rec traverse var_depth closures program pc depth =
9393
List.fold_left
9494
~f:(fun program i ->
9595
match i with
96-
| Let (_, Closure (_, (pc', _))) ->
96+
| Let (_, Closure (_, (pc', _), _)) ->
9797
traverse var_depth closures program pc' (depth + 1)
9898
| _ -> program)
9999
~init:program
@@ -103,7 +103,7 @@ let rec traverse var_depth closures program pc depth =
103103
iter_closures block.body ~f:(fun l ->
104104
let free_vars =
105105
Var.Map.fold
106-
(fun f (_, (pc', _)) free_vars ->
106+
(fun f (_, (pc', _), _) free_vars ->
107107
Var.Map.add
108108
f
109109
(collect_free_vars program var_depth (depth + 1) pc' !closures)
@@ -136,7 +136,7 @@ let rec traverse var_depth closures program pc depth =
136136
let functions =
137137
let arities =
138138
Var.Map.fold
139-
(fun f (params, _) m -> Var.Map.add f (List.length params) m)
139+
(fun f (params, _, _) m -> Var.Map.add f (List.length params) m)
140140
l
141141
Var.Map.empty
142142
in

compiler/lib-wasm/generate.ml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ module Generate (Target : Target_sig.S) = struct
3939
; blocks : block Addr.Map.t
4040
; closures : Closure_conversion.closure Var.Map.t
4141
; global_context : Code_generation.context
42-
; debug : Parse_bytecode.Debug.t
4342
}
4443

4544
let label_index context pc =
@@ -909,6 +908,7 @@ module Generate (Target : Target_sig.S) = struct
909908
~unit_name
910909
params
911910
((pc, _) as cont)
911+
cloc
912912
acc =
913913
let g = Structure.build_graph ctx.blocks pc in
914914
let dom = Structure.dominator_tree g in
@@ -1088,8 +1088,7 @@ module Generate (Target : Target_sig.S) = struct
10881088
(fun ~result_typ ~fall_through ~context ->
10891089
translate_branch result_typ fall_through (-1) cont context)
10901090
in
1091-
let end_loc = Parse_bytecode.Debug.find_loc ctx.debug ~position:After pc in
1092-
match end_loc with
1091+
match cloc with
10931092
| Some loc -> event loc
10941093
| None -> return ())
10951094
in
@@ -1176,8 +1175,7 @@ module Generate (Target : Target_sig.S) = struct
11761175
~should_export
11771176
~warn_on_unhandled_effect
11781177
*)
1179-
~deadcode_sentinal
1180-
~debug =
1178+
~deadcode_sentinal =
11811179
global_context.unit_name <- unit_name;
11821180
let p, closures = Closure_conversion.f p in
11831181
(*
@@ -1190,15 +1188,14 @@ module Generate (Target : Target_sig.S) = struct
11901188
; blocks = p.blocks
11911189
; closures
11921190
; global_context
1193-
; debug
11941191
}
11951192
in
11961193
let toplevel_name = Var.fresh_n "toplevel" in
11971194
let functions =
11981195
Code.fold_closures_outermost_first
11991196
p
1200-
(fun name_opt params cont ->
1201-
translate_function p ctx name_opt ~toplevel_name ~unit_name params cont)
1197+
(fun name_opt params cont cloc ->
1198+
translate_function p ctx name_opt ~toplevel_name ~unit_name params cont cloc)
12021199
[]
12031200
in
12041201
let functions =
@@ -1293,10 +1290,10 @@ let init = G.init
12931290

12941291
let start () = make_context ~value_type:Gc_target.Value.value
12951292

1296-
let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal ~debug =
1293+
let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal =
12971294
let t = Timer.make () in
12981295
let p = fix_switch_branches p in
1299-
let res = G.f ~context ~unit_name ~live_vars ~in_cps ~deadcode_sentinal ~debug p in
1296+
let res = G.f ~context ~unit_name ~live_vars ~in_cps ~deadcode_sentinal p in
13001297
if times () then Format.eprintf " code gen.: %a@." Timer.print t;
13011298
res
13021299

compiler/lib-wasm/generate.mli

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ val f :
2727
-> live_vars:int array
2828
-> in_cps:Effects.in_cps
2929
-> deadcode_sentinal:Code.Var.t
30-
-> debug:Parse_bytecode.Debug.t
3130
-> Wasm_ast.var * (string list * (string * Javascript.expression) list)
3231

3332
val add_start_function : context:Code_generation.context -> Wasm_ast.var -> unit

compiler/lib/code.ml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ type expr =
384384
}
385385
| Block of int * Var.t array * array_or_not * mutability
386386
| Field of Var.t * int * field_type
387-
| Closure of Var.t list * cont
387+
| Closure of Var.t list * cont * Parse_info.t option
388388
| Constant of constant
389389
| Prim of prim * prim_arg list
390390
| Special of special
@@ -538,7 +538,7 @@ module Print = struct
538538
Format.fprintf f "}"
539539
| Field (x, i, Non_float) -> Format.fprintf f "%a[%d]" Var.print x i
540540
| Field (x, i, Float) -> Format.fprintf f "FLOAT{%a[%d]}" Var.print x i
541-
| Closure (l, c) -> Format.fprintf f "fun(%a){%a}" var_list l cont c
541+
| Closure (l, c, _) -> Format.fprintf f "fun(%a){%a}" var_list l cont c
542542
| Constant c -> Format.fprintf f "CONST{%a}" constant c
543543
| Prim (p, l) -> prim f p l
544544
| Special s -> special f s
@@ -597,10 +597,10 @@ let fold_closures p f accu =
597597
(fun _ block accu ->
598598
List.fold_left block.body ~init:accu ~f:(fun accu i ->
599599
match i with
600-
| Let (x, Closure (params, cont)) -> f (Some x) params cont accu
600+
| Let (x, Closure (params, cont, cloc)) -> f (Some x) params cont cloc accu
601601
| _ -> accu))
602602
p.blocks
603-
(f None [] (p.start, []) accu)
603+
(f None [] (p.start, []) None accu)
604604

605605
(****)
606606

@@ -756,16 +756,16 @@ let fold_closures_innermost_first { start; blocks; _ } f accu =
756756
let block = Addr.Map.find pc blocks in
757757
List.fold_left block.body ~init:accu ~f:(fun accu i ->
758758
match i with
759-
| Let (x, Closure (params, cont)) ->
759+
| Let (x, Closure (params, cont, cloc)) ->
760760
let accu = visit blocks (fst cont) f accu in
761-
f (Some x) params cont accu
761+
f (Some x) params cont cloc accu
762762
| _ -> accu))
763763
pc
764764
blocks
765765
accu
766766
in
767767
let accu = visit blocks start f accu in
768-
f None [] (start, []) accu
768+
f None [] (start, []) None accu
769769

770770
let fold_closures_outermost_first { start; blocks; _ } f accu =
771771
let rec visit blocks pc f accu =
@@ -775,15 +775,15 @@ let fold_closures_outermost_first { start; blocks; _ } f accu =
775775
let block = Addr.Map.find pc blocks in
776776
List.fold_left block.body ~init:accu ~f:(fun accu i ->
777777
match i with
778-
| Let (x, Closure (params, cont)) ->
779-
let accu = f (Some x) params cont accu in
778+
| Let (x, Closure (params, cont, cloc)) ->
779+
let accu = f (Some x) params cont cloc accu in
780780
visit blocks (fst cont) f accu
781781
| _ -> accu))
782782
pc
783783
blocks
784784
accu
785785
in
786-
let accu = f None [] (start, []) accu in
786+
let accu = f None [] (start, []) None accu in
787787
visit blocks start f accu
788788

789789
let eq p1 p2 =
@@ -819,7 +819,7 @@ let invariant { blocks; start; _ } =
819819
| Apply _ -> ()
820820
| Block (_, _, _, _) -> ()
821821
| Field (_, _, _) -> ()
822-
| Closure (l, cont) ->
822+
| Closure (l, cont, _) ->
823823
List.iter l ~f:define;
824824
check_cont cont
825825
| Constant _ -> ()

compiler/lib/code.mli

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ type expr =
204204
}
205205
| Block of int * Var.t array * array_or_not * mutability
206206
| Field of Var.t * int * field_type
207-
| Closure of Var.t list * cont
207+
| Closure of Var.t list * cont * Parse_info.t option
208208
| Constant of constant
209209
| Prim of prim * prim_arg list
210210
| Special of special
@@ -266,24 +266,34 @@ type 'c fold_blocs = block Addr.Map.t -> Addr.t -> (Addr.t -> 'c -> 'c) -> 'c ->
266266
type fold_blocs_poly = { fold : 'a. 'a fold_blocs } [@@unboxed]
267267

268268
val fold_closures :
269-
program -> (Var.t option -> Var.t list -> cont -> 'd -> 'd) -> 'd -> 'd
269+
program
270+
-> (Var.t option -> Var.t list -> cont -> Parse_info.t option -> 'd -> 'd)
271+
-> 'd
272+
-> 'd
270273
(** [fold_closures p f init] folds [f] over all closures in the program [p],
271274
starting from the initial value [init]. For each closure, [f] is called
272275
with the following arguments: the closure name (enclosed in
273276
{!Stdlib.Some}), its parameter list, the address and parameter instantiation
274-
of its first block, and the current accumulator. In addition, [f] is called
275-
on the initial block [p.start], with [None] as the closure name.
276-
All closures in all blocks of [p] are included in the fold, not only the
277-
ones reachable from [p.start]. *)
277+
of its first block, the optional closure location and the current accumulator.
278+
In addition, [f] is called on the initial block [p.start], with
279+
[None] as the closure name. All closures in all blocks of [p] are
280+
included in the fold, not only the ones reachable from
281+
[p.start]. *)
278282

279283
val fold_closures_innermost_first :
280-
program -> (Var.t option -> Var.t list -> cont -> 'd -> 'd) -> 'd -> 'd
284+
program
285+
-> (Var.t option -> Var.t list -> cont -> Parse_info.t option -> 'd -> 'd)
286+
-> 'd
287+
-> 'd
281288
(** Similar to {!fold_closures}, but applies the fold function to the
282289
innermost closures first. Unlike with {!fold_closures}, only the closures
283290
reachable from [p.start] are considered. *)
284291

285292
val fold_closures_outermost_first :
286-
program -> (Var.t option -> Var.t list -> cont -> 'd -> 'd) -> 'd -> 'd
293+
program
294+
-> (Var.t option -> Var.t list -> cont -> Parse_info.t option -> 'd -> 'd)
295+
-> 'd
296+
-> 'd
287297
(** Similar to {!fold_closures}, but applies the fold function to the
288298
outermost closures first. Unlike with {!fold_closures}, only the closures
289299
reachable from [p.start] are considered. *)

compiler/lib/deadcode.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ and mark_expr st e =
7272
List.iter args ~f:(fun x -> mark_var st x)
7373
| Block (_, a, _, _) -> Array.iter a ~f:(fun x -> mark_var st x)
7474
| Field (x, _, _) -> mark_var st x
75-
| Closure (_, (pc, _)) -> mark_reachable st pc
75+
| Closure (_, (pc, _), _) -> mark_reachable st pc
7676
| Special _ -> ()
7777
| Prim (_, l) ->
7878
List.iter l ~f:(fun x ->
@@ -140,7 +140,8 @@ let filter_cont blocks st (pc, args) =
140140

141141
let filter_closure blocks st i =
142142
match i with
143-
| Let (x, Closure (l, cont)) -> Let (x, Closure (l, filter_cont blocks st cont))
143+
| Let (x, Closure (l, cont, gloc)) ->
144+
Let (x, Closure (l, filter_cont blocks st cont, gloc))
144145
| _ -> i
145146

146147
let filter_live_last blocks st l =

0 commit comments

Comments
 (0)