aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_a.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-01-12 15:57:32 +0100
committerBjörn Gustavsson <[email protected]>2019-01-16 13:06:00 +0100
commiteb0b8da6e816afde020e3f229803045f8b2bdb89 (patch)
tree1b59ad3c0dc45ea34138495d1e0a98a5bc565ff2 /lib/compiler/src/beam_a.erl
parentc865abfcd396957e3c831a9f3dbe7922f63795be (diff)
downloadotp-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_a.erl')
-rw-r--r--lib/compiler/src/beam_a.erl12
1 files changed, 8 insertions, 4 deletions
diff --git a/lib/compiler/src/beam_a.erl b/lib/compiler/src/beam_a.erl
index dd2537a699..1ac892a8f1 100644
--- a/lib/compiler/src/beam_a.erl
+++ b/lib/compiler/src/beam_a.erl
@@ -100,8 +100,12 @@ rename_instr({bs_put_utf16=I,F,Fl,Src}) ->
{bs_put,F,{I,Fl},[Src]};
rename_instr({bs_put_utf32=I,F,Fl,Src}) ->
{bs_put,F,{I,Fl},[Src]};
-rename_instr({bs_put_string,_,_}=I) ->
- {bs_put,{f,0},I,[]};
+rename_instr({bs_put_string,_,{string,String}}) ->
+ %% Only happens when compiling from .S files. In old
+ %% .S files, String is a list. In .S in OTP 22 and later,
+ %% String is a binary.
+ {bs_put,{f,0},{bs_put_binary,8,{field_flags,[unsigned,big]}},
+ [{atom,all},{literal,iolist_to_binary([String])}]};
rename_instr({bs_add=I,F,[Src1,Src2,U],Dst}) when is_integer(U) ->
{bif,I,F,[Src1,Src2,{integer,U}],Dst};
rename_instr({bs_utf8_size=I,F,Src,Dst}) ->
@@ -118,8 +122,8 @@ rename_instr({bs_private_append=I,F,Sz,U,Src,Flags,Dst}) ->
{bs_init,F,{I,U,Flags},none,[Sz,Src],Dst};
rename_instr(bs_init_writable=I) ->
{bs_init,{f,0},I,1,[{x,0}],{x,0}};
-rename_instr({test,Op,F,[Ctx,Bits,{string,Str}]}) ->
- %% When compiling from a .S file.
+rename_instr({test,bs_match_string=Op,F,[Ctx,Bits,{string,Str}]}) when is_list(Str) ->
+ %% When compiling from an old .S file. Starting from OTP 22, Str is a binary.
<<Bs:Bits/bits,_/bits>> = list_to_binary(Str),
{test,Op,F,[Ctx,Bs]};
rename_instr({put_map_assoc,Fail,S,D,R,L}) ->