Skip to content

Commit 6c2bb02

Browse files
authored
Disable function sorting (oxcaml#2287)
1 parent 8641dde commit 6c2bb02

File tree

10 files changed

+123
-10
lines changed

10 files changed

+123
-10
lines changed

driver/flambda_backend_args.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ let mk_checkmach_details_cutoff f =
114114
| No_details -> 0
115115
| At_most n -> n)
116116

117+
let mk_function_layout f =
118+
let layouts = Flambda_backend_flags.Function_layout.(List.map to_string all) in
119+
let default = Flambda_backend_flags.Function_layout.(to_string default) in
120+
"-function-layout", Arg.Symbol (layouts, f),
121+
(Printf.sprintf " Order of functions in the generated assembly (default: %s)"
122+
default)
123+
117124
let mk_disable_poll_insertion f =
118125
"-disable-poll-insertion", Arg.Unit f, " Do not insert poll points"
119126

@@ -629,6 +636,7 @@ module type Flambda_backend_options = sig
629636
val dcheckmach : unit -> unit
630637
val checkmach_details_cutoff : int -> unit
631638

639+
val function_layout : string -> unit
632640
val disable_poll_insertion : unit -> unit
633641
val enable_poll_insertion : unit -> unit
634642

@@ -741,6 +749,7 @@ struct
741749
mk_dcheckmach F.dcheckmach;
742750
mk_checkmach_details_cutoff F.checkmach_details_cutoff;
743751

752+
mk_function_layout F.function_layout;
744753
mk_disable_poll_insertion F.disable_poll_insertion;
745754
mk_enable_poll_insertion F.enable_poll_insertion;
746755

@@ -907,6 +916,12 @@ module Flambda_backend_options_impl = struct
907916
in
908917
Flambda_backend_flags.checkmach_details_cutoff := c
909918

919+
let function_layout s =
920+
match Flambda_backend_flags.Function_layout.of_string s with
921+
| None -> () (* this should not occur as we use Arg.Symbol *)
922+
| Some layout ->
923+
Flambda_backend_flags.function_layout := layout
924+
910925
let disable_poll_insertion = set' Flambda_backend_flags.disable_poll_insertion
911926
let enable_poll_insertion = clear' Flambda_backend_flags.disable_poll_insertion
912927

@@ -1179,6 +1194,13 @@ module Extra_params = struct
11791194
| None -> ()
11801195
end;
11811196
true
1197+
| "function-layout" ->
1198+
(match Flambda_backend_flags.Function_layout.of_string v with
1199+
| Some layout -> Flambda_backend_flags.function_layout := layout; true
1200+
| None ->
1201+
raise
1202+
(Arg.Bad
1203+
(Printf.sprintf "Unexpected value %s for %s" v name)))
11821204
| "poll-insertion" -> set' Flambda_backend_flags.disable_poll_insertion
11831205
| "symbol-visibility-protected" -> set' Flambda_backend_flags.disable_poll_insertion
11841206
| "long-frames" -> set' Flambda_backend_flags.allow_long_frames

driver/flambda_backend_args.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ module type Flambda_backend_options = sig
5151
val dcheckmach : unit -> unit
5252
val checkmach_details_cutoff : int -> unit
5353

54+
val function_layout : string -> unit
5455
val disable_poll_insertion : unit -> unit
5556
val enable_poll_insertion : unit -> unit
5657

driver/flambda_backend_flags.ml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@ type checkmach_details_cutoff =
4242
let default_checkmach_details_cutoff = At_most 20
4343
let checkmach_details_cutoff = ref default_checkmach_details_cutoff
4444
(* -checkmach-details-cutoff n *)
45+
module Function_layout = struct
46+
type t =
47+
| Topological
48+
| Source
49+
50+
let to_string = function
51+
| Topological -> "topological"
52+
| Source -> "source"
53+
54+
let default = Topological
55+
56+
let all = [Topological; Source]
57+
58+
let of_string v =
59+
let f t =
60+
if String.equal (to_string t) v then Some t else None
61+
in
62+
List.find_map f all
63+
end
64+
65+
let function_layout = ref Function_layout.default (* -function-layout *)
4566

4667
let disable_poll_insertion = ref (not Config.poll_insertion)
4768
(* -disable-poll-insertion *)

driver/flambda_backend_flags.mli

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ type checkmach_details_cutoff =
4646
val checkmach_details_cutoff : checkmach_details_cutoff ref
4747
val default_checkmach_details_cutoff : checkmach_details_cutoff
4848

49+
module Function_layout : sig
50+
type t =
51+
| Topological
52+
| Source
53+
54+
val to_string : t -> string
55+
val of_string : string -> t option
56+
val default :t
57+
58+
val all : t list
59+
end
60+
61+
62+
val function_layout : Function_layout.t ref
4963
val disable_poll_insertion : bool ref
5064
val allow_long_frames : bool ref
5165
val max_long_frames_threshold : int

middle_end/flambda2/to_cmm/to_cmm_result.ml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,15 @@ let to_cmm r =
164164
let r = define_module_symbol_if_missing r in
165165
(* Make sure we do not forget any current data *)
166166
let r = archive_data r in
167-
(* Sort functions according to debuginfo, to get a stable ordering *)
168167
let sorted_functions =
169-
List.sort
170-
(fun (f1 : Cmm.fundecl) (f2 : Cmm.fundecl) ->
171-
Debuginfo.compare f1.fun_dbg f2.fun_dbg)
172-
r.functions
168+
match !Flambda_backend_flags.function_layout with
169+
| Topological -> List.rev r.functions
170+
| Source ->
171+
(* Sort functions according to debuginfo, to get a stable ordering *)
172+
List.sort
173+
(fun (f1 : Cmm.fundecl) (f2 : Cmm.fundecl) ->
174+
Debuginfo.compare f1.fun_dbg f2.fun_dbg)
175+
r.functions
173176
in
174177
let function_phrases = List.map (fun f -> C.cfunction f) sorted_functions in
175178
(* Translate roots to Cmm symbols *)

