diff options
author | Björn Gustavsson <[email protected]> | 2018-10-21 09:27:59 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-10-22 07:21:08 +0200 |
commit | 58d6a866dae481a098ea583439cac3fbb95df787 (patch) | |
tree | c5724cc55f70c0b870a6a533b09c702f77caad19 /lib/compiler/src | |
parent | 7f5279f9e0c8ee6ac013328be65e687841fb425c (diff) | |
download | otp-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')
-rw-r--r-- | lib/compiler/src/beam_jump.erl | 13 |
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. |