From 61eaa7570811d81e2a91d0126461a2dac22786dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 21 Apr 2015 15:21:48 +0200 Subject: beam_utils: Be less conservative about liveness for exit instructions beam_utils used to be overly conservative about liveness for exit instructions such as: call_ext erlang:exit/1 beam_utils would consider all y registers to be used, to avoid overwriting a catch or try tag. That does not seem to be a real risk. However, we miss opportunities for stack trimming if we consider y registers used by an exit instruction. --- lib/compiler/src/beam_utils.erl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'lib/compiler/src/beam_utils.erl') diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index fd666be41e..fca13497ba 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -344,14 +344,10 @@ check_liveness(R, [{call_ext,Live,_}=I|Is], St) -> false -> check_liveness(R, Is, St); true -> - %% We must make sure we don't check beyond this instruction - %% or we will fall through into random unrelated code and - %% get stuck in a loop. - %% - %% We don't want to overwrite a 'catch', so consider this - %% register in use. - %% - {used,St} + %% We must make sure we don't check beyond this + %% instruction or we will fall through into random + %% unrelated code and get stuck in a loop. + {killed,St} end end; check_liveness(R, [{call_fun,Live}|Is], St) -> -- cgit v1.2.3 From 808e43007754cb68dbe947ec6752698167b1c470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 21 Apr 2015 18:00:27 +0200 Subject: beam_utils: Teach check_liveness/3 to understand get_map_elements Understanding get_map_elements improves the stack trimming done by beam_trim. --- lib/compiler/src/beam_utils.erl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib/compiler/src/beam_utils.erl') diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index fca13497ba..a0132b99e3 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -468,6 +468,22 @@ check_liveness(R, [{loop_rec_end,{f,Fail}}|_], St) -> check_liveness_at(R, Fail, St); check_liveness(R, [{line,_}|Is], St) -> check_liveness(R, Is, St); +check_liveness(R, [{get_map_elements,{f,Fail},S,{list,L}}|Is], St0) -> + {Ss,Ds} = split_even(L), + case member(R, [S|Ss]) of + true -> + {used,St0}; + false -> + case check_liveness_at(R, Fail, St0) of + {killed,St}=Killed -> + case member(R, Ds) of + true -> Killed; + false -> check_liveness(R, Is, St) + end; + Other -> + Other + end + end; check_liveness(_R, Is, St) when is_list(Is) -> %% case Is of %% [I|_] -> -- cgit v1.2.3 From cc322a3749218d1e704a351f8c815d653e8c24a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Sun, 26 Apr 2015 11:26:09 +0200 Subject: beam_utils: Re-use the local helper function drop_labels/1 In 8470558, the drop_labels/1 function was added to beam_utils as a minor optimization. Since the function is already available, we might as well use it in index_label/3 too. --- lib/compiler/src/beam_utils.erl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/compiler/src/beam_utils.erl') diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index a0132b99e3..b82bcd0e95 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -128,8 +128,7 @@ empty_label_index() -> %% Add an index for a label. index_label(Lbl, Is0, Acc) -> - Is = lists:dropwhile(fun({label,_}) -> true; - (_) -> false end, Is0), + Is = drop_labels(Is0), gb_trees:enter(Lbl, Is, Acc). -- cgit v1.2.3