Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005698OCamlOCaml backend (code generation)public2012-07-24 17:332012-07-24 21:52
Reportermsawicki 
Assigned Tolefessan 
PrioritynormalSeverityminorReproducibilityalways
StatusresolvedResolutionfixed 
Platformx86_64OSLinuxOS VersionCentOS 5.7 / 6.2
Product Version3.12.0 
Target VersionFixed in Version4.01.0+dev 
Summary0005698: Assembler source reuses labels
DescriptionWhen 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
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0007802)
protz (manager)
2012-07-24 17:36

I suspect revision 11887 fixes this, could you give the current trunk or the 4.00 branch a try?
(0007803)
msawicki (reporter)
2012-07-24 17:59

Tried trunk (r12768), it is still broken.

-Marcin
(0007804)
protz (manager)
2012-07-24 18:10

Ok, http://caml.inria.fr/mantis/view.php?id=4869 [^] really did look very similar :). Thanks for testing.
(0007805)
lefessan (developer)
2012-07-24 19:26

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.
(0007807)
lefessan (developer)
2012-07-24 21:19

Fixed in SVN trunk r12770.
(0007808)
msawicki (reporter)
2012-07-24 21:52

Thanks, Fabrice!

- Issue History
Date Modified Username Field Change
2012-07-24 17:33 msawicki New Issue
2012-07-24 17:36 protz Note Added: 0007802
2012-07-24 17:59 msawicki Note Added: 0007803
2012-07-24 18:10 protz Note Added: 0007804
2012-07-24 19:26 lefessan Note Added: 0007805
2012-07-24 19:26 lefessan Assigned To => lefessan
2012-07-24 19:26 lefessan Status new => confirmed
2012-07-24 21:19 lefessan Note Added: 0007807
2012-07-24 21:19 lefessan Status confirmed => resolved
2012-07-24 21:19 lefessan Fixed in Version => 4.01.0+dev
2012-07-24 21:19 lefessan Resolution open => fixed
2012-07-24 21:52 msawicki Note Added: 0007808


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker