Skip to content

Commit e52f804

Browse files
committed
Compiler: do not prevent deadcode to preserve tailcall
1 parent bd51fc3 commit e52f804

File tree

2 files changed

+9
-28
lines changed

2 files changed

+9
-28
lines changed

compiler/lib/global_deadcode.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ let solver vars uses defs live_vars scoped_live_vars =
434434
+ They are returned; or
435435
+ They are applied to a function.
436436
*)
437-
let zero prog sentinal live_table =
437+
let zero prog pure_funs sentinal live_table =
438438
let compact_vars vars =
439439
let i = ref (Array.length vars - 1) in
440440
while !i >= 0 && Var.equal vars.(!i) sentinal do
@@ -486,7 +486,10 @@ let zero prog sentinal live_table =
486486
let tc =
487487
(* We don't want to break tailcalls. *)
488488
match List.last body with
489-
| Some (Let (x', Apply _)) when Code.Var.equal x' x -> true
489+
| Some (Let (x', (Apply _ as e))) when Code.Var.equal x' x ->
490+
if (not (is_live x')) && Pure_fun.pure_expr pure_funs e
491+
then false (* we don't want to stop deadcode *)
492+
else true
490493
| Some _ | None -> false
491494
in
492495
if tc then Return x else Return (zero_var x)
@@ -581,7 +584,7 @@ let f p ~deadcode_sentinal global_info =
581584
Print.print_uses uses;
582585
Print.print_live_tbl live_table);
583586
(* Zero out dead fields *)
584-
let p = zero p deadcode_sentinal live_table in
587+
let p = zero p pure_funs deadcode_sentinal live_table in
585588
if debug ()
586589
then (
587590
Format.eprintf "After Zeroing:@.";

compiler/tests-compiler/tailcall.ml

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -126,38 +126,16 @@ let%expect_test "global-deadcode-bug" =
126126
|}
127127
in
128128
Util.compile_and_run ~flags:[ "--disable"; "inline" ] prog;
129-
[%expect
130-
{|
131-
/tmp/build_b5b39e_dune/jsoo-test3c37fc/test.js:1787
132-
throw err;
133-
^
134-
135-
TypeError: Cannot read properties of undefined (reading '2')
136-
at g (/tmp/build_b5b39e_dune/jsoo-test3c37fc/test.js:1878:23)
137-
at f (/tmp/build_b5b39e_dune/jsoo-test3c37fc/test.js:1879:46)
138-
at fun1 (/tmp/build_b5b39e_dune/jsoo-test3c37fc/test.js:1880:5)
139-
at /tmp/build_b5b39e_dune/jsoo-test3c37fc/test.js:1883:4
140-
at Object.<anonymous> (/tmp/build_b5b39e_dune/jsoo-test3c37fc/test.js:1887:3)
141-
at Module._compile (node:internal/modules/cjs/loader:1734:14)
142-
at Object..js (node:internal/modules/cjs/loader:1899:10)
143-
at Module.load (node:internal/modules/cjs/loader:1469:32)
144-
at Function._load (node:internal/modules/cjs/loader:1286:12)
145-
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
146-
147-
Node.js v23.11.0
148-
129+
[%expect {|
149130
here
150-
151-
process exited with error code 7
152-
node test.js
131+
Success!
153132
|}];
154133
let program = Util.compile_and_parse ~flags:[ "--disable"; "inline" ] prog in
155134
Util.print_fun_decl program (Some "fun1");
156135
[%expect
157136
{|
158137
function fun1(param){
159-
function g(f){if(f[2]) return;}
160-
function f(x){caml_call1(Stdlib[46], cst_here); return g();}
138+
function f(x){caml_call1(Stdlib[46], cst_here);}
161139
f(5000);
162140
return log_success(0);
163141
}

0 commit comments

Comments
 (0)