Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assembler source reuses labels #5698

Closed
vicuna opened this issue Jul 24, 2012 · 6 comments
Closed

Assembler source reuses labels #5698

vicuna opened this issue Jul 24, 2012 · 6 comments
Assignees

Comments

@vicuna
Copy link

vicuna commented Jul 24, 2012

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

    movq    (%rbx), %rdi
    call    *%rdi

.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

    .word   17
    .word   0
    .align  8
    .long   (.L200000 - .) + 0x78000000
    .long   0x148a0000

.L200000:
.asciz "tons_of_match_statements_b.ml"
.align 8
.section .note.GNU-stack,"",%progbits

@vicuna
Copy link
Author

vicuna commented Jul 24, 2012

Comment author: @protz

I suspect revision 11887 fixes this, could you give the current trunk or the 4.00 branch a try?

@vicuna
Copy link
Author

vicuna commented Jul 24, 2012

Comment author: msawicki

Tried trunk (r12768), it is still broken.

-Marcin

@vicuna
Copy link
Author

vicuna commented Jul 24, 2012

Comment author: @protz

Ok, #4869 really did look very similar :). Thanks for testing.

@vicuna
Copy link
Author

vicuna commented Jul 24, 2012

Comment author: @lefessan

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.

@vicuna
Copy link
Author

vicuna commented Jul 24, 2012

Comment author: @lefessan

Fixed in SVN trunk r12770.

@vicuna
Copy link
Author

vicuna commented Jul 24, 2012

Comment author: msawicki

Thanks, Fabrice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants