aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-10-06 09:25:53 +0200
committerBjörn Gustavsson <[email protected]>2017-10-11 09:59:41 +0200
commit119713b4d9ad6649aa5f1d0bf492e2f35a0ced01 (patch)
treef9643f6f423116af35d06f0b85f1bd5601f365be /lib/compiler
parent5fa3ac7e10f45ad433ac6a44f32f9b5e96b56fcd (diff)
downloadotp-119713b4d9ad6649aa5f1d0bf492e2f35a0ced01.tar.gz
otp-119713b4d9ad6649aa5f1d0bf492e2f35a0ced01.tar.bz2
otp-119713b4d9ad6649aa5f1d0bf492e2f35a0ced01.zip
Optimize a catch whose return value is ignored
Rewrite a catch expression like this: catch side_effect(), ... to: try side_effect() catch _:_ -> ok end, ... A try/catch is more efficient since no stack trace will be built when an exception occurs.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/sys_core_fold.erl9
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index f3f315935a..df880ff784 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -418,6 +418,15 @@ expr(#c_call{module=M0,name=N0}=Call0, Ctxt, Sub) ->
expr(#c_primop{args=As0}=Prim, _, Sub) ->
As1 = expr_list(As0, value, Sub),
Prim#c_primop{args=As1};
+expr(#c_catch{anno=Anno,body=B}, effect, Sub) ->
+ %% When the return value of the 'catch' is ignored, we can replace it
+ %% with a try/catch to avoid building a stack trace when an exception
+ %% occurs.
+ Var = #c_var{name='catch_value'},
+ Evs = [#c_var{name='Class'},#c_var{name='Reason'},#c_var{name='Stk'}],
+ Try = #c_try{anno=Anno,arg=B,vars=[Var],body=Var,
+ evars=Evs,handler=void()},
+ expr(Try, effect, Sub);
expr(#c_catch{body=B0}=Catch, _, Sub) ->
%% We can remove catch if the value is simple
B1 = body(B0, value, Sub),