aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-08-31 19:14:10 +0200
committerBjörn Gustavsson <[email protected]>2012-10-09 15:24:41 +0200
commited7ab81375d599c73cbe0d2195102187957c25d6 (patch)
treef2e4114919a1e79be55f6171997febf33c0b9f27
parentb44f86b779f0b8579e4df2a98930ac3150c6c07c (diff)
downloadotp-ed7ab81375d599c73cbe0d2195102187957c25d6.tar.gz
otp-ed7ab81375d599c73cbe0d2195102187957c25d6.tar.bz2
otp-ed7ab81375d599c73cbe0d2195102187957c25d6.zip
Rewrite bs_add, bs_utf*_size to BIF instructions in optimizations
We can remove some code bloat by handling the special instructions as BIF instructions in the optimization passes. Also note that bs_utf*_size was not handled by beam_utils:check_liveness/3 (meaning the conservative answer instead of the correct answer would be returned).
-rw-r--r--lib/compiler/src/beam_a.erl6
-rw-r--r--lib/compiler/src/beam_bsm.erl8
-rw-r--r--lib/compiler/src/beam_clean.erl6
-rw-r--r--lib/compiler/src/beam_jump.erl6
-rw-r--r--lib/compiler/src/beam_trim.erl5
-rw-r--r--lib/compiler/src/beam_utils.erl18
-rw-r--r--lib/compiler/src/beam_z.erl6
7 files changed, 12 insertions, 43 deletions
diff --git a/lib/compiler/src/beam_a.erl b/lib/compiler/src/beam_a.erl
index 4a8ba9743a..3709b94c3c 100644
--- a/lib/compiler/src/beam_a.erl
+++ b/lib/compiler/src/beam_a.erl
@@ -58,4 +58,10 @@ 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_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}) ->
+ {bif,I,F,[Src],Dst};
+rename_instr({bs_utf16_size=I,F,Src,Dst}) ->
+ {bif,I,F,[Src],Dst};
rename_instr(I) -> I.
diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl
index aaf48d4587..dd3b5f5c04 100644
--- a/lib/compiler/src/beam_bsm.erl
+++ b/lib/compiler/src/beam_bsm.erl
@@ -293,8 +293,6 @@ btb_reaches_match_2([{jump,{f,Lbl}}|_], Regs, #btb{index=Li}=D) ->
btb_reaches_match_2(Is, Regs, D);
btb_reaches_match_2([{label,_}|Is], Regs, D) ->
btb_reaches_match_2(Is, Regs, D);
-btb_reaches_match_2([{bs_add,{f,0},_,Dst}|Is], Regs, D) ->
- btb_reaches_match_1(Is, btb_kill([Dst], Regs), D);
btb_reaches_match_2([bs_init_writable|Is], Regs0, D) ->
Regs = btb_kill_not_live(0, Regs0),
btb_reaches_match_1(Is, Regs, D);
@@ -311,12 +309,6 @@ btb_reaches_match_2([{bs_private_append,{f,0},_,_,Src,_,Dst}=I|Is], Regs, D) ->
btb_reaches_match_2([{bs_put,{f,0},_,Ss}=I|Is], Regs, D) ->
btb_ensure_not_used(Ss, I, Regs),
btb_reaches_match_1(Is, Regs, D);
-btb_reaches_match_2([{bs_utf8_size,_,Src,Dst}=I|Is], Regs, D) ->
- btb_ensure_not_used([Src], I, Regs),
- btb_reaches_match_1(Is, btb_kill([Dst], Regs), D);
-btb_reaches_match_2([{bs_utf16_size,_,Src,Dst}=I|Is], Regs, D) ->
- btb_ensure_not_used([Src], I, Regs),
- btb_reaches_match_1(Is, btb_kill([Dst], Regs), D);
btb_reaches_match_2([{bs_restore2,Src,_}=I|Is], Regs0, D) ->
case btb_contains_context(Src, Regs0) of
false ->
diff --git a/lib/compiler/src/beam_clean.erl b/lib/compiler/src/beam_clean.erl
index fea653e1e7..083ccb32fa 100644
--- a/lib/compiler/src/beam_clean.erl
+++ b/lib/compiler/src/beam_clean.erl
@@ -248,15 +248,9 @@ replace([{bs_init_bits,{f,Lbl},Sz,Words,R,F,Dst}|Is], Acc, D) when Lbl =/= 0 ->
replace(Is, [{bs_init_bits,{f,label(Lbl, D)},Sz,Words,R,F,Dst}|Acc], D);
replace([{bs_put,{f,Lbl},Info,Ss}|Is], Acc, D) when Lbl =/= 0 ->
replace(Is, [{bs_put,{f,label(Lbl, D)},Info,Ss}|Acc], D);
-replace([{bs_add,{f,Lbl},Src,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{bs_add,{f,label(Lbl, D)},Src,Dst}|Acc], D);
replace([{bs_append,{f,Lbl},_,_,_,_,_,_,_}=I0|Is], Acc, D) when Lbl =/= 0 ->
I = setelement(2, I0, {f,label(Lbl, D)}),
replace(Is, [I|Acc], D);
-replace([{bs_utf8_size=I,{f,Lbl},Src,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{I,{f,label(Lbl, D)},Src,Dst}|Acc], D);
-replace([{bs_utf16_size=I,{f,Lbl},Src,Dst}|Is], Acc, D) when Lbl =/= 0 ->
- replace(Is, [{I,{f,label(Lbl, D)},Src,Dst}|Acc], D);
replace([I|Is], Acc, D) ->
replace(Is, [I|Acc], D);
replace([], Acc, _) -> Acc.
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index e87085134b..deb7c2033f 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -541,14 +541,8 @@ ulbl({bs_init_bits,Lbl,_,_,_,_,_}, Used) ->
mark_used(Lbl, Used);
ulbl({bs_put,Lbl,_,_}, Used) ->
mark_used(Lbl, Used);
-ulbl({bs_add,Lbl,_,_}, Used) ->
- mark_used(Lbl, Used);
ulbl({bs_append,Lbl,_,_,_,_,_,_,_}, Used) ->
mark_used(Lbl, Used);
-ulbl({bs_utf8_size,Lbl,_,_}, Used) ->
- mark_used(Lbl, Used);
-ulbl({bs_utf16_size,Lbl,_,_}, Used) ->
- mark_used(Lbl, Used);
ulbl(_, Used) -> Used.
mark_used({f,0}, Used) -> Used;
diff --git a/lib/compiler/src/beam_trim.erl b/lib/compiler/src/beam_trim.erl
index 5856f0d3b5..8f694f602b 100644
--- a/lib/compiler/src/beam_trim.erl
+++ b/lib/compiler/src/beam_trim.erl
@@ -172,9 +172,6 @@ remap([{bif,Name,Fail,Ss,D}|Is], Map, Acc) ->
remap([{gc_bif,Name,Fail,Live,Ss,D}|Is], Map, Acc) ->
I = {gc_bif,Name,Fail,Live,[Map(S) || S <- Ss],Map(D)},
remap(Is, Map, [I|Acc]);
-remap([{bs_add,Fail,[SrcA,SrcB,U],D}|Is], Map, Acc) ->
- I = {bs_add,Fail,[Map(SrcA),Map(SrcB),U],Map(D)},
- remap(Is, Map, [I|Acc]);
remap([{bs_append=Op,Fail,Bits,Heap,Live,Unit,Bin,Flags,D}|Is], Map, Acc) ->
I = {Op,Fail,Map(Bits),Heap,Live,Unit,Map(Bin),Flags,Map(D)},
remap(Is, Map, [I|Acc]);
@@ -287,8 +284,6 @@ frame_size([{test,_,{f,L},_}|Is], Safe) ->
frame_size_branch(L, Is, Safe);
frame_size([{test,_,{f,L},_,_,_}|Is], Safe) ->
frame_size_branch(L, Is, Safe);
-frame_size([{bs_add,{f,L},_,_}|Is], Safe) ->
- frame_size_branch(L, Is, Safe);
frame_size([{bs_append,{f,L},_,_,_,_,_,_,_}|Is], Safe) ->
frame_size_branch(L, Is, Safe);
frame_size([{bs_private_append,{f,L},_,_,_,_,_}|Is], Safe) ->
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 400979bc19..be6cc56eaa 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -427,12 +427,6 @@ check_liveness(R, [{gc_bif,Op,{f,Fail},Live,Ss,D}|Is], St0) ->
Other
end
end;
-check_liveness(R, [{bs_add,{f,0},Ss,D}|Is], St) ->
- case member(R, Ss) of
- true -> {used,St};
- false when R =:= D -> {killed,St};
- false -> check_liveness(R, Is, St)
- end;
check_liveness(R, [{bs_put,{f,0},_,Ss}|Is], St) ->
case member(R, Ss) of
true -> {used,St};
@@ -676,10 +670,6 @@ combine_alloc_lists_1([]) -> [].
live_opt([{bs_context_to_binary,Src}=I|Is], Regs0, D, Acc) ->
Regs = x_live([Src], Regs0),
live_opt(Is, Regs, D, [I|Acc]);
-live_opt([{bs_add,Fail,[Src1,Src2,_],Dst}=I|Is], Regs0, D, Acc) ->
- Regs1 = x_live([Src1,Src2], x_dead([Dst], Regs0)),
- Regs = live_join_label(Fail, D, Regs1),
- live_opt(Is, Regs, D, [I|Acc]);
live_opt([{bs_init2,Fail,Sz,Extra,Live0,Fl,Dst}|Is], Regs0, D, Acc) ->
Regs1 = x_dead([Dst], Regs0),
Live = live_regs(Regs1),
@@ -719,14 +709,6 @@ live_opt([{bs_restore2,Src,_}=I|Is], Regs0, D, Acc) ->
live_opt([{bs_save2,Src,_}=I|Is], Regs0, D, Acc) ->
Regs = x_live([Src], Regs0),
live_opt(Is, Regs, D, [I|Acc]);
-live_opt([{bs_utf8_size,Fail,Src,Dst}=I|Is], Regs0, D, Acc) ->
- Regs1 = x_live([Src], x_dead([Dst], Regs0)),
- Regs = live_join_label(Fail, D, Regs1),
- live_opt(Is, Regs, D, [I|Acc]);
-live_opt([{bs_utf16_size,Fail,Src,Dst}=I|Is], Regs0, D, Acc) ->
- Regs1 = x_live([Src], x_dead([Dst], Regs0)),
- Regs = live_join_label(Fail, D, Regs1),
- live_opt(Is, Regs, D, [I|Acc]);
live_opt([{test,bs_start_match2,Fail,Live,[Src,_],_}=I|Is], _, D, Acc) ->
Regs0 = live_call(Live),
Regs1 = x_live([Src], Regs0),
diff --git a/lib/compiler/src/beam_z.erl b/lib/compiler/src/beam_z.erl
index 7da6391f1f..7af6f1a74c 100644
--- a/lib/compiler/src/beam_z.erl
+++ b/lib/compiler/src/beam_z.erl
@@ -44,4 +44,10 @@ undo_rename({bs_put,F,{I,Fl},[Src]}) ->
{I,F,Fl,Src};
undo_rename({bs_put,{f,0},{bs_put_string,_,_}=I,[]}) ->
I;
+undo_rename({bif,bs_add=I,F,[Src1,Src2,{integer,U}],Dst}) ->
+ {I,F,[Src1,Src2,U],Dst};
+undo_rename({bif,bs_utf8_size=I,F,[Src],Dst}) ->
+ {I,F,Src,Dst};
+undo_rename({bif,bs_utf16_size=I,F,[Src],Dst}) ->
+ {I,F,Src,Dst};
undo_rename(I) -> I.