diff --git a/CHANGES.md b/CHANGES.md index 2b2d5ae784..00ae6ddf4c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -32,6 +32,7 @@ * Compiler: more efficient code generation from bytecode (#1972) * Runtime: use Dataview to convert between floats and bit representation * Compiler: speed-up compilation by improving the scheduling of optimization passes (#1962) +* Compiler: deadcode elimination of cyclic values (#1978) ## Bug fixes * Compiler: fix stack overflow issues with double translation (#1869) diff --git a/compiler/lib/deadcode.ml b/compiler/lib/deadcode.ml index dee6a937a5..7292d1fd02 100644 --- a/compiler/lib/deadcode.ml +++ b/compiler/lib/deadcode.ml @@ -97,6 +97,14 @@ and mark_reachable st pc = let block = Addr.Map.find pc st.blocks in List.iter block.body ~f:(fun i -> match i with + | Let (_, Prim (Extern "caml_update_dummy", [ Pv x; Pv y ])) -> + if st.live.(Var.idx x) = 0 + then + (* We will keep this instruction only if x is live *) + add_def st.defs x (Field_update y) + else ( + mark_var st x; + mark_var st y) | Let (_, e) -> if not (pure_expr st.pure_funs e) then mark_expr st e | Event _ | Assign _ -> () | Set_field (x, _, _, y) -> ( @@ -131,6 +139,7 @@ and mark_reachable st pc = let live_instr st i = match i with + | Let (_, Prim (Extern "caml_update_dummy", [ Pv x; Pv _ ])) -> st.live.(Var.idx x) > 0 | Let (x, e) -> st.live.(Var.idx x) > 0 || not (pure_expr st.pure_funs e) | Assign (x, _) | Set_field (x, _, _, _) -> st.live.(Var.idx x) > 0 | Event _ | Offset_ref _ | Array_set _ -> true diff --git a/compiler/tests-compiler/dune.inc b/compiler/tests-compiler/dune.inc index b5a6e77332..c5cc6d8aff 100644 --- a/compiler/tests-compiler/dune.inc +++ b/compiler/tests-compiler/dune.inc @@ -869,6 +869,21 @@ (preprocess (pps ppx_expect))) +(library + ;; compiler/tests-compiler/update_dummy.ml + (name update_dummy_15) + (enabled_if true) + (modules update_dummy) + (libraries js_of_ocaml_compiler unix str jsoo_compiler_expect_tests_helper) + (inline_tests + (enabled_if true) + (deps + (file %{project_root}/compiler/bin-js_of_ocaml/js_of_ocaml.exe) + (file %{project_root}/compiler/bin-jsoo_minify/jsoo_minify.exe))) + (flags (:standard -open Jsoo_compiler_expect_tests_helper)) + (preprocess + (pps ppx_expect))) + (library ;; compiler/tests-compiler/variable_declaration_output.ml (name variable_declaration_output_15) diff --git a/compiler/tests-compiler/update_dummy.ml b/compiler/tests-compiler/update_dummy.ml new file mode 100644 index 0000000000..d74dabc86d --- /dev/null +++ b/compiler/tests-compiler/update_dummy.ml @@ -0,0 +1,21 @@ +open Util + +let%expect_test "deadcode elimination of cyclic values" = + let program = + compile_and_parse + {| + let f () = + let rec x = 1 :: x in + let rec y = 1 :: y in + snd (x, y) + |} + in + print_fun_decl program (Some "f"); + [%expect + {| + function f(param){ + var y = []; + runtime.caml_update_dummy(y, [0, 1, y]); + return y; + } + //end |}]