Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
6481-Improve-optimization-of-binary-matching.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 6481-Improve-optimization-of-binary-matching.patch of Package erlang
From cadd19e84478edc6e62e6b125a4d37745e913ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Wed, 7 Dec 2022 12:30:53 +0100 Subject: [PATCH] Improve optimization of binary matching The pattern matching compiler conservatively assumed that binary patterns can never be re-ordered. Actually it is safe to re-order clauses that match binaries if the first segment in each clause match the same number of bits. Re-ordering clauses can help generating better code and also help detect redundant clauses. For the following code: word(<<"AND">>) -> <<"and">>; word(<<"AS">>) -> <<"as">>; word(<<"A">>) -> <<"a">>; word(<<"AS">>) -> <<"as">>. the compiler will now generate the following warning: t.erl:6:1: Warning: this clause cannot match because a previous clause at line 5 always matches % 6| word(<<"AS">>) -> <<"as">>; % | ^ The compiler will also generate slightly better code for the same example without the redundant clause: word(<<"AND">>) -> <<"and">>; word(<<"AS">>) -> <<"as">>; word(<<"A">>) -> <<"a">>. Closes #6535 --- lib/compiler/src/v3_kernel.erl | 23 +++++++++++++++++++++-- lib/compiler/test/warnings_SUITE.erl | 7 ++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index b2ddf1afd5..70b2b56d68 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -1375,8 +1375,9 @@ select_bin_int([#iclause{pats=[#k_bin_seg{anno=A,type=integer, true -> throw(not_possible); false -> ok end, - Cs = select_bin_int_1(Cs0, Bits, Fl, Val), - [{k_bin_int,[C#iclause{pats=[P|Ps]}|Cs]}]; + Cs1 = [C#iclause{pats=[P|Ps]}|select_bin_int_1(Cs0, Bits, Fl, Val)], + Cs = reorder_bin_ints(Cs1), + [{k_bin_int,Cs}]; select_bin_int(_) -> throw(not_possible). select_bin_int_1([#iclause{pats=[#k_bin_seg{anno=A,type=integer, @@ -1419,6 +1420,24 @@ match_fun(Val) -> {match,Bs} end. +reorder_bin_ints([_]=Cs) -> + Cs; +reorder_bin_ints(Cs0) -> + %% It is safe to reorder clauses that matches binaries if the + %% first segments for all of them match the same number of bits. + Cs = sort([{reorder_bin_int_sort_key(C),C} || C <- Cs0]), + [C || {_,C} <- Cs]. + +reorder_bin_int_sort_key(#iclause{pats=[Pats|_]}) -> + case Pats of + #k_bin_int{val=Val,next=#k_bin_end{}} -> + %% Sort before clauses with additional segments. This usually results in + %% better code. + [Val]; + #k_bin_int{val=Val} -> + [Val,more] + end. + %% match_value([Var], Con, [Clause], Default, State) -> {SelectExpr,State}. %% At this point all the clauses have the same constructor, we must %% now separate them according to value. diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl index 9b860de951..ed8e324377 100644 --- a/lib/compiler/test/warnings_SUITE.erl +++ b/lib/compiler/test/warnings_SUITE.erl @@ -148,10 +148,15 @@ pattern3(Config) when is_list(Config) -> f({A,_}) -> {ok,A}; f([_|_]=B) -> {ok,B}; f({urk,nisse}) -> urka_glurka. + word(<<\"AND\">>) -> <<\"and\">>; + word(<<\"AS\">>) -> <<\"as\">>; + word(<<\"A\">>) -> <<\"a\">>; + word(<<\"AS\">>) -> <<\"as\">>. ">>, [nowarn_unused_vars], {warnings, - [{4,v3_kernel,{nomatch_shadow,2}}]}}], + [{4,v3_kernel,{nomatch_shadow,2}}, + {{8,13},v3_kernel,{nomatch_shadow,6}}]}}], [] = run(Config, Ts), ok. -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor