diff options
author | Björn-Egil Dahlberg <[email protected]> | 2014-02-21 11:39:07 +0100 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2014-02-21 11:39:07 +0100 |
commit | 2d3c60dbd941ac4408488414b6e8434405ad24a5 (patch) | |
tree | 19d6f56c13b5068ada890b8050ce6576a64d4f54 /lib/compiler/src/v3_codegen.erl | |
parent | 2b7d4bebe6d7ecf79d78ead792237a458798be5f (diff) | |
parent | 1c37990e06a4588b941f430f872ad45001b63844 (diff) | |
download | otp-2d3c60dbd941ac4408488414b6e8434405ad24a5.tar.gz otp-2d3c60dbd941ac4408488414b6e8434405ad24a5.tar.bz2 otp-2d3c60dbd941ac4408488414b6e8434405ad24a5.zip |
Merge branch 'egil/compiler/maps-get_map_elements'
* egil/compiler/maps-get_map_elements:
compiler: Strengthen Maps compile tests
compiler: Remove dead warning
erts: Fix erts_debug:disassemble/1
compiler: Transform list of Args to exact literal type
compiler: Test Maps aliasing
compiler: Use aliasing in map pair patterns
compiler: Check literal order in beam_validator
erts: Introduce new instructions for combined key fetches
compiler: Change map instructions for fetching values
Diffstat (limited to 'lib/compiler/src/v3_codegen.erl')
-rw-r--r-- | lib/compiler/src/v3_codegen.erl | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl index 4d155c0fd0..e00ee1f3ad 100644 --- a/lib/compiler/src/v3_codegen.erl +++ b/lib/compiler/src/v3_codegen.erl @@ -938,22 +938,39 @@ select_map_val(V, Es, B, Fail, I, Vdb, Bef, St0) -> {Bis,Aft,St2} = match_cg(B, Fail, Int, St1), {Eis++Bis,Aft,St2}. +select_extract_map(_, [], _, _, _, Bef, St) -> {[],Bef,St}; select_extract_map(Src, Vs, Fail, I, Vdb, Bef, St) -> - F = fun ({map_pair,Key,{var,V}}, Int0) -> - Rsrc = fetch_var(Src, Int0), + %% First split the instruction flow + %% We want one set of each + %% 1) has_map_fields (no target registers) + %% 2) get_map_elements (with target registers) + %% Assume keys are term-sorted + Rsrc = fetch_var(Src, Bef), + + {{HasKs,GetVs},Aft} = lists:foldr(fun + ({map_pair,Key,{var,V}},{{HasKsi,GetVsi},Int0}) -> case vdb_find(V, Vdb) of {V,_,L} when L =< I -> - {[{test,has_map_field,{f,Fail},[Rsrc,Key]}],Int0}; + {{[Key|HasKsi],GetVsi},Int0}; _Other -> Reg1 = put_reg(V, Int0#sr.reg), Int1 = Int0#sr{reg=Reg1}, - {[{get_map_element,{f,Fail}, - Rsrc,Key,fetch_reg(V, Reg1)}], - Int1} + {{HasKsi,[Key,fetch_reg(V, Reg1)|GetVsi]},Int1} end - end, - {Es,Aft} = flatmapfoldl(F, Bef, Vs), - {Es,Aft,St}. + end, {{[],[]},Bef}, Vs), + + Code = case {HasKs,GetVs} of + {[],[]} -> {[],Aft,St}; + {HasKs,[]} -> + [{test,has_map_fields,{f,Fail},Rsrc,{list,HasKs}}]; + {[],GetVs} -> + [{get_map_elements, {f,Fail},Rsrc,{list,GetVs}}]; + {HasKs,GetVs} -> + [{test,has_map_fields,{f,Fail},Rsrc,{list,HasKs}}, + {get_map_elements, {f,Fail},Rsrc,{list,GetVs}}] + end, + {Code, Aft, St}. + select_extract_cons(Src, [{var,Hd}, {var,Tl}], I, Vdb, Bef, St) -> {Es,Aft} = case {vdb_find(Hd, Vdb), vdb_find(Tl, Vdb)} of |