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

Simplify doesn't seem to like symbol grouping from Lambda_to_flambda #542

Open
Keryan-dev opened this issue Jul 6, 2021 · 0 comments
Open

Comments

@Keryan-dev
Copy link

Keryan-dev commented Jul 6, 2021

Working on PR #540 and #541, which need to group symbols of closures and code to have a correct order of declarations. I stumbled on failures in Simplify and Un_cps.

The following examples are run with #541 which group every symbols in a single let-binding.

let f n =
  let rec loop i =
    loop (i + n)
  in
  loop 0

It gives us after CPS conversion (in a concise form):

let-symbol f_0_0_code = (ref to loop_1_1_code in closure)
and loop_1_1_code = (no dependencies)
and f_0 = (closure for f_0_0_code)

To which Simplify react with:

>> Fatal error: Patricia_tree.disjoint_union: key f_0_0_code is in intersection

Tweaking the example we can obtain a different error:

let g m n = m - n
let f n =
  let rec loop i =
    if i >= n then g n 42 else
    loop (i + 1)
  in
  loop 0
let-symbol g_0_0_code = (no dependencies)
and f_1_1_code = (ref to loop_2_2_code in closure)
and loop_2_2_code = (ref to symbol g_0)
and g_0 = (closure for g_0_0_code)
and f_1 = (closure for f_1_1_code)
>> Fatal error: Code ID camlTest__loop_2_5_code not bound
Context is: translating function camlTest__f_1_3_code to Cmm with return cont k69, exn cont k70 and body:

In this case, Simplify produces:

let-symbol loop_2_2_code = (ref to symbol g_0)
and f_1_1_code = (ref to loop_2_2_code in closure)
and g_0_0_code = (no dependencies)
and g_0 = (closure for g_0_4_code) (* ! *)
and g_0_4_code = (no dependencies)
and f_1 = (closure for f_1_3_code) (* ! *)
and f_1_3_code = (ref to loop_2_5_code in closure) (* ! *)

So we have g_0_0_code, f_1_1_code and loop_2_2_code unused and loop_2_5_code undefined.

Going further with #540, which sorts the declarations to group symbols only where its needed.

The examples above are no longer an issue but we can still find code that triggers odd behaviors:

let rec f w =
  let fa, af = f w in
    (fun x -> fa x),
    (fun x -> af x)
let-symbol anon_1_1_code = (no dependencies)
           anon_2_2_code = (no dependencies)
let-symbol f_0 = (closure for f_0_0_code)
and f_0_0_code = (ref to anon_1_1_code in closure
                  ref to anon_2_2_code in closure
                  ref to symbol f_0)
>> Fatal error: Code ID anon_1_1_code not bound

After simplify:

let-symbol anon_1_1_code = (deleted)
           anon_2_2_code = (no dependencies) (* ! *)
           anon_1_4_code = (no dependencies)
           anon_2_5_code = (no dependencies)
let-symbol f_0_0_code = (ref to anon_1_1_code in closure
                         ref to anon_2_2_code in closure
                         ref to symbol f_0)
and f_0 = (closure of f_0_3_code) (* ! *)
and f_0_3_code = (ref to anon_1_4_code in closure
                  ref to anon_2_5_code in closure
                  ref to symbol f_0)

So we have f_0_0_code and anon_2_2_code unused but not deleted, which causes the error. Unlike the previous example the code would be correct by deleting them.

For completeness, the same example with #541 raises:

>> Fatal error: Patricia_tree.disjoint_union: key f_0_3_code is in intersection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant