Skip to content

Commit 2b149df

Browse files
authored
flambda-backend: Improve diagnostics in Value_rec_compiler and add -dletreclambda (#2599)
1 parent 7718414 commit 2b149df

File tree

6 files changed

+62
-22
lines changed

6 files changed

+62
-22
lines changed

driver/main_args.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,10 @@ let mk_dsource f =
755755
let mk_dlambda f =
756756
"-dlambda", Arg.Unit f, " (undocumented)"
757757

758+
let mk_dletreclambda f =
759+
"-dletreclambda", Arg.Unit f,
760+
" Dump Lambda terms going into Value_rec_compiler"
761+
758762
let mk_drawclambda f =
759763
"-drawclambda", Arg.Unit f, " (undocumented)"
760764

@@ -954,6 +958,7 @@ module type Core_options = sig
954958
val _dshape : unit -> unit
955959
val _drawlambda : unit -> unit
956960
val _dlambda : unit -> unit
961+
val _dletreclambda : unit -> unit
957962

958963
end
959964

@@ -1273,6 +1278,7 @@ struct
12731278
mk_dshape F._dshape;
12741279
mk_drawlambda F._drawlambda;
12751280
mk_dlambda F._dlambda;
1281+
mk_dletreclambda F._dletreclambda;
12761282
mk_dinstr F._dinstr;
12771283
mk_dcamlprimc F._dcamlprimc;
12781284
mk_dtimings F._dtimings;
@@ -1357,6 +1363,7 @@ struct
13571363
mk_dshape F._dshape;
13581364
mk_drawlambda F._drawlambda;
13591365
mk_dlambda F._dlambda;
1366+
mk_dletreclambda F._dletreclambda;
13601367
mk_dinstr F._dinstr;
13611368
mk_debug_ocaml F._debug_ocaml;
13621369

@@ -1510,6 +1517,7 @@ struct
15101517
mk_dshape F._dshape;
15111518
mk_drawlambda F._drawlambda;
15121519
mk_dlambda F._dlambda;
1520+
mk_dletreclambda F._dletreclambda;
15131521
mk_drawclambda F._drawclambda;
15141522
mk_dclambda F._dclambda;
15151523
mk_dcmm_invariants F._dcmm_invariants;
@@ -1638,6 +1646,7 @@ module Make_opttop_options (F : Opttop_options) = struct
16381646
mk_dshape F._dshape;
16391647
mk_drawlambda F._drawlambda;
16401648
mk_dlambda F._dlambda;
1649+
mk_dletreclambda F._dletreclambda;
16411650
mk_drawclambda F._drawclambda;
16421651
mk_dclambda F._dclambda;
16431652
mk_dcmm_invariants F._dcmm_invariants;
@@ -1840,6 +1849,7 @@ module Default = struct
18401849
| _ -> Compenv.fatal "Incorrect -libloc format, expected: <path>:<lib1>,<lib2>,...:<hidden_lib1>,<hidden_lib2>,..."
18411850
let _color = Misc.set_or_ignore color_reader.parse color
18421851
let _dlambda = set dump_lambda
1852+
let _dletreclambda = set dump_letreclambda
18431853
let _dparsetree = set dump_parsetree
18441854
let _drawlambda = set dump_rawlambda
18451855
let _dsource = set dump_source

driver/main_args.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ module type Core_options = sig
8181
val _dshape : unit -> unit
8282
val _drawlambda : unit -> unit
8383
val _dlambda : unit -> unit
84+
val _dletreclambda : unit -> unit
8485

8586
end
8687

lambda/printlambda.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ val integer_comparison: formatter -> integer_comparison -> unit
2121
val float_comparison: float_comparison -> string
2222
val structured_constant: formatter -> structured_constant -> unit
2323
val lambda: formatter -> lambda -> unit
24+
val lfunction : formatter -> lfunction -> unit
2425
val program: formatter -> program -> unit
2526
val primitive: formatter -> primitive -> unit
2627
val name_of_primitive : primitive -> string

lambda/value_rec_compiler.ml

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ and lambda_with_env = {
9696
env : binding_size Ident.Map.t;
9797
}
9898

99-
let dynamic_size () =
100-
Misc.fatal_error "letrec: No size found for Static binding"
99+
let dynamic_size lam =
100+
Misc.fatal_errorf "letrec: No size found for Static binding:@ %a"
101+
Printlambda.lambda lam
101102

102103
(* [join_sizes] is used to compute the size of an expression with multiple
103104
branches. Such expressions are normally classified as [Dynamic] by
@@ -108,26 +109,26 @@ let dynamic_size () =
108109
Note that the current compilation scheme would work if we allowed the
109110
[Constant] and [Block] cases to be joined, but [Function] needs to be
110111
a single function. *)
111-
let join_sizes size1 size2 =
112+
let join_sizes lam size1 size2 =
112113
match size1, size2 with
113114
| Unreachable, size | size, Unreachable -> size
114-
| _, _ -> dynamic_size ()
115+
| _, _ -> dynamic_size lam
115116

116117
let compute_static_size lam =
117118
let rec compute_expression_size env lam =
118119
match lam with
119120
| Lvar v ->
120121
begin match Ident.Map.find_opt v env with
121122
| None ->
122-
dynamic_size ()
123+
dynamic_size lam
123124
| Some binding_size ->
124125
Lazy_backtrack.force
125126
(fun { lambda; env } -> compute_expression_size env lambda)
126127
binding_size
127128
end
128-
| Lmutvar _ -> dynamic_size ()
129+
| Lmutvar _ -> dynamic_size lam
129130
| Lconst _ -> Constant
130-
| Lapply _ -> dynamic_size ()
131+
| Lapply _ -> dynamic_size lam
131132
| Lfunction lfun -> Function lfun
132133
| Llet (_, _, id, def, body) ->
133134
let env =
@@ -170,7 +171,7 @@ let compute_static_size lam =
170171
| Lwhile _
171172
| Lfor _
172173
| Lassign _ -> Constant
173-
| Lsend _ -> dynamic_size ()
174+
| Lsend _ -> dynamic_size lam
174175
| Levent (e, _) ->
175176
compute_expression_size env e
176177
| Lifused _ -> Constant
@@ -180,20 +181,20 @@ let compute_static_size lam =
180181
(* Lexclave should only occur in tail position of a function.
181182
Since we only compute sizes for let-bound definitions, we should never
182183
reach this case.
183-
This justifies using [assert false] instead of [dynamic_size ()],
184+
This justifies using [assert false] instead of [dynamic_size lam],
184185
the latter meaning that [Value_rec_check] should have forbidden that case.
185186
*)
186187
assert false
187188
and compute_and_join_sizes env branches =
188189
List.fold_left (fun size branch ->
189-
join_sizes size (compute_expression_size env branch))
190+
join_sizes branch size (compute_expression_size env branch))
190191
Unreachable branches
191192
and compute_and_join_sizes_switch :
192193
type a. binding_size Ident.Map.t -> (a * lambda) list list -> size =
193194
fun env all_cases ->
194195
List.fold_left (fun size cases ->
195196
List.fold_left (fun size (_key, action) ->
196-
join_sizes size (compute_expression_size env action))
197+
join_sizes action size (compute_expression_size env action))
197198
size cases)
198199
Unreachable all_cases
199200
and size_of_primitive env p args =
@@ -335,7 +336,7 @@ let compute_static_size lam =
335336
| Patomic_fetch_add
336337
| Popaque _
337338
| Pdls_get ->
338-
dynamic_size ()
339+
dynamic_size lam
339340

