diff options
author | Björn Gustavsson <[email protected]> | 2019-01-12 15:57:32 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-01-16 13:06:00 +0100 |
commit | eb0b8da6e816afde020e3f229803045f8b2bdb89 (patch) | |
tree | 1b59ad3c0dc45ea34138495d1e0a98a5bc565ff2 /lib/compiler/src/beam_bs.erl | |
parent | c865abfcd396957e3c831a9f3dbe7922f63795be (diff) | |
download | otp-eb0b8da6e816afde020e3f229803045f8b2bdb89.tar.gz otp-eb0b8da6e816afde020e3f229803045f8b2bdb89.tar.bz2 otp-eb0b8da6e816afde020e3f229803045f8b2bdb89.zip |
Refactor string operands
There are two instructions that take string operands:
{bs_put_string,Fail,NumberOfBytes,{string,String}}
{bs_match_string,Fail,Register,NumberOfBits,{string,String}}
In the canonical BEAM code that is passed to beam_asm, string String
is currently represented as a list. (The string in bs_match_string is
a bitstring before the beam_z compiler pass.) That is wasteful,
because there will be unnecessary conversions between lists and
binaries.
Change the representation of String to be a binary.
Furthermore, bs_put_string is an optimization of a bs_put_binary
instruction with a literal binary operand. Currently, the
bs_put_string instruction is introduced in beam_bs. Delay the
introduction of bs_put_string to the beam_z pass. That will simplify
optimizations and allow us to do the optimization currently done
in beam_bs in a SSA pass in a future commit.
Diffstat (limited to 'lib/compiler/src/beam_bs.erl')
-rw-r--r-- | lib/compiler/src/beam_bs.erl | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/lib/compiler/src/beam_bs.erl b/lib/compiler/src/beam_bs.erl index eea0cfcd02..9cf12be1b6 100644 --- a/lib/compiler/src/beam_bs.erl +++ b/lib/compiler/src/beam_bs.erl @@ -117,17 +117,23 @@ eval_put_float(Src, Sz, Flags) when Sz =< 256 -> value({integer,I}) -> I; value({float,F}) -> F. -bs_collect_string(Is, [{bs_put,_,{bs_put_string,Len,{string,Str}},[]}|Acc]) -> - bs_coll_str_1(Is, Len, reverse(Str), Acc); +bs_collect_string(Is, [{bs_put,_,{bs_put_binary,1,_}, + [{atom,all},{literal,BinString}]}|Acc]) -> + bs_coll_str_1(Is, BinString, Acc); bs_collect_string(Is, Acc) -> - bs_coll_str_1(Is, 0, [], Acc). + bs_coll_str_1(Is, <<>>, Acc). +bs_coll_str_1([{bs_put,_,{bs_put_binary,1,_}, + [{atom,all},{literal,BinString}]}|Is], + StrAcc, IsAcc) when is_binary(BinString) -> + bs_coll_str_1(Is, <<StrAcc/binary,BinString/binary>>, IsAcc); bs_coll_str_1([{bs_put,_,{bs_put_integer,U,_},[{integer,Sz},{integer,V}]}|Is], - Len, StrAcc, IsAcc) when U*Sz =:= 8 -> + StrAcc, IsAcc) when U*Sz =:= 8 -> Byte = V band 16#FF, - bs_coll_str_1(Is, Len+1, [Byte|StrAcc], IsAcc); -bs_coll_str_1(Is, Len, StrAcc, IsAcc) -> - {Is,[{bs_put,{f,0},{bs_put_string,Len,{string,reverse(StrAcc)}},[]}|IsAcc]}. + bs_coll_str_1(Is, <<StrAcc/binary,Byte>>, IsAcc); +bs_coll_str_1(Is, StrAcc, IsAcc) -> + {Is,[{bs_put,{f,0},{bs_put_binary,1,{field_flags,[unsigned,big]}}, + [{atom,all},{literal,StrAcc}]}|IsAcc]}. field_endian({field_flags,F}) -> field_endian_1(F). |