diff options
author | John Högberg <[email protected]> | 2019-03-27 14:09:28 +0100 |
---|---|---|
committer | John Högberg <[email protected]> | 2019-03-27 14:09:28 +0100 |
commit | 3ae5e291972d8c56682aa62df8e9ca015442538a (patch) | |
tree | 001f23f37b54f67b794c1f33ff93c8f0b9793413 /lib/compiler/src | |
parent | 52dd4f4842d9c3314e7c10a4e05ceafdfc636649 (diff) | |
parent | a5976a6a6065e0d5c0c3ca118f50494c10fdc5a7 (diff) | |
download | otp-3ae5e291972d8c56682aa62df8e9ca015442538a.tar.gz otp-3ae5e291972d8c56682aa62df8e9ca015442538a.tar.bz2 otp-3ae5e291972d8c56682aa62df8e9ca015442538a.zip |
Merge branch 'john/compiler/fix-type-opt-no-return/ERL-897'
* john/compiler/fix-type-opt-no-return/ERL-897:
compiler: Fully disable no_return optimizations in try blocks
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/beam_ssa_type.erl | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl index c01ea4af91..06b42f1928 100644 --- a/lib/compiler/src/beam_ssa_type.erl +++ b/lib/compiler/src/beam_ssa_type.erl @@ -267,10 +267,29 @@ opt_is([#b_set{op=call,args=Args0,dst=Dst}=I0|Is], I1 = beam_ssa:normalize(I0#b_set{args=Args}), {Ts1,Ds,Fdb,I2} = opt_call(I1, D, Ts0, Ds0, Fdb0), case {map_get(Dst, Ts1),Is} of - {_,[#b_set{op=succeeded}]} -> + {Type,[#b_set{op=succeeded}]} when Type =/= none -> %% This call instruction is inside a try/catch - %% block. Don't attempt to optimize it. + %% block. Don't attempt to simplify it. opt_is(Is, Ts1, Ds, Fdb, D, Sub0, [I2|Acc]); + {none,[#b_set{op=succeeded}]} -> + %% This call instruction is inside a try/catch + %% block, but we know it will never return and + %% later optimizations may try to exploit that. + %% + %% For example, if we have an expression that + %% either returns this call or a tuple, we know + %% that the expression always returns a tuple + %% and can turn a later element/3 into + %% get_tuple_element. + %% + %% This is sound but difficult to validate in a + %% meaningful way as try/catch currently forces + %% us to maintain the illusion that the success + %% block is reachable even when its not, so we + %% disable the optimization to keep things + %% simple. + Ts = Ts1#{ Dst := any }, + opt_is(Is, Ts, Ds, Fdb, D, Sub0, [I2|Acc]); {none,_} -> %% This call never returns. The rest of the %% instructions will not be executed. |