aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/v3_codegen.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-10-20 06:11:04 +0200
committerBjörn Gustavsson <[email protected]>2017-10-21 07:50:12 +0200
commit6753bbcc3fdb0dd15c8025902d22dc4ec8c33575 (patch)
treecc84ad335e0018b9572e777756f9f6876787e893 /lib/compiler/src/v3_codegen.erl
parent3ea750a53874d61ef7d4d806656ca63c7759a8a4 (diff)
downloadotp-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.erl11
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),