-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
compiler: Change some bifs to guard bifs in try/catch #9042
compiler: Change some bifs to guard bifs in try/catch #9042
Conversation
CT Test ResultsNo tests were run for this PR. This is either because the build failed, or the PR is based on a branch without GH actions tests configured. Results for commit ad10c97 To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass. See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally. Artifacts// Erlang/OTP Github Action Bot |
51eea9a
to
d02498c
Compare
lib/compiler/test/beam_ssa_check_SUITE_data/non_throwing_bifs.erl
Outdated
Show resolved
Hide resolved
5446359
to
b8e73f9
Compare
lib/compiler/src/beam_ssa_opt.erl
Outdated
arity=A}=R0|Args0]}=I0|Is], | ||
Acc) -> | ||
%% Rewrite binary_to_atom/1 call to binary_to_atom/2. | ||
{I1, Args1} = if {M, F, A} =:= {erlang, binary_to_atom, 1} -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the same be done for binary_to_existing_atom
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks for pointing out!
What's the criteria to tell if a BIF can or cannot be optimised in this way? |
A BIF can be optimized this way if it's pure (i.e. does not change the state). If it's not pure, it's not always safe to remove the try/catch around it. Edit: Apparently I failed to count for |
6edf639
to
19834c0
Compare
When put in a try, calling a guard bif with no side-effects is already optimized to remove the try/catch. However, there are bifs with side-effects that can be safely optimized in the same way in order to gain performance. Example code: try binary_to_atom(A, utf8) catch _:_ -> [] end. Before, SSA for the bif call after optimizations: _6 = call (`erlang`:`binary_to_atom`/2), _0, `utf8` _14 = succeeded:body _6 Now, SSA for the bif call after optimizations: _6 = bif:binary_to_atom _0, `utf8` _14 = succeeded:guard _6 Bifs that are optimized for try/catch in this change: `binary_to_atom/1`, `binary_to_atom/2`, `binary_to_existing_atom/1`, `binary_to_existing_atom/2`, `list_to_atom/1`, `list_to_existing_atom/1`.
19834c0
to
ad10c97
Compare
When put in a try, calling a guard bif with no side-effects and 6 other bifs ([PR-9042](erlang#9042)) are optimized to remove the try/catch. However, most pure bifs can be safely optimized in the same way in order to gain performance. This PR introduces a new internal instruction `call_pseudo_guard_bif` that enables the compiler to remove the try/catch around the bif. The instruction is designed to call the bif in the same way, but having more optimized error-handling in the runtime system. Example code: try float_to_list(A, utf8) catch _:_ -> error end. Before, assembly for the bif call after optimizations: {label,2}. {allocate,1,1}. {'try',{y,0},{f,3}}. {line,[{location,"zlc.erl",23}]}. {call_ext,1,{extfunc,erlang,float_to_list,1}}. {try_end,{y,0}}. {deallocate,1}. return. Now, assembly for the bif call after optimizations: {label,2}. {allocate,0,1}. {line,[{location,"zlc.erl",23}]}. {call_pseudo_guard_bif,1,{extfunc,erlang,float_to_list,1},{f,3}}. {deallocate,0}. return. Bifs that are optimized for try/catch in this change are listed in `pbif.tab`.
This is a fix for [PR-9042](erlang#9042). `binary_to_atom/1` and `binary_to_existing_atom/1` now use the correct optimization. Tests for SSA in `non_throwing_bifs.erl` are fixed and added to the correct suite.
When put in a try, calling a guard bif with no side-effects is already optimized to remove the try/catch. However, there are bifs with side-effects that can be safely optimized in the same way in order to gain performance.
Example code:
Before, SSA for the bif call after optimizations:
Now, SSA for the bif call after optimizations:
Bifs that are optimized for try/catch in this change:
binary_to_atom/1
,binary_to_atom/2
,binary_to_existing_atom/1
,binary_to_existing_atom/2
,list_to_atom/1
,list_to_existing_atom/1
.