[erlang-patches] binary matching optimization error
Christian von Roques
roques@REDACTED
Thu Aug 21 19:21:17 CEST 2008
Using R12B-3 I recently wrote code similar to the following:
-module(bug).
-export([foo/2]).
%% foo(<<1,2>>, 2) should evaluate to <<1,2>>, but evaluates to <<2>>
%% when compiled without no_bsm_opt
foo(Bin, 0) ->
foo(Bin, 42);
foo(<<_A, Rest/bitstring>>, 1) ->
foo(Rest, 43);
foo(Bin, _I) ->
Bin.
beam_bsm "optimizes" foo/2 to the following:
{function, foo, 2, 2}.
{label,1}.
{func_info,{atom,bug},{atom,foo},2}.
{label,2}.
{test,is_eq_exact,{f,3},[{x,1},{integer,0}]}.
{bs_context_to_binary,{x,0}}.
{move,{integer,42},{x,1}}.
{call_only,2,{f,2}}.
{label,3}.
{test,bs_start_match2,{f,4},[{x,0},2,0,{x,0}]}.
{test,bs_skip_bits2,
{f,4},
[{x,0},
{integer,8},
1,
{field_flags,[{anno,[7,{file,"./bug.erl"}]},unsigned,big]}]}.
{'%',{bin_opt,[7,{file,"./bug.erl"}]}}.
{bs_save2,{x,0},{atom,start}}.
{move,{x,0},{x,2}}.
{test,is_eq_exact,{f,4},[{x,1},{integer,1}]}.
{move,{integer,43},{x,1}}.
{move,{x,2},{x,0}}.
{call_only,2,{f,2}}.
{label,4}.
{bs_context_to_binary,{x,0}}.
return.
The problem seems to be, that the match state needs to be saved so
that after a tail-recursive call to foo(Rest, 43) the
bs_context_to_binary at {label 2} results in shortened binary and at
the same time the match state must not be saved so that
bs_context_to_binary at {label 4} yields the unshortened binary.
I've come up with a minor modification of beam_bsm, which detects
cases like these and disables "optimizing" them.
Another possible solution could be to push the bs_save2 downwards
until after the match is complete.
Christian.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: beam_bsm.erl.patch
Type: text/x-diff
Size: 2163 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-patches/attachments/20080821/39c89621/attachment.bin>
More information about the erlang-patches
mailing list