tests/backend/checkmach/dune.inc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
(action
164164
(with-outputs-to fail8.output.corrected
165165
(pipe-outputs
166-
(with-accepted-exit-codes 2
166+
(with-accepted-exit-codes 0
167167
(run %{bin:ocamlopt.opt} %{ml} -g -color never -error-style short -c
168168
-zero-alloc-check default -checkmach-details-cutoff 0 -O3))
169169
(run "./filter.sh")
@@ -749,3 +749,9 @@
749749
(enabled_if (= %{context_name} "main"))
750750
(deps fail24.output fail24.output.corrected)
751751
(action (diff fail24.output fail24.output.corrected)))
752+
753+
(rule
754+
(alias runtest)
755+
(enabled_if (= %{context_name} "main"))
756+
(deps test_raise_message.ml)
757+
(action (run %{bin:ocamlopt.opt} %{deps} -g -c -zero-alloc-check default -dcse -dcheckmach -dump-into-file -O3 -warn-error +a)))

tests/backend/checkmach/fail8.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(* fails because forward dependency on g is treated conservatively *)
1+
(* forward dependency on g *)
22
exception E
33
let[@zero_alloc] rec f x b =
44
if b then (g x; raise E)
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +0,0 @@
1-
File "fail8.ml", line 3, characters 5-15:
2-
Error: Annotation check for zero_alloc failed on function Fail8.f (camlFail8.f_HIDE_STAMP)

tests/backend/checkmach/gen/gen_dune.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ let () =
7878
print_test_expected_output ~cutoff:0 ~extra_dep:None ~exit_code:2 "fail5";
7979
print_test_expected_output ~cutoff:0 ~extra_dep:None ~exit_code:2 "fail6";
8080
print_test_expected_output ~cutoff:0 ~extra_dep:None ~exit_code:2 "fail7";
81-
print_test_expected_output ~cutoff:0 ~extra_dep:None ~exit_code:2 "fail8";
81+
print_test_expected_output ~cutoff:0 ~extra_dep:None ~exit_code:0 "fail8";
8282
print_test_expected_output ~cutoff:0 ~extra_dep:None ~exit_code:2 "fail9";
8383
print_test_expected_output ~cutoff:0 ~extra_dep:None ~exit_code:2 "fail10";
8484
print_test_expected_output ~cutoff:default_cutoff ~extra_dep:None ~exit_code:2 "fail12";
@@ -123,4 +123,5 @@ let () =
123123
print_test_expected_output ~cutoff:default_cutoff ~extra_dep:None ~exit_code:2 "test_attr_check_opt";
124124
print_test_expected_output ~cutoff:default_cutoff ~extra_dep:None ~exit_code:0 "test_attr_check_none";
125125
print_test_expected_output ~cutoff:default_cutoff ~extra_dep:None ~exit_code:2 "fail24";
126+
print_test "test_raise_message.ml";
126127
()
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
module Sexp = struct
2+
type t =
3+
| Atom of string
4+
| List of t list
5+
let of_int n = Atom (string_of_int n)
6+
end
7+
8+
exception Exn of Sexp.t
9+
10+
let raise_s sexp = raise (Exn sexp)
11+
[@@ocaml.inline never][@@ocaml.local never][@@ocaml.specialise never]
12+
13+
(* Pattern before ppx looks like this: *)
14+
(* let[@zero_alloc] raise_invalid_index ~unknown_index ~name =
15+
* raise_s
16+
* [%message
17+
* "Unknown" (unknown_index : int) (name : string)]
18+
* ;; *)
19+
20+
let raise_invalid_index_FAIL ~unknown_index ~name =
21+
raise_s
22+
(let ppx_sexp_message () =
23+
Sexp.List
24+
[Sexp.Atom "Unknown";
25+
Sexp.List
26+
[Sexp.Atom "unknown_index"; Sexp.of_int unknown_index];
27+
Sexp.List
28+
[Sexp.Atom "name"; Sexp.Atom name]]
29+
[@@ocaml.inline never][@@ocaml.local never][@@ocaml.specialise never]
30+
in
31+
((ppx_sexp_message ())[@nontail ]))
32+
[@@ocaml.inline never][@@ocaml.local never][@@ocaml.specialise never][@@zero_alloc ]
33+
34+
35+
36+
let ppx_sexp_message ~unknown_index ~name =
37+
Sexp.List
38+
[Sexp.Atom "Unknown";
39+
Sexp.List
40+
[Sexp.Atom "unknown_index"; Sexp.of_int unknown_index];
41+
Sexp.List
42+
[Sexp.Atom "name"; Sexp.Atom name]]
43+
[@@ocaml.inline never][@@ocaml.local never][@@ocaml.specialise never]
44+
45+
let raise_invalid_index ~unknown_index ~name =
46+
raise_s ((ppx_sexp_message ~unknown_index ~name)[@nontail ])
47+
[@@ocaml.inline never][@@ocaml.local never][@@ocaml.specialise never][@@zero_alloc ]

0 commit comments

Comments
 (0)