diff options
author | Björn Gustavsson <[email protected]> | 2015-02-27 12:17:05 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-03-09 09:41:18 +0100 |
commit | c5e808c27beeef8cfc5eaa4ab37aeaaaef3db849 (patch) | |
tree | c662a184ce3d83c0ec478fb250848302d2b18c7d /lib/compiler/src/v3_core.erl | |
parent | 09dfc3ba50174c55733b11db70d444f62b029302 (diff) | |
download | otp-c5e808c27beeef8cfc5eaa4ab37aeaaaef3db849.tar.gz otp-c5e808c27beeef8cfc5eaa4ab37aeaaaef3db849.tar.bz2 otp-c5e808c27beeef8cfc5eaa4ab37aeaaaef3db849.zip |
v3_core: Add is_map tests before map instructions
If we have a sequence of put_map_* instructions operating on the
same map, it will be more efficient if we can have one is_map/2
instruction before put_map_* instructions, so that each put_map_*
does not need to test whether the argument is a map.
Diffstat (limited to 'lib/compiler/src/v3_core.erl')
-rw-r--r-- | lib/compiler/src/v3_core.erl | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 9478dc9579..cd44fb459b 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -758,30 +758,28 @@ make_bool_switch_guard(L, E, V, T, F) -> {clause,NegL,[V],[],[V]} ]}. -expr_map(M0,Es0,A,St0) -> - {M1,Mps,St1} = safe(M0, St0), +expr_map(M0, Es0, A, St0) -> + {M1,Eps0,St1} = safe(M0, St0), case is_valid_map_src(M1) of true -> - case {M1,Es0} of - {#c_var{}, []} -> - %% transform M#{} to is_map(M) - {Vpat,St2} = new_var(St1), - {Fpat,St3} = new_var(St2), - Cs = [#iclause{ - anno=A, - pats=[Vpat], - guard=[#icall{anno=#a{anno=A}, + {M2,Eps1,St2} = map_build_pairs(M1, Es0, A, St1), + M3 = case Es0 of + [] -> M1; + [_|_] -> M2 + end, + Cs = [#iclause{ + anno=#a{anno=[compiler_generated|A]}, + pats=[], + guard=[#icall{anno=#a{anno=A}, module=#c_literal{anno=A,val=erlang}, name=#c_literal{anno=A,val=is_map}, - args=[Vpat]}], - body=[Vpat]}], - Fc = fail_clause([Fpat], A, #c_literal{val=badarg}), - {#icase{anno=#a{anno=A},args=[M1],clauses=Cs,fc=Fc},Mps,St3}; - {_,_} -> - {M2,Eps,St2} = map_build_pairs(M1, Es0, A, St1), - {M2,Mps++Eps,St2} - end; - false -> throw({bad_map,bad_map}) + args=[M1]}], + body=[M3]}], + Fc = fail_clause([], [eval_failure|A], #c_literal{val=badarg}), + Eps = Eps0 ++ Eps1, + {#icase{anno=#a{anno=A},args=[],clauses=Cs,fc=Fc},Eps,St2}; + false -> + throw({bad_map,bad_map}) end. map_build_pairs(Map, Es0, Ann, St0) -> |