diff options
author | John Högberg <[email protected]> | 2019-06-25 12:56:24 +0200 |
---|---|---|
committer | John Högberg <[email protected]> | 2019-07-05 11:33:38 +0200 |
commit | 02c74c89232ed72f16c2a326e0c15938c3493041 (patch) | |
tree | 31d7c9db862cccd7750cc5b91abe4bed3ddb5ecd /lib/compiler/src/beam_ssa_codegen.erl | |
parent | 1e4e506b5c3af02632da29b0802e913121403bf4 (diff) | |
download | otp-02c74c89232ed72f16c2a326e0c15938c3493041.tar.gz otp-02c74c89232ed72f16c2a326e0c15938c3493041.tar.bz2 otp-02c74c89232ed72f16c2a326e0c15938c3493041.zip |
compiler: Introduce exception trampolines
When the compiler is smart enough to figure out that something
will always succeed, it will get rid of the failure branch, but
the inverse has not been possible because liveness optimization
could end up removing the instruction altogether (since it's never
used on the failure path), which is not okay when exceptions are in
the picture.
To prevent exception-generating instructions from being optimized
away when their branches are, we introduce a dummy instruction
that refers to the result on the failure path, ensuring that it
won't be optimized away.
Diffstat (limited to 'lib/compiler/src/beam_ssa_codegen.erl')
-rw-r--r-- | lib/compiler/src/beam_ssa_codegen.erl | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_ssa_codegen.erl b/lib/compiler/src/beam_ssa_codegen.erl index 7248aca5f3..7102f524d0 100644 --- a/lib/compiler/src/beam_ssa_codegen.erl +++ b/lib/compiler/src/beam_ssa_codegen.erl @@ -965,6 +965,12 @@ cg_block(Is0, Last, Next, St0) -> case Last of #cg_br{succ=Next,fail=Next} -> cg_block(Is0, none, St0); + #cg_br{succ=Same,fail=Same} when Same =:= ?BADARG_BLOCK -> + %% An expression in this block *always* throws an exception, so we + %% terminate it with an 'if_end' to make sure the validator knows + %% that the following instructions won't actually be reached. + {Is,St} = cg_block(Is0, none, St0), + {Is++[if_end],St}; #cg_br{succ=Same,fail=Same} -> {Fail,St1} = use_block_label(Same, St0), {Is,St} = cg_block(Is0, none, St1), |