diff options
author | Björn Gustavsson <[email protected]> | 2017-10-20 06:11:04 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2017-10-21 07:50:12 +0200 |
commit | 6753bbcc3fdb0dd15c8025902d22dc4ec8c33575 (patch) | |
tree | cc84ad335e0018b9572e777756f9f6876787e893 /lib/compiler/src/v3_codegen.erl | |
parent | 3ea750a53874d61ef7d4d806656ca63c7759a8a4 (diff) | |
download | otp-6753bbcc3fdb0dd15c8025902d22dc4ec8c33575.tar.gz otp-6753bbcc3fdb0dd15c8025902d22dc4ec8c33575.tar.bz2 otp-6753bbcc3fdb0dd15c8025902d22dc4ec8c33575.zip |
Optimize matching of literals for single-valued types
If a type only has one clause and if the pattern is literal,
the matching can be done more efficiently by directly comparing
with the literal.
Example:
find(String, "") -> String;
find(String, <<>>) -> String;
find(String, SearchPattern) ->
.
.
.
Without this optimization, the relevant part of the code would look
this:
{test,bs_start_match2,{f,3},2,[{x,1},0],{x,2}}.
{test,bs_test_tail2,{f,4},[{x,2},0]}.
return.
{label,3}.
{test,is_nil,{f,4},[{x,1}]}.
return.
{label,4}.
.
.
.
That is, if {x,1} is a binary, a match context will be built to
test whether {x,1} is an empty binary.
With the optimization, the code will look this:
{test,is_eq_exact,{f,3},[{x,1},{literal,<<>>}]}.
return.
{label,3}.
{test,is_nil,{f,4},[{x,1}]}.
return.
{label,4}.
.
.
.
Diffstat (limited to 'lib/compiler/src/v3_codegen.erl')
-rw-r--r-- | lib/compiler/src/v3_codegen.erl | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl index e705aefb96..ee5bafbc5c 100644 --- a/lib/compiler/src/v3_codegen.erl +++ b/lib/compiler/src/v3_codegen.erl @@ -654,6 +654,8 @@ select_cg(#l{ke={type_clause,bin_end,[S]}}, {var,V}, Tf, _Vf, Bef, St) -> select_bin_end(S, V, Tf, Bef, St); select_cg(#l{ke={type_clause,map,S}}, {var,V}, Tf, Vf, Bef, St) -> select_map(S, V, Tf, Vf, Bef, St); +select_cg(#l{ke={type_clause,literal,S}}, {var,V}, Tf, Vf, Bef, St) -> + select_literal(S, V, Tf, Vf, Bef, St); select_cg(#l{ke={type_clause,Type,Scs}}, {var,V}, Tf, Vf, Bef, St0) -> {Vis,{Aft,St1}} = mapfoldl(fun (S, {Int,Sta}) -> @@ -695,6 +697,15 @@ add_vls([V|Vs], Lbl, Acc) -> add_vls(Vs, Lbl, [V, {f,Lbl}|Acc]); add_vls([], _, Acc) -> Acc. +select_literal(S, V, Tf, Vf, Bef, St) -> + Reg = fetch_var(V, Bef), + F = fun(ValClause, Fail, St0) -> + {Val,Is,Aft,St1} = select_val(ValClause, V, Vf, Bef, St0), + Test = {test,is_eq_exact,{f,Fail},[Reg,{literal,Val}]}, + {[Test|Is],Aft,St1} + end, + match_fmf(F, Tf, St, S). + select_cons(#l{ke={val_clause,{cons,Es},B},i=I,vdb=Vdb}, V, Tf, Vf, Bef, St0) -> {Eis,Int,St1} = select_extract_cons(V, Es, I, Vdb, Bef, St0), {Bis,Aft,St2} = match_cg(B, Vf, Int, St1), |