diff options
author | Björn Gustavsson <[email protected]> | 2015-08-05 19:12:15 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-08-21 15:56:14 +0200 |
commit | 3640e5c89bda0ca45b3320e8a00efb48b9d9f531 (patch) | |
tree | 24d721f71f1879a6d1cf7b46002c14ab97ba4155 /lib/compiler | |
parent | c288ab87fd6cafe22ce46be551baa2e815b495b0 (diff) | |
download | otp-3640e5c89bda0ca45b3320e8a00efb48b9d9f531.tar.gz otp-3640e5c89bda0ca45b3320e8a00efb48b9d9f531.tar.bz2 otp-3640e5c89bda0ca45b3320e8a00efb48b9d9f531.zip |
Reorder instructions across try/catch
Simplify further optimizations by moving safe instructions to
before the 'try' or 'catch' instruction.
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_reorder.erl | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_reorder.erl b/lib/compiler/src/beam_reorder.erl index 3230e33dbd..70adca6b04 100644 --- a/lib/compiler/src/beam_reorder.erl +++ b/lib/compiler/src/beam_reorder.erl @@ -64,6 +64,16 @@ reorder(Is) -> D = beam_utils:index_labels(Is), reorder_1(Is, D, []). +reorder_1([{Op,_,_}=TryCatch|[I|Is]=Is0], D, Acc) + when Op =:= 'catch'; Op =:= 'try' -> + %% Don't allow 'try' or 'catch' instructions to split blocks if + %% it can be avoided. + case is_safe(I) of + false -> + reorder_1(Is0, D, [TryCatch|Acc]); + true -> + reorder_1([TryCatch|Is], D, [I|Acc]) + end; reorder_1([{label,L}=I|_], D, Acc) -> Is = beam_utils:code_at(L, D), reorder_1(Is, D, [I|Acc]); @@ -111,3 +121,14 @@ reorder_1([{allocate_zero,N,Live}|Is], D, reorder_1([I|Is], D, Acc) -> reorder_1(Is, D, [I|Acc]); reorder_1([], _, Acc) -> reverse(Acc). + +%% is_safe(Instruction) -> true|false +%% Test whether an instruction is safe (cannot cause an exception). + +is_safe({kill,_}) -> true; +is_safe({move,_,_}) -> true; +is_safe({put,_}) -> true; +is_safe({put_list,_,_,_}) -> true; +is_safe({put_tuple,_,_}) -> true; +is_safe({test_heap,_,_}) -> true; +is_safe(_) -> false. |