From d4379900790b37498fefa237cd03ab2d5781bb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 6 Nov 2013 08:58:32 +0100 Subject: compiler: Teach Maps understanding to inliner --- lib/compiler/src/cerl.erl | 107 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 6 deletions(-) (limited to 'lib/compiler/src/cerl.erl') diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl index 4b74d60e9f..30bb4c5d96 100644 --- a/lib/compiler/src/cerl.erl +++ b/lib/compiler/src/cerl.erl @@ -120,7 +120,16 @@ update_c_bitstr/5, update_c_bitstr/6, ann_c_bitstr/5, ann_c_bitstr/6, is_c_bitstr/1, bitstr_val/1, bitstr_size/1, bitstr_bitsize/1, bitstr_unit/1, bitstr_type/1, - bitstr_flags/1]). + bitstr_flags/1, + + %% keep map exports here for now + map_es/1, + update_c_map_skel/2, + update_c_map_pair_assoc_skel/2, update_c_map_pair_exact_skel/2, + ann_c_map_skel/2, + ann_c_map_pair_assoc_skel/2, ann_c_map_pair_exact_skel/2, + map_pair_es/1, map_pair_assoc_es/1, map_pair_exact_es/1 + ]). -export_type([c_binary/0, c_call/0, c_clause/0, c_cons/0, c_fun/0, c_literal/0, c_module/0, c_tuple/0, c_values/0, c_var/0, cerl/0, var_name/0]). @@ -250,8 +259,8 @@ -type ctype() :: 'alias' | 'apply' | 'binary' | 'bitrst' | 'call' | 'case' | 'catch' | 'clause' | 'cons' | 'fun' | 'let' | 'letrec' - | 'literal' | 'module' | 'primop' | 'receive' | 'seq' | 'try' - | 'tuple' | 'values' | 'var'. + | 'literal' | 'map' | 'module' | 'primop' | 'receive' | 'seq' + | 'try' | 'tuple' | 'values' | 'var'. -spec type(cerl()) -> ctype(). @@ -268,6 +277,9 @@ type(#c_fun{}) -> 'fun'; type(#c_let{}) -> 'let'; type(#c_letrec{}) -> letrec; type(#c_literal{}) -> literal; +type(#c_map{}) -> map; +type(#c_map_pair_assoc{}) -> map_pair_assoc; +type(#c_map_pair_exact{}) -> map_pair_exact; type(#c_module{}) -> module; type(#c_primop{}) -> primop; type(#c_receive{}) -> 'receive'; @@ -1557,6 +1569,58 @@ ann_make_list(_, [], Node) -> Node. +%% --------------------------------------------------------------------- +%% maps + +map_es(#c_map{es = Es}) -> + Es. + +map_pair_assoc_es(#c_map_pair_assoc{key=K,val=V}) -> [K,V]. +map_pair_exact_es(#c_map_pair_exact{key=K,val=V}) -> [K,V]. +map_pair_es(#c_map_pair_assoc{key=K,val=V}) -> [K,V]; +map_pair_es(#c_map_pair_exact{key=K,val=V}) -> [K,V]. + +update_c_map_pair_assoc_skel(Old, [K,V]) -> + #c_map_pair_assoc{key=K, val=V, anno = get_ann(Old)}. + +update_c_map_pair_exact_skel(Old, [K,V]) -> + #c_map_pair_exact{key=K, val=V, anno = get_ann(Old)}. + +ann_c_map_pair_assoc_skel(As, [K,V]) -> + #c_map_pair_assoc{key = K, val=V, anno = As}. + +ann_c_map_pair_exact_skel(As, [K,V]) -> + #c_map_pair_exact{key = K, val=V, anno = As}. + +%c_map_skel(Es) -> +% #c_map{es = Es}. +% + +ann_c_map(As, Es) -> + #c_map{es = Es, anno = As }. +%% TODO: when we have map literals use a variant of +%% case is_lit_list(Es) of +%% false -> +%% #c_map{es = Es, anno = As}; +%% true -> +%% #c_literal{val = maps:from_list(lit_list_vals(Es)), anno = As} +%% end. + + +ann_c_map_pair_assoc(As, [K,V]) -> + #c_map_pair_assoc{key = K, val=V, anno = As}. + +ann_c_map_pair_exact(As, [K,V]) -> + #c_map_pair_exact{key = K, val=V, anno = As}. + + +ann_c_map_skel(As, Es) -> + #c_map{es = Es, anno = As}. + +update_c_map_skel(Old, Es) -> + #c_map{es = Es, anno = get_ann(Old)}. + + %% --------------------------------------------------------------------- %% @spec c_tuple(Elements::[cerl()]) -> cerl() @@ -2945,6 +3009,10 @@ pat_vars(Node, Vs) -> pat_vars(cons_hd(Node), pat_vars(cons_tl(Node), Vs)); tuple -> pat_list_vars(tuple_es(Node), Vs); + map -> + pat_list_vars(map_es(Node), Vs); + map_pair_exact -> + pat_list_vars(map_pair_exact_es(Node), Vs); binary -> pat_list_vars(binary_segments(Node), Vs); bitstr -> @@ -3756,6 +3824,12 @@ is_data(#c_cons{}) -> true; is_data(#c_tuple{}) -> true; +is_data(#c_map{}) -> + true; +is_data(#c_map_pair_assoc{}) -> + true; +is_data(#c_map_pair_exact{}) -> + true; is_data(_) -> false. @@ -3801,7 +3875,13 @@ data_type(#c_literal{val = V}) -> data_type(#c_cons{}) -> cons; data_type(#c_tuple{}) -> - tuple. + tuple; +data_type(#c_map{}) -> + map; +data_type(#c_map_pair_assoc{}) -> + map_pair_assoc; +data_type(#c_map_pair_exact{}) -> + map_pair_exact. %% @spec data_es(Node::cerl()) -> [cerl()] @@ -3833,7 +3913,13 @@ data_es(#c_literal{val = V}) -> data_es(#c_cons{hd = H, tl = T}) -> [H, T]; data_es(#c_tuple{es = Es}) -> - Es. + Es; +data_es(#c_map{es=Es}) -> + Es; +data_es(#c_map_pair_assoc{key=K,val=V}) -> + [K,V]; +data_es(#c_map_pair_exact{key=K,val=V}) -> + [K,V]. %% @spec data_arity(Node::cerl()) -> integer() @@ -3890,7 +3976,10 @@ make_data(CType, Es) -> ann_make_data(As, {atomic, V}, []) -> #c_literal{val = V, anno = As}; ann_make_data(As, cons, [H, T]) -> ann_c_cons(As, H, T); -ann_make_data(As, tuple, Es) -> ann_c_tuple(As, Es). +ann_make_data(As, tuple, Es) -> ann_c_tuple(As, Es); +ann_make_data(As, map, Es) -> ann_c_map(As, Es); +ann_make_data(As, map_pair_assoc, Es) -> ann_c_map_pair_assoc(As, Es); +ann_make_data(As, map_pair_exact, Es) -> ann_c_map_pair_exact(As, Es). %% @spec update_data(Old::cerl(), Type::dtype(), @@ -4022,6 +4111,12 @@ subtrees(T) -> [[cons_hd(T)], [cons_tl(T)]]; tuple -> [tuple_es(T)]; + map -> + [map_es(T)]; + map_pair_assoc -> + [map_pair_assoc_es(T)]; + map_pair_exact -> + [map_pair_exact_es(T)]; 'let' -> [let_vars(T), [let_arg(T)], [let_body(T)]]; seq -> -- cgit v1.2.3 From 64e5677c883990e1d5b5666d857413293910972a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 12 Nov 2013 12:19:30 +0100 Subject: compiler: Add Maps types to cerl --- lib/compiler/src/cerl.erl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/compiler/src/cerl.erl') diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl index 30bb4c5d96..c6bf046c4d 100644 --- a/lib/compiler/src/cerl.erl +++ b/lib/compiler/src/cerl.erl @@ -154,6 +154,9 @@ -type c_let() :: #c_let{}. -type c_letrec() :: #c_letrec{}. -type c_literal() :: #c_literal{}. +-type c_map() :: #c_map{}. +-type c_map_pair_assoc() :: #c_map_pair_assoc{}. +-type c_map_pair_exact() :: #c_map_pair_exact{}. -type c_module() :: #c_module{}. -type c_primop() :: #c_primop{}. -type c_receive() :: #c_receive{}. @@ -164,9 +167,10 @@ -type c_var() :: #c_var{}. -type cerl() :: c_alias() | c_apply() | c_binary() | c_bitstr() - | c_call() | c_case() | c_catch() | c_clause() | c_cons() + | c_call() | c_case() | c_catch() | c_clause() | c_cons() | c_fun() | c_let() | c_letrec() | c_literal() - | c_module() | c_primop() | c_receive() | c_seq() + | c_map() | c_map_pair_assoc() | c_map_pair_exact() + | c_module() | c_primop() | c_receive() | c_seq() | c_try() | c_tuple() | c_values() | c_var(). %% ===================================================================== @@ -1572,6 +1576,8 @@ ann_make_list(_, [], Node) -> %% --------------------------------------------------------------------- %% maps +-spec map_es(c_map()) -> [cerl()]. + map_es(#c_map{es = Es}) -> Es. -- cgit v1.2.3 From 5b4b6c9b6bd1cf258841004f2e11bb2a82ebfe24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Mon, 13 Jan 2014 18:05:00 +0100 Subject: compiler: Squash #c_map_pair_*{} to #c_map_pair{} Simplify compiler internals and parsing of core format. --- lib/compiler/src/cerl.erl | 106 ++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 80 deletions(-) (limited to 'lib/compiler/src/cerl.erl') diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl index c6bf046c4d..60a8559950 100644 --- a/lib/compiler/src/cerl.erl +++ b/lib/compiler/src/cerl.erl @@ -124,11 +124,11 @@ %% keep map exports here for now map_es/1, - update_c_map_skel/2, - update_c_map_pair_assoc_skel/2, update_c_map_pair_exact_skel/2, - ann_c_map_skel/2, - ann_c_map_pair_assoc_skel/2, ann_c_map_pair_exact_skel/2, - map_pair_es/1, map_pair_assoc_es/1, map_pair_exact_es/1 + update_c_map/2, + ann_c_map/2, + map_pair_op/1,map_pair_key/1,map_pair_val/1, + update_c_map_pair/4, + ann_c_map_pair/4 ]). -export_type([c_binary/0, c_call/0, c_clause/0, c_cons/0, c_fun/0, c_literal/0, @@ -155,8 +155,7 @@ -type c_letrec() :: #c_letrec{}. -type c_literal() :: #c_literal{}. -type c_map() :: #c_map{}. --type c_map_pair_assoc() :: #c_map_pair_assoc{}. --type c_map_pair_exact() :: #c_map_pair_exact{}. +-type c_map_pair() :: #c_map_pair{}. -type c_module() :: #c_module{}. -type c_primop() :: #c_primop{}. -type c_receive() :: #c_receive{}. @@ -169,7 +168,7 @@ -type cerl() :: c_alias() | c_apply() | c_binary() | c_bitstr() | c_call() | c_case() | c_catch() | c_clause() | c_cons() | c_fun() | c_let() | c_letrec() | c_literal() - | c_map() | c_map_pair_assoc() | c_map_pair_exact() + | c_map() | c_map_pair() | c_module() | c_primop() | c_receive() | c_seq() | c_try() | c_tuple() | c_values() | c_var(). @@ -282,8 +281,7 @@ type(#c_let{}) -> 'let'; type(#c_letrec{}) -> letrec; type(#c_literal{}) -> literal; type(#c_map{}) -> map; -type(#c_map_pair_assoc{}) -> map_pair_assoc; -type(#c_map_pair_exact{}) -> map_pair_exact; +type(#c_map_pair{}) -> map_pair; type(#c_module{}) -> module; type(#c_primop{}) -> primop; type(#c_receive{}) -> 'receive'; @@ -1581,50 +1579,24 @@ ann_make_list(_, [], Node) -> map_es(#c_map{es = Es}) -> Es. -map_pair_assoc_es(#c_map_pair_assoc{key=K,val=V}) -> [K,V]. -map_pair_exact_es(#c_map_pair_exact{key=K,val=V}) -> [K,V]. -map_pair_es(#c_map_pair_assoc{key=K,val=V}) -> [K,V]; -map_pair_es(#c_map_pair_exact{key=K,val=V}) -> [K,V]. - -update_c_map_pair_assoc_skel(Old, [K,V]) -> - #c_map_pair_assoc{key=K, val=V, anno = get_ann(Old)}. - -update_c_map_pair_exact_skel(Old, [K,V]) -> - #c_map_pair_exact{key=K, val=V, anno = get_ann(Old)}. - -ann_c_map_pair_assoc_skel(As, [K,V]) -> - #c_map_pair_assoc{key = K, val=V, anno = As}. - -ann_c_map_pair_exact_skel(As, [K,V]) -> - #c_map_pair_exact{key = K, val=V, anno = As}. - -%c_map_skel(Es) -> -% #c_map{es = Es}. -% - ann_c_map(As, Es) -> #c_map{es = Es, anno = As }. -%% TODO: when we have map literals use a variant of -%% case is_lit_list(Es) of -%% false -> -%% #c_map{es = Es, anno = As}; -%% true -> -%% #c_literal{val = maps:from_list(lit_list_vals(Es)), anno = As} -%% end. - -ann_c_map_pair_assoc(As, [K,V]) -> - #c_map_pair_assoc{key = K, val=V, anno = As}. +update_c_map(Old, Es) -> + #c_map{es = Es, anno = get_ann(Old)}. -ann_c_map_pair_exact(As, [K,V]) -> - #c_map_pair_exact{key = K, val=V, anno = As}. +map_pair_key(#c_map_pair{key=K}) -> K. +map_pair_val(#c_map_pair{val=V}) -> V. +map_pair_op(#c_map_pair{op=Op}) -> Op. +-spec ann_c_map_pair([term()], cerl(), cerl(), cerl()) -> + c_map_pair(). -ann_c_map_skel(As, Es) -> - #c_map{es = Es, anno = As}. +ann_c_map_pair(As,Op,K,V) -> + #c_map_pair{op=Op, key = K, val=V, anno = As}. -update_c_map_skel(Old, Es) -> - #c_map{es = Es, anno = get_ann(Old)}. +update_c_map_pair(Old,Op,K,V) -> + #c_map_pair{op=Op, key=K, val=V, anno = get_ann(Old)}. %% --------------------------------------------------------------------- @@ -3017,8 +2989,8 @@ pat_vars(Node, Vs) -> pat_list_vars(tuple_es(Node), Vs); map -> pat_list_vars(map_es(Node), Vs); - map_pair_exact -> - pat_list_vars(map_pair_exact_es(Node), Vs); + map_pair -> + pat_list_vars([map_pair_op(Node),map_pair_key(Node),map_pair_val(Node)],Vs); binary -> pat_list_vars(binary_segments(Node), Vs); bitstr -> @@ -3830,12 +3802,6 @@ is_data(#c_cons{}) -> true; is_data(#c_tuple{}) -> true; -is_data(#c_map{}) -> - true; -is_data(#c_map_pair_assoc{}) -> - true; -is_data(#c_map_pair_exact{}) -> - true; is_data(_) -> false. @@ -3881,14 +3847,7 @@ data_type(#c_literal{val = V}) -> data_type(#c_cons{}) -> cons; data_type(#c_tuple{}) -> - tuple; -data_type(#c_map{}) -> - map; -data_type(#c_map_pair_assoc{}) -> - map_pair_assoc; -data_type(#c_map_pair_exact{}) -> - map_pair_exact. - + tuple. %% @spec data_es(Node::cerl()) -> [cerl()] %% @@ -3919,14 +3878,7 @@ data_es(#c_literal{val = V}) -> data_es(#c_cons{hd = H, tl = T}) -> [H, T]; data_es(#c_tuple{es = Es}) -> - Es; -data_es(#c_map{es=Es}) -> - Es; -data_es(#c_map_pair_assoc{key=K,val=V}) -> - [K,V]; -data_es(#c_map_pair_exact{key=K,val=V}) -> - [K,V]. - + Es. %% @spec data_arity(Node::cerl()) -> integer() %% @@ -3982,11 +3934,7 @@ make_data(CType, Es) -> ann_make_data(As, {atomic, V}, []) -> #c_literal{val = V, anno = As}; ann_make_data(As, cons, [H, T]) -> ann_c_cons(As, H, T); -ann_make_data(As, tuple, Es) -> ann_c_tuple(As, Es); -ann_make_data(As, map, Es) -> ann_c_map(As, Es); -ann_make_data(As, map_pair_assoc, Es) -> ann_c_map_pair_assoc(As, Es); -ann_make_data(As, map_pair_exact, Es) -> ann_c_map_pair_exact(As, Es). - +ann_make_data(As, tuple, Es) -> ann_c_tuple(As, Es). %% @spec update_data(Old::cerl(), Type::dtype(), %% Elements::[cerl()]) -> cerl() @@ -4119,10 +4067,8 @@ subtrees(T) -> [tuple_es(T)]; map -> [map_es(T)]; - map_pair_assoc -> - [map_pair_assoc_es(T)]; - map_pair_exact -> - [map_pair_exact_es(T)]; + map_pair -> + [[map_pair_op(T)],[map_pair_key(T)],[map_pair_val(T)]]; 'let' -> [let_vars(T), [let_arg(T)], [let_body(T)]]; seq -> -- cgit v1.2.3