You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 5698 Reporter: msawicki Assigned to:@lefessan Status: closed (set by @xavierleroy on 2015-12-11T18:07:25Z) Resolution: fixed Priority: normal Severity: minor Platform: x86_64 OS: Linux OS Version: CentOS 5.7 / 6.2 Version: 3.12.0 Fixed in version: 4.01.0+dev Category: back end (clambda to assembly) Monitored by:@lefessan
Bug description
When compiling large machine-generated code, the assembler files (*.s) sometimes reuse labels (.L200000 in the example below), which breaks the compilation.
We suspect this is related to cross-library inlining.
The example below, generate_code_1.ml, will generate two files: tons_of_match_statements.ml and tons_of_match_statements_b.ml, which, when compiled with the options given below (in particular, -inline 20), cause the label .L200000 to be used twice in the assembler source (tons_of_match_statements_b.s).
This is of course an artificial example. Our real-life code which triggers this bug creates hundreds of label conflicts in a single .s file (which I wasn't able to reproduce using simpler code).
Thank you,
-Marcin Sawicki
Jane Street
Steps to reproduce
$ ocamlopt -version
3.12.0+ocamlspotter-1.2
$ cat ./genererate_code_1.ml
open Printf
let kk = 6010
let nn = 10
let generate_function oc name k default =
fprintf oc "let %s%d = function\n" name k;
let x = Hashtbl.create nn in
for i = 1 to nn do
let r = Random.int 20000 in if not (Hashtbl.mem x r) then Hashtbl.add x r ()
done;
let xl = List.sort compare (Hashtbl.fold (fun k () acc -> k::acc) x []) in
List.iter (fun k -> fprintf oc "| %d -> %d\n" k (Random.int 1_000_000_000)) xl;
fprintf oc "| %s\n" (default k);
fprintf oc ";;\n\n"
;;
let generate_module_a () =
let oc = open_out "tons_of_match_statements.ml" in
for k = 1 to kk do
generate_function oc "a" k (fun _ -> "_ -> -13")
done;
close_out oc
;;
let generate_module_b () =
let oc = open_out "tons_of_match_statements_b.ml" in
fprintf oc "module T = Tons_of_match_statements\n";
for k = 1 to kk do
generate_function oc "b" k (sprintf "x -> T.a%d x")
done;
fprintf oc "let ()=\n";
for i = 1 to kk do
fprintf oc "Printf.printf "%%d\n" (b%d 2828);\n" i
done;
fprintf oc ";;\n";
close_out oc
;;
tons_of_match_statements_b.s: Assembler messages:
tons_of_match_statements_b.s:1094237: Error: symbol `.L200000' is already defined
File "tons_of_match_statements_b.ml", line 1, characters 0-1:
Error: Assembler error, input left in file tons_of_match_statements_b.s
EXIT STATUS 2
Problem comes from asmcomp/emitaux.ml:172, where 200000 is hardcoded as the beginning label for frame filenames. I will try a fix using Linearize.new_label instead.
Original bug ID: 5698
Reporter: msawicki
Assigned to: @lefessan
Status: closed (set by @xavierleroy on 2015-12-11T18:07:25Z)
Resolution: fixed
Priority: normal
Severity: minor
Platform: x86_64
OS: Linux
OS Version: CentOS 5.7 / 6.2
Version: 3.12.0
Fixed in version: 4.01.0+dev
Category: back end (clambda to assembly)
Monitored by: @lefessan
Bug description
When compiling large machine-generated code, the assembler files (*.s) sometimes reuse labels (.L200000 in the example below), which breaks the compilation.
We suspect this is related to cross-library inlining.
The example below, generate_code_1.ml, will generate two files: tons_of_match_statements.ml and tons_of_match_statements_b.ml, which, when compiled with the options given below (in particular, -inline 20), cause the label .L200000 to be used twice in the assembler source (tons_of_match_statements_b.s).
This is of course an artificial example. Our real-life code which triggers this bug creates hundreds of label conflicts in a single .s file (which I wasn't able to reproduce using simpler code).
Thank you,
-Marcin Sawicki
Jane Street
Steps to reproduce
$ ocamlopt -version
3.12.0+ocamlspotter-1.2
$ cat ./genererate_code_1.ml
open Printf
let kk = 6010
let nn = 10
let generate_function oc name k default =
fprintf oc "let %s%d = function\n" name k;
let x = Hashtbl.create nn in
for i = 1 to nn do
let r = Random.int 20000 in if not (Hashtbl.mem x r) then Hashtbl.add x r ()
done;
let xl = List.sort compare (Hashtbl.fold (fun k () acc -> k::acc) x []) in
List.iter (fun k -> fprintf oc "| %d -> %d\n" k (Random.int 1_000_000_000)) xl;
fprintf oc "| %s\n" (default k);
fprintf oc ";;\n\n"
;;
let generate_module_a () =
let oc = open_out "tons_of_match_statements.ml" in
for k = 1 to kk do
generate_function oc "a" k (fun _ -> "_ -> -13")
done;
close_out oc
;;
let generate_module_b () =
let oc = open_out "tons_of_match_statements_b.ml" in
fprintf oc "module T = Tons_of_match_statements\n";
for k = 1 to kk do
generate_function oc "b" k (sprintf "x -> T.a%d x")
done;
fprintf oc "let ()=\n";
for i = 1 to kk do
fprintf oc "Printf.printf "%%d\n" (b%d 2828);\n" i
done;
fprintf oc ";;\n";
close_out oc
;;
let () =
Random.init 137;
generate_module_a ();
Random.init 196;
generate_module_b ();
exit 0
;;
$ ocaml ./generate_code_1.ml && ocamlopt -thread -w @a-4-7-9-29-28 -strict-sequence -annot -inline 20 -nodynlink -g -S tons_of_match_statements.ml tons_of_match_statements_b.ml
tons_of_match_statements_b.s: Assembler messages:
tons_of_match_statements_b.s:1094237: Error: symbol `.L200000' is already defined
File "tons_of_match_statements_b.ml", line 1, characters 0-1:
Error: Assembler error, input left in file tons_of_match_statements_b.s
EXIT STATUS 2
$ /bin/egrep --color=always -5 '^[.]L200000' ./tons_of_match_statements_b.s
.L199999:
leaq camlTons_of_match_statements_b__11711(%rip), %rax
call camlPrintf__printf_1393
.L200000:
movq %rax, %rbx
movq $43, %rax
cmpq $13101, %rax
jbe .L199047
cmpq $13103, %rax
.L200000:
.asciz "tons_of_match_statements_b.ml"
.align 8
.section .note.GNU-stack,"",%progbits
The text was updated successfully, but these errors were encountered: