Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
0448-Combine-adjacent-map-update-operations.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0448-Combine-adjacent-map-update-operations.patch of Package erlang
From ec36d500f80032c257d48b5cda33640ee96eecc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Sat, 30 Jul 2022 08:59:29 +0200 Subject: [PATCH 2/2] Combine adjacent map update operations Combine adjacent map update operations such as: A = #{key1 => V1, key2 => V2}, A#{key3 => V3}. Such code are used not written directly, but it can result from use of macros or inlining. --- lib/compiler/src/beam_ssa_opt.erl | 65 ++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl index 5a29ec6b6a..d77a4b2bdd 100644 --- a/lib/compiler/src/beam_ssa_opt.erl +++ b/lib/compiler/src/beam_ssa_opt.erl @@ -1025,6 +1025,30 @@ cse_is([#b_set{op={succeeded,_},dst=Bool,args=[Src]}=I0|Is], Es, Sub0, Acc) -> Sub = Sub0#{Bool=>#b_literal{val=true}}, cse_is(Is, Es, Sub, Acc) end; +cse_is([#b_set{op=put_map,dst=Dst,args=[_Kind,Map|_]}=I0|Is], + Es0, Sub0, Acc) -> + I1 = sub(I0, Sub0), + {ok,ExprKey} = cse_expr(I1), + case Es0 of + #{ExprKey:=PrevPutMap} -> + Sub = Sub0#{Dst=>PrevPutMap}, + cse_is(Is, Es0, Sub, Acc); + #{Map:=PutMap} -> + case combine_put_maps(PutMap, I1) of + none -> + Es1 = Es0#{ExprKey=>Dst}, + Es = cse_add_inferred_exprs(I1, Es1), + cse_is(Is, Es, Sub0, [I1|Acc]); + I -> + Es1 = Es0#{ExprKey=>Dst}, + Es = cse_add_inferred_exprs(I1, Es1), + cse_is(Is, Es, Sub0, [I|Acc]) + end; + #{} -> + Es1 = Es0#{ExprKey=>Dst}, + Es = cse_add_inferred_exprs(I1, Es1), + cse_is(Is, Es, Sub0, [I1|Acc]) + end; cse_is([#b_set{dst=Dst}=I0|Is], Es0, Sub0, Acc) -> I = sub(I0, Sub0), case beam_ssa:clobbers_xregs(I) of @@ -1073,8 +1097,9 @@ cse_add_inferred_exprs(#b_set{op={bif,tl},dst=Tl,args=[List]}, Es) -> Es#{{get_tl,[List]} => Tl}; cse_add_inferred_exprs(#b_set{op={bif,map_get},dst=Value,args=[Key,Map]}, Es) -> Es#{{get_map_element,[Map,Key]} => Value}; -cse_add_inferred_exprs(#b_set{op=put_map,dst=Map,args=[_,_|Args]}, Es) -> - cse_add_map_get(Args, Map, Es); +cse_add_inferred_exprs(#b_set{op=put_map,dst=Map,args=[_,_|Args]}=I, Es0) -> + Es = cse_add_map_get(Args, Map, Es0), + Es#{Map => I}; cse_add_inferred_exprs(_, Es) -> Es. cse_add_map_get([Key,Value|T], Map, Es0) -> @@ -1113,6 +1138,42 @@ cse_suitable(#b_set{anno=Anno,op={bif,Name},args=Args}) -> erl_internal:bool_op(Name, Arity)); cse_suitable(#b_set{}) -> false. +combine_put_maps(#b_set{dst=Prev,args=[#b_literal{val=assoc},Map|Args1]}, + #b_set{args=[#b_literal{val=assoc},Prev|Args2]}=I) -> + case are_map_keys_literals(Args1) andalso are_map_keys_literals(Args2) of + true -> + Args = combine_put_map_args(Args1, Args2), + I#b_set{args=[#b_literal{val=assoc},Map|Args]}; + false -> + none + end; +combine_put_maps(#b_set{}, #b_set{}) -> + none. + +combine_put_map_args(Args1, Args2) -> + Keys = sets:from_list(get_map_keys(Args2), [{version,2}]), + combine_put_map_args_1(Args1, Args2, Keys). + +combine_put_map_args_1([Key,Value|T], Tail, Keys) -> + case sets:is_element(Key, Keys) of + true -> + combine_put_map_args_1(T, Tail, Keys); + false -> + [Key,Value|combine_put_map_args_1(T, Tail, Keys)] + end; +combine_put_map_args_1([], Tail, _Keys) -> Tail. + +get_map_keys([Key,_|T]) -> + [Key|get_map_keys(T)]; +get_map_keys([]) -> []. + +are_map_keys_literals([#b_literal{},_Value|Args]) -> + are_map_keys_literals(Args); +are_map_keys_literals([#b_var{}|_]) -> + false; +are_map_keys_literals([]) -> + true. + %%% %%% Using floating point instructions. %%% -- 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