340341
(* Primitives specific to flambda-backend *)
341342
| Pmakefloatblock (_, _) ->
@@ -356,7 +357,7 @@ let compute_static_size lam =
356357

357358
| Pmakeufloatblock (_, _)
358359
| Pmake_unboxed_product _ ->
359-
dynamic_size () (* Not allowed *)
360+
dynamic_size lam (* Not allowed *)
360361

361362
| Pobj_dup
362363
| Parray_to_iarray
@@ -385,7 +386,7 @@ let compute_static_size lam =
385386
| Pfloatoffloat32 _
386387
| Pfloat32offloat _
387388
| Pget_header _ ->
388-
dynamic_size ()
389+
dynamic_size lam
389390
in
390391
compute_expression_size Ident.Map.empty lam
391392

@@ -584,7 +585,9 @@ let rec split_static_function lfun block_var local_idents lam :
584585
Reachable (lfun, switch)
585586
| Reachable _, Reachable _, _ | Reachable _, _, Some (Reachable _)
586587
| _, Reachable _, Some (Reachable _) ->
587-
Misc.fatal_error "letrec: multiple functions"
588+
Misc.fatal_errorf "letrec: multiple functions:@ lfun=%a@ lam=%a"
589+
Printlambda.lfunction lfun
590+
Printlambda.lambda lam
588591
end
589592
| Lstringswitch (arg, arms, failaction, loc, layout) ->
590593
let arms_res = rebuild_arms lfun block_var local_idents arms in
@@ -598,7 +601,9 @@ let rec split_static_function lfun block_var local_idents lam :
598601
| Unreachable, Some (Reachable (lfun, failaction)) ->
599602
Reachable (lfun, Lstringswitch (arg, arms, Some failaction, loc, layout))
600603
| Reachable _, Some (Reachable _) ->
601-
Misc.fatal_error "letrec: multiple functions"
604+
Misc.fatal_errorf "letrec: multiple functions:@ lfun=%a@ lam=%a"
605+
Printlambda.lfunction lfun
606+
Printlambda.lambda lam
602607
end
603608
| Lstaticcatch (body, (nfail, params), handler, r, layout) ->
604609
let body_res = split_static_function lfun block_var local_idents body in
@@ -616,7 +621,9 @@ let rec split_static_function lfun block_var local_idents lam :
616621
| Unreachable, Reachable (lfun, handler) ->
617622
Reachable (lfun, Lstaticcatch (body, (nfail, params), handler, r, layout))
618623
| Reachable _, Reachable _ ->
619-
Misc.fatal_error "letrec: multiple functions"
624+
Misc.fatal_errorf "letrec: multiple functions:@ lfun=%a@ lam=%a"
625+
Printlambda.lfunction lfun
626+
Printlambda.lambda lam
620627
end
621628
| Ltrywith (body, exn_var, handler, layout) ->
622629
let body_res = split_static_function lfun block_var local_idents body in
@@ -631,7 +638,9 @@ let rec split_static_function lfun block_var local_idents lam :
631638
| Unreachable, Reachable (lfun, handler) ->
632639
Reachable (lfun, Ltrywith (body, exn_var, handler, layout))
633640
| Reachable _, Reachable _ ->
634-
Misc.fatal_error "letrec: multiple functions"
641+
Misc.fatal_errorf "letrec: multiple functions:@ lfun=%a@ lam=%a"
642+
Printlambda.lfunction lfun
643+
Printlambda.lambda lam
635644
end
636645
| Lifthenelse (cond, ifso, ifnot, layout) ->
637646
let ifso_res = split_static_function lfun block_var local_idents ifso in
@@ -643,7 +652,9 @@ let rec split_static_function lfun block_var local_idents lam :
643652
| Unreachable, Reachable (lfun, ifnot) ->
644653
Reachable (lfun, Lifthenelse (cond, ifso, ifnot, layout))
645654
| Reachable _, Reachable _ ->
646-
Misc.fatal_error "letrec: multiple functions"
655+
Misc.fatal_errorf "letrec: multiple functions:@ lfun=%a@ lam=%a"
656+
Printlambda.lfunction lfun
657+
Printlambda.lambda lam
647658
end
648659
| Lsequence (e1, e2) ->
649660
let+ e2 = split_static_function lfun block_var local_idents e2 in
@@ -661,7 +672,11 @@ let rec split_static_function lfun block_var local_idents lam :
661672
| Lsend _
662673
| Lifused _
663674
| Lregion _
664-
| Lexclave _ -> Misc.fatal_error "letrec binding is not a static function"
675+
| Lexclave _ ->
676+
Misc.fatal_errorf
677+
"letrec binding is not a static function:@ lfun=%a@ lam=%a"
678+
Printlambda.lfunction lfun
679+
Printlambda.lambda lam
665680
and rebuild_arms :
666681
type a. _ -> _ -> _ -> (a * Lambda.lambda) list ->
667682
(a * Lambda.lambda) list split_result =
@@ -678,7 +693,9 @@ and rebuild_arms :
678693
| Unreachable, Reachable (lfun, arms) ->
679694
Reachable (lfun, (i, lam) :: arms)
680695
| Reachable _, Reachable _ ->
681-
Misc.fatal_error "letrec: multiple functions"
696+
Misc.fatal_errorf "letrec: multiple functions:@ lfun=%a@ lam=%a"
697+
Printlambda.lfunction lfun
698+
Printlambda.lambda lam
682699

