aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_jump.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-10-21 09:27:59 +0200
committerBjörn Gustavsson <[email protected]>2018-10-22 07:21:08 +0200
commit58d6a866dae481a098ea583439cac3fbb95df787 (patch)
treec5724cc55f70c0b870a6a533b09c702f77caad19 /lib/compiler/src/beam_jump.erl
parent7f5279f9e0c8ee6ac013328be65e687841fb425c (diff)
downloadotp-58d6a866dae481a098ea583439cac3fbb95df787.tar.gz
otp-58d6a866dae481a098ea583439cac3fbb95df787.tar.bz2
otp-58d6a866dae481a098ea583439cac3fbb95df787.zip
Make the move elimination optimization in beam_jump safe
The `beam_jump` pass could eliminate `move` instructions when it was not safe to do so. See the new test case `unsafe_move_elimination/1` for an example. Reported-by: Michał Muskała
Diffstat (limited to 'lib/compiler/src/beam_jump.erl')
-rw-r--r--lib/compiler/src/beam_jump.erl13
1 files changed, 5 insertions, 8 deletions
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index fbff4cfd79..d694bd2a5b 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -196,22 +196,19 @@ no_fallthrough([I|_]) ->
is_unreachable_after(I).
already_has_value(Lit, Lbl, Reg, D) ->
- Key = {Lbl,Reg},
case D of
- #{Lbl:=unsafe} ->
- false;
- #{Key:=Lit} ->
+ #{Lbl:={Reg,Lit}} ->
true;
#{} ->
false
end.
update_value_dict([Lit,{f,Lbl}|T], Reg, D0) ->
- Key = {Lbl,Reg},
D = case D0 of
- #{Key := inconsistent} -> D0;
- #{Key := _} -> D0#{Key := inconsistent};
- _ -> D0#{Key => Lit}
+ #{Lbl:=unsafe} -> D0;
+ #{Lbl:={Reg,Lit}} -> D0;
+ #{Lbl:=_} -> D0#{Lbl:=unsafe};
+ #{} -> D0#{Lbl=>{Reg,Lit}}
end,
update_value_dict(T, Reg, D);
update_value_dict([], _, D) -> D.