diff options
author | Björn Gustavsson <[email protected]> | 2012-08-31 16:06:37 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2012-10-09 15:24:41 +0200 |
commit | b44f86b779f0b8579e4df2a98930ac3150c6c07c (patch) | |
tree | ba10bf906e4432f12a9a7aa6d6ee1af7735dfacf | |
parent | 105e056cddaf765952d58813e2ec5c9bdfd4403c (diff) | |
download | otp-b44f86b779f0b8579e4df2a98930ac3150c6c07c.tar.gz otp-b44f86b779f0b8579e4df2a98930ac3150c6c07c.tar.bz2 otp-b44f86b779f0b8579e4df2a98930ac3150c6c07c.zip |
Rewrite bs_put* instructions to a generic bs_put instruction
Seven bs_put_* instructions can be combined into one generic bs_put
instruction to avoid some code bloat. That will also improve some
optimizations (such as beam_trim) that did not handle all bs_put*
variants.
-rw-r--r-- | lib/compiler/src/beam_a.erl | 21 | ||||
-rw-r--r-- | lib/compiler/src/beam_block.erl | 40 | ||||
-rw-r--r-- | lib/compiler/src/beam_bsm.erl | 21 | ||||
-rw-r--r-- | lib/compiler/src/beam_clean.erl | 14 | ||||
-rw-r--r-- | lib/compiler/src/beam_flatten.erl | 8 | ||||
-rw-r--r-- | lib/compiler/src/beam_jump.erl | 12 | ||||
-rw-r--r-- | lib/compiler/src/beam_trim.erl | 20 | ||||
-rw-r--r-- | lib/compiler/src/beam_utils.erl | 42 | ||||
-rw-r--r-- | lib/compiler/src/beam_z.erl | 11 |
9 files changed, 66 insertions, 123 deletions
diff --git a/lib/compiler/src/beam_a.erl b/lib/compiler/src/beam_a.erl index 496b0aba41..4a8ba9743a 100644 --- a/lib/compiler/src/beam_a.erl +++ b/lib/compiler/src/beam_a.erl @@ -30,9 +30,12 @@ module({Mod,Exp,Attr,Fs0,Lc}, _Opt) -> function({function,Name,Arity,CLabel,Is0}) -> try + %% Rename certain operations to simplify the optimization passes. + Is1 = [rename_instr(I) || I <- Is0], + %% Remove unusued labels for cleanliness and to help %% optimization passes and HiPE. - Is = beam_jump:remove_unused_labels(Is0), + Is = beam_jump:remove_unused_labels(Is1), {function,Name,Arity,CLabel,Is} catch Class:Error -> @@ -40,3 +43,19 @@ function({function,Name,Arity,CLabel,Is0}) -> io:fwrite("Function: ~w/~w\n", [Name,Arity]), erlang:raise(Class, Error, Stack) end. + +rename_instr({bs_put_binary=I,F,Sz,U,Fl,Src}) -> + {bs_put,F,{I,U,Fl},[Sz,Src]}; +rename_instr({bs_put_float=I,F,Sz,U,Fl,Src}) -> + {bs_put,F,{I,U,Fl},[Sz,Src]}; +rename_instr({bs_put_integer=I,F,Sz,U,Fl,Src}) -> + {bs_put,F,{I,U,Fl},[Sz,Src]}; +rename_instr({bs_put_utf8=I,F,Fl,Src}) -> + {bs_put,F,{I,Fl},[Src]}; +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(I) -> I. diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl index f6ebc646bb..a97cf8517f 100644 --- a/lib/compiler/src/beam_block.erl +++ b/lib/compiler/src/beam_block.erl @@ -420,8 +420,8 @@ inverse_comp_op(_) -> none. %%% Evaluation of constant bit fields. %%% -is_bs_put({bs_put_integer,_,_,_,_,_}) -> true; -is_bs_put({bs_put_float,_,_,_,_,_}) -> true; +is_bs_put({bs_put,_,{bs_put_integer,_,_},_}) -> true; +is_bs_put({bs_put,_,{bs_put_float,_,_},_}) -> true; is_bs_put(_) -> false. collect_bs_puts(Is) -> @@ -436,20 +436,24 @@ collect_bs_puts_1([I|Is]=Is0, Acc) -> opt_bs_puts(Is) -> opt_bs_1(Is, []). -opt_bs_1([{bs_put_float,Fail,{integer,Sz},1,Flags0,Src}=I0|Is], Acc) -> +opt_bs_1([{bs_put,Fail, + {bs_put_float,1,Flags0},[{integer,Sz},Src]}=I0|Is], Acc) -> try eval_put_float(Src, Sz, Flags0) of <<Int:Sz>> -> Flags = force_big(Flags0), - I = {bs_put_integer,Fail,{integer,Sz},1,Flags,{integer,Int}}, + I = {bs_put,Fail,{bs_put_integer,1,Flags}, + [{integer,Sz},{integer,Int}]}, opt_bs_1([I|Is], Acc) catch error:_ -> opt_bs_1(Is, [I0|Acc]) end; -opt_bs_1([{bs_put_integer,_,{integer,8},1,_,{integer,_}}|_]=IsAll, Acc0) -> +opt_bs_1([{bs_put,_,{bs_put_integer,1,_},[{integer,8},{integer,_}]}|_]=IsAll, + Acc0) -> {Is,Acc} = bs_collect_string(IsAll, Acc0), opt_bs_1(Is, Acc); -opt_bs_1([{bs_put_integer,Fail,{integer,Sz},1,F,{integer,N}}=I|Is0], Acc) when Sz > 8 -> +opt_bs_1([{bs_put,Fail,{bs_put_integer,1,F},[{integer,Sz},{integer,N}]}=I|Is0], + Acc) when Sz > 8 -> case field_endian(F) of big -> %% We can do this optimization for any field size without risk @@ -463,14 +467,14 @@ opt_bs_1([{bs_put_integer,Fail,{integer,Sz},1,F,{integer,N}}=I|Is0], Acc) when S %% an explosion in code size. <<Int:Sz>> = <<N:Sz/little>>, Flags = force_big(F), - Is = [{bs_put_integer,Fail,{integer,Sz},1, - Flags,{integer,Int}}|Is0], + Is = [{bs_put,Fail,{bs_put_integer,1,Flags}, + [{integer,Sz},{integer,Int}]}|Is0], opt_bs_1(Is, Acc); _ -> %native or too wide little field opt_bs_1(Is0, [I|Acc]) end; -opt_bs_1([{Op,Fail,{integer,Sz},U,F,Src}|Is], Acc) when U > 1 -> - opt_bs_1([{Op,Fail,{integer,U*Sz},1,F,Src}|Is], Acc); +opt_bs_1([{bs_put,Fail,{Op,U,F},[{integer,Sz},Src]}|Is], Acc) when U > 1 -> + opt_bs_1([{bs_put,Fail,{Op,1,F},[{integer,U*Sz},Src]}|Is], Acc); opt_bs_1([I|Is], Acc) -> opt_bs_1(Is, [I|Acc]); opt_bs_1([], Acc) -> reverse(Acc). @@ -486,17 +490,17 @@ eval_put_float(Src, Sz, Flags) when Sz =< 256 -> %Only evaluate if Sz is reasona value({integer,I}) -> I; value({float,F}) -> F. -bs_collect_string(Is, [{bs_put_string,Len,{string,Str}}|Acc]) -> +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, Acc) -> bs_coll_str_1(Is, 0, [], Acc). -bs_coll_str_1([{bs_put_integer,_,{integer,Sz},U,_,{integer,V}}|Is], +bs_coll_str_1([{bs_put,_,{bs_put_integer,U,_},[{integer,Sz},{integer,V}]}|Is], Len, 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_string,Len,{string,reverse(StrAcc)}}|IsAcc]}. + {Is,[{bs_put,{f,0},{bs_put_string,Len,{string,reverse(StrAcc)}},[]}|IsAcc]}. field_endian({field_flags,F}) -> field_endian_1(F). @@ -528,15 +532,17 @@ bs_split_int(N, Sz, Fail, Acc) -> bs_split_int_1(N, FirstByteSz, Sz, Fail, Acc). bs_split_int_1(-1, _, Sz, Fail, Acc) when Sz > 64 -> - I = {bs_put_integer,Fail,{integer,Sz},1,{field_flags,[big]},{integer,-1}}, + I = {bs_put,Fail,{bs_put_integer,1,{field_flags,[big]}}, + [{integer,Sz},{integer,-1}]}, [I|Acc]; bs_split_int_1(0, _, Sz, Fail, Acc) when Sz > 64 -> - I = {bs_put_integer,Fail,{integer,Sz},1,{field_flags,[big]},{integer,0}}, + I = {bs_put,Fail,{bs_put_integer,1,{field_flags,[big]}}, + [{integer,Sz},{integer,0}]}, [I|Acc]; bs_split_int_1(N, ByteSz, Sz, Fail, Acc) when Sz > 0 -> Mask = (1 bsl ByteSz) - 1, - I = {bs_put_integer,Fail,{integer,ByteSz},1, - {field_flags,[big]},{integer,N band Mask}}, + I = {bs_put,Fail,{bs_put_integer,1,{field_flags,[big]}}, + [{integer,ByteSz},{integer,N band Mask}]}, bs_split_int_1(N bsr ByteSz, 8, Sz-ByteSz, Fail, [I|Acc]); bs_split_int_1(_, _, _, _, Acc) -> Acc. diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl index 1217f7f777..aaf48d4587 100644 --- a/lib/compiler/src/beam_bsm.erl +++ b/lib/compiler/src/beam_bsm.erl @@ -308,16 +308,8 @@ btb_reaches_match_2([{bs_append,{f,0},_,_,_,_,Src,_,Dst}=I|Is], Regs, D) -> btb_reaches_match_2([{bs_private_append,{f,0},_,_,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_put_integer,{f,0},_,_,_,Src}=I|Is], Regs, D) -> - btb_ensure_not_used([Src], I, Regs), - btb_reaches_match_1(Is, Regs, D); -btb_reaches_match_2([{bs_put_float,{f,0},_,_,_,Src}=I|Is], Regs, D) -> - btb_ensure_not_used([Src], I, Regs), - btb_reaches_match_1(Is, Regs, D); -btb_reaches_match_2([{bs_put_binary,{f,0},_,_,_,Src}=I|Is], Regs, D) -> - btb_ensure_not_used([Src], I, Regs), - btb_reaches_match_1(Is, Regs, D); -btb_reaches_match_2([{bs_put_string,_,_}|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), @@ -325,15 +317,6 @@ btb_reaches_match_2([{bs_utf8_size,_,Src,Dst}=I|Is], 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_put_utf8,_,_,Src}=I|Is], Regs, D) -> - btb_ensure_not_used([Src], I, Regs), - btb_reaches_match_1(Is, Regs, D); -btb_reaches_match_2([{bs_put_utf16,_,_,Src}=I|Is], Regs, D) -> - btb_ensure_not_used([Src], I, Regs), - btb_reaches_match_1(Is, Regs, D); -btb_reaches_match_2([{bs_put_utf32,_,_,Src}=I|Is], Regs, D) -> - btb_ensure_not_used([Src], I, Regs), - btb_reaches_match_1(Is, 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 a7994ab3b3..fea653e1e7 100644 --- a/lib/compiler/src/beam_clean.erl +++ b/lib/compiler/src/beam_clean.erl @@ -246,18 +246,8 @@ replace([{bs_init2,{f,Lbl},Sz,Words,R,F,Dst}|Is], Acc, D) when Lbl =/= 0 -> replace(Is, [{bs_init2,{f,label(Lbl, D)},Sz,Words,R,F,Dst}|Acc], D); 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_integer,{f,Lbl},Bits,Unit,Fl,Val}|Is], Acc, D) when Lbl =/= 0 -> - replace(Is, [{bs_put_integer,{f,label(Lbl, D)},Bits,Unit,Fl,Val}|Acc], D); -replace([{bs_put_utf8=I,{f,Lbl},Fl,Val}|Is], Acc, D) when Lbl =/= 0 -> - replace(Is, [{I,{f,label(Lbl, D)},Fl,Val}|Acc], D); -replace([{bs_put_utf16=I,{f,Lbl},Fl,Val}|Is], Acc, D) when Lbl =/= 0 -> - replace(Is, [{I,{f,label(Lbl, D)},Fl,Val}|Acc], D); -replace([{bs_put_utf32=I,{f,Lbl},Fl,Val}|Is], Acc, D) when Lbl =/= 0 -> - replace(Is, [{I,{f,label(Lbl, D)},Fl,Val}|Acc], D); -replace([{bs_put_binary,{f,Lbl},Bits,Unit,Fl,Val}|Is], Acc, D) when Lbl =/= 0 -> - replace(Is, [{bs_put_binary,{f,label(Lbl, D)},Bits,Unit,Fl,Val}|Acc], D); -replace([{bs_put_float,{f,Lbl},Bits,Unit,Fl,Val}|Is], Acc, D) when Lbl =/= 0 -> - replace(Is, [{bs_put_float,{f,label(Lbl, D)},Bits,Unit,Fl,Val}|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 -> diff --git a/lib/compiler/src/beam_flatten.erl b/lib/compiler/src/beam_flatten.erl index 6c7cb849aa..4cca406f45 100644 --- a/lib/compiler/src/beam_flatten.erl +++ b/lib/compiler/src/beam_flatten.erl @@ -113,13 +113,7 @@ insert_alloc_1([I|Is], Alloc, Acc) -> %% as a literal, the bs_init2/6 instruction will not occur %% at the end and therefore it is no need to test for it here.) %% -is_bs_constructor({bs_put_integer,_,_,_,_,_}) -> true; -is_bs_constructor({bs_put_utf8,_,_,_}) -> true; -is_bs_constructor({bs_put_utf16,_,_,_}) -> true; -is_bs_constructor({bs_put_utf32,_,_,_}) -> true; -is_bs_constructor({bs_put_float,_,_,_,_,_}) -> true; -is_bs_constructor({bs_put_binary,_,_,_,_,_}) -> true; -is_bs_constructor({bs_put_string,_,_}) -> true; +is_bs_constructor({bs_put,_,_,_}) -> true; is_bs_constructor(_) -> false. %% opt(Is0) -> Is diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index 2b68b3ed20..e87085134b 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -539,17 +539,7 @@ ulbl({bs_init2,Lbl,_,_,_,_,_}, Used) -> mark_used(Lbl, Used); ulbl({bs_init_bits,Lbl,_,_,_,_,_}, Used) -> mark_used(Lbl, Used); -ulbl({bs_put_integer,Lbl,_Bits,_Unit,_Fl,_Val}, Used) -> - mark_used(Lbl, Used); -ulbl({bs_put_float,Lbl,_Bits,_Unit,_Fl,_Val}, Used) -> - mark_used(Lbl, Used); -ulbl({bs_put_binary,Lbl,_Bits,_Unit,_Fl,_Val}, Used) -> - mark_used(Lbl, Used); -ulbl({bs_put_utf8,Lbl,_Fl,_Val}, Used) -> - mark_used(Lbl, Used); -ulbl({bs_put_utf16,Lbl,_Fl,_Val}, Used) -> - mark_used(Lbl, Used); -ulbl({bs_put_utf32,Lbl,_Fl,_Val}, Used) -> +ulbl({bs_put,Lbl,_,_}, Used) -> mark_used(Lbl, Used); ulbl({bs_add,Lbl,_,_}, Used) -> mark_used(Lbl, Used); diff --git a/lib/compiler/src/beam_trim.erl b/lib/compiler/src/beam_trim.erl index 5f4fa3b1f8..5856f0d3b5 100644 --- a/lib/compiler/src/beam_trim.erl +++ b/lib/compiler/src/beam_trim.erl @@ -189,16 +189,8 @@ remap([{bs_init2,Fail,Src,Live,U,Flags,D}|Is], Map, Acc) -> remap([{bs_init_bits,Fail,Src,Live,U,Flags,D}|Is], Map, Acc) -> I = {bs_init_bits,Fail,Map(Src),Live,U,Flags,Map(D)}, remap(Is, Map, [I|Acc]); -remap([{bs_put_binary=Op,Fail,Src,U,Flags,D}|Is], Map, Acc) -> - I = {Op,Fail,Map(Src),U,Flags,Map(D)}, - remap(Is, Map, [I|Acc]); -remap([{bs_put_integer=Op,Fail,Src,U,Flags,D}|Is], Map, Acc) -> - I = {Op,Fail,Map(Src),U,Flags,Map(D)}, - remap(Is, Map, [I|Acc]); -remap([{bs_put_float=Op,Fail,Src,U,Flags,D}|Is], Map, Acc) -> - I = {Op,Fail,Map(Src),U,Flags,Map(D)}, - remap(Is, Map, [I|Acc]); -remap([{bs_put_string,_,_}=I|Is], Map, Acc) -> +remap([{bs_put=Op,Fail,Info,Ss}|Is], Map, Acc) -> + I = {Op,Fail,Info,[Map(S) || S <- Ss]}, remap(Is, Map, [I|Acc]); remap([{kill,Y}|T], Map, Acc) -> remap(T, Map, [{kill,Map(Y)}|Acc]); @@ -307,14 +299,8 @@ frame_size([{bs_init2,{f,L},_,_,_,_,_}|Is], Safe) -> frame_size_branch(L, Is, Safe); frame_size([{bs_init_bits,{f,L},_,_,_,_,_}|Is], Safe) -> frame_size_branch(L, Is, Safe); -frame_size([{bs_put_binary,{f,L},_,_,_,_}|Is], Safe) -> +frame_size([{bs_put,{f,L},_,_}|Is], Safe) -> frame_size_branch(L, Is, Safe); -frame_size([{bs_put_integer,{f,L},_,_,_,_}|Is], Safe) -> - frame_size_branch(L, Is, Safe); -frame_size([{bs_put_float,{f,L},_,_,_,_}|Is], Safe) -> - frame_size_branch(L, Is, Safe); -frame_size([{bs_put_string,_,_}|Is], Safe) -> - frame_size(Is, Safe); frame_size([{kill,_}|Is], Safe) -> frame_size(Is, Safe); frame_size([send|Is], Safe) -> diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index 7e4a476dab..400979bc19 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -330,8 +330,6 @@ check_liveness(R, [{bs_init_bits,_,_,_,_,_,Dst}|Is], St) -> R =:= Dst -> {killed,St}; true -> check_liveness(R, Is, St) end; -check_liveness(R, [{bs_put_string,_,_}|Is], St) -> - check_liveness(R, Is, St); check_liveness(R, [{deallocate,_}|Is], St) -> case R of {y,_} -> {killed,St}; @@ -435,18 +433,8 @@ check_liveness(R, [{bs_add,{f,0},Ss,D}|Is], St) -> false when R =:= D -> {killed,St}; false -> check_liveness(R, Is, St) end; -check_liveness(R, [{bs_put_binary,{f,0},Sz,_,_,Src}|Is], St) -> - case member(R, [Sz,Src]) of - true -> {used,St}; - false -> check_liveness(R, Is, St) - end; -check_liveness(R, [{bs_put_integer,{f,0},Sz,_,_,Src}|Is], St) -> - case member(R, [Sz,Src]) of - true -> {used,St}; - false -> check_liveness(R, Is, St) - end; -check_liveness(R, [{bs_put_float,{f,0},Sz,_,_,Src}|Is], St) -> - case member(R, [Sz,Src]) of +check_liveness(R, [{bs_put,{f,0},_,Ss}|Is], St) -> + case member(R, Ss) of true -> {used,St}; false -> check_liveness(R, Is, St) end; @@ -721,28 +709,8 @@ live_opt([{bs_private_append,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_put_binary,Fail,Src1,_,_,Src2}=I|Is], Regs0, D, Acc) -> - Regs1 = x_live([Src1,Src2], Regs0), - Regs = live_join_label(Fail, D, Regs1), - live_opt(Is, Regs, D, [I|Acc]); -live_opt([{bs_put_float,Fail,Src1,_,_,Src2}=I|Is], Regs0, D, Acc) -> - Regs1 = x_live([Src1,Src2], Regs0), - Regs = live_join_label(Fail, D, Regs1), - live_opt(Is, Regs, D, [I|Acc]); -live_opt([{bs_put_integer,Fail,Src1,_,_,Src2}=I|Is], Regs0, D, Acc) -> - Regs1 = x_live([Src1,Src2], Regs0), - Regs = live_join_label(Fail, D, Regs1), - live_opt(Is, Regs, D, [I|Acc]); -live_opt([{bs_put_utf8,Fail,_,Src}=I|Is], Regs0, D, Acc) -> - Regs1 = x_live([Src], Regs0), - Regs = live_join_label(Fail, D, Regs1), - live_opt(Is, Regs, D, [I|Acc]); -live_opt([{bs_put_utf16,Fail,_,Src}=I|Is], Regs0, D, Acc) -> - Regs1 = x_live([Src], Regs0), - Regs = live_join_label(Fail, D, Regs1), - live_opt(Is, Regs, D, [I|Acc]); -live_opt([{bs_put_utf32,Fail,_,Src}=I|Is], Regs0, D, Acc) -> - Regs1 = x_live([Src], Regs0), +live_opt([{bs_put,Fail,_,Ss}=I|Is], Regs0, D, Acc) -> + Regs1 = x_live(Ss, Regs0), Regs = live_join_label(Fail, D, Regs1), live_opt(Is, Regs, D, [I|Acc]); live_opt([{bs_restore2,Src,_}=I|Is], Regs0, D, Acc) -> @@ -847,8 +815,6 @@ live_opt([timeout=I|Is], _, D, Acc) -> live_opt(Is, 0, D, [I|Acc]); %% Transparent instructions - they neither use nor modify x registers. -live_opt([{bs_put_string,_,_}=I|Is], Regs, D, Acc) -> - live_opt(Is, Regs, D, [I|Acc]); live_opt([{deallocate,_}=I|Is], Regs, D, Acc) -> live_opt(Is, Regs, D, [I|Acc]); live_opt([{kill,_}=I|Is], Regs, D, Acc) -> diff --git a/lib/compiler/src/beam_z.erl b/lib/compiler/src/beam_z.erl index 706500e01c..7da6391f1f 100644 --- a/lib/compiler/src/beam_z.erl +++ b/lib/compiler/src/beam_z.erl @@ -27,8 +27,9 @@ module({Mod,Exp,Attr,Fs0,Lc}, _Opt) -> Fs = [function(F) || F <- Fs0], {ok,{Mod,Exp,Attr,Fs,Lc}}. -function({function,Name,Arity,CLabel,Is}) -> +function({function,Name,Arity,CLabel,Is0}) -> try + Is = [undo_rename(I) || I <- Is0], {function,Name,Arity,CLabel,Is} catch Class:Error -> @@ -36,3 +37,11 @@ function({function,Name,Arity,CLabel,Is}) -> io:fwrite("Function: ~w/~w\n", [Name,Arity]), erlang:raise(Class, Error, Stack) end. + +undo_rename({bs_put,F,{I,U,Fl},[Sz,Src]}) -> + {I,F,Sz,U,Fl,Src}; +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(I) -> I. |