683700
(** {1. Compilation} *)
684701

@@ -796,6 +813,13 @@ let update_prim =
796813
(** Compilation function *)
797814

798815
let compile_letrec input_bindings body =
816+
if !Clflags.dump_letreclambda then (
817+
Format.eprintf "Value_rec_compiler input bindings:\n";
818+
List.iter (fun (id, _, def) ->
819+
Format.eprintf " %a = %a\n%!" Ident.print id Printlambda.lambda def)
820+
input_bindings;
821+
Format.eprintf "Value_rec_compiler body:@ %a\n%!" Printlambda.lambda body
822+
);
799823
let subst_for_constants =
800824
List.fold_left (fun subst (id, _, _) ->
801825
Ident.Map.add id Lambda.dummy_constant subst)
@@ -833,7 +857,9 @@ let compile_letrec input_bindings body =
833857
split_static_function lfun ctx_id Ident.Set.empty def
834858
with
835859
| Unreachable ->
836-
Misc.fatal_error "letrec: no function for binding"
860+
Misc.fatal_errorf
861+
"letrec: no function for binding:@ def=%a@ lfun=%a"
862+
Printlambda.lambda def Printlambda.lfunction lfun
837863
| Reachable ({ lfun; free_vars_block_size }, lam) ->
838864
let functions = (id, lfun) :: rev_bindings.functions in
839865
let static =

utils/clflags.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ and dump_typedtree = ref false (* -dtypedtree *)
122122
and dump_shape = ref false (* -dshape *)
123123
and dump_rawlambda = ref false (* -drawlambda *)
124124
and dump_lambda = ref false (* -dlambda *)
125+
and dump_letreclambda = ref false (* -dletreclambda *)
125126
and dump_rawclambda = ref false (* -drawclambda *)
126127
and dump_clambda = ref false (* -dclambda *)
127128
and dump_rawflambda = ref false (* -drawflambda *)

utils/clflags.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ val dump_typedtree : bool ref
133133
val dump_shape : bool ref
134134
val dump_rawlambda : bool ref
135135
val dump_lambda : bool ref
136+
val dump_letreclambda : bool ref
136137
val dump_rawclambda : bool ref
137138
val dump_clambda : bool ref
138139
val dump_rawflambda : bool ref

0 commit comments

Comments
 (0)