4
%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
4
%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
6
6
%% The contents of this file are subject to the Erlang Public License,
7
7
%% Version 1.1, (the "License"); you may not use this file except in
8
8
%% compliance with the License. You should have received a copy of the
9
9
%% Erlang Public License along with this software. If not, it can be
10
10
%% retrieved online at http://www.erlang.org/.
12
12
%% Software distributed under the License is distributed on an "AS IS"
13
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
%% the License for the specific language governing rights and limitations
15
15
%% under the License.
281
281
forward([I|Is], D, Lc, Acc);
282
282
forward([{test,is_nil,_,[Dst]}=I,{move,nil,Dst}|Is], D, Lc, Acc) ->
283
283
forward([I|Is], D, Lc, Acc);
284
forward([{test,is_eq_exact,_,[_,{atom,_}]}=I|Is], D, Lc, [{label,_}|_]=Acc) ->
284
forward([{test,is_eq_exact,_,_}=I|Is], D, Lc, Acc) ->
286
286
[{label,_}|_] -> forward(Is, D, Lc, [I|Acc]);
287
287
_ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc])
289
forward([{test,is_ne_exact,_,[_,{atom,_}]}=I|Is], D, Lc, [{label,_}|_]=Acc) ->
289
forward([{test,is_ne_exact,_,_}=I|Is], D, Lc, Acc) ->
291
291
[{label,_}|_] -> forward(Is, D, Lc, [I|Acc]);
292
292
_ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc])
371
371
To = shortcut_bs_start_match(To0, Src, D),
372
372
I = {test,bs_start_match2,{f,To},Live,Info,Dst},
373
373
backward(Is, D, [I|Acc]);
374
backward([{test,is_eq_exact=Op,{f,To0},[Reg,{atom,Val}]=Ops}|Is], D, Acc) ->
374
backward([{test,is_eq_exact,{f,To0},[Reg,{atom,Val}]=Ops}|Is], D, Acc) ->
375
375
To1 = shortcut_bs_test(To0, Is, D),
376
376
To = shortcut_fail_label(To1, Reg, Val, D),
377
I = {test,Op,{f,To},Ops},
377
I = combine_eqs(To, Ops, D, Acc),
378
378
backward(Is, D, [I|Acc]);
379
379
backward([{test,Op,{f,To0},Ops0}|Is], D, Acc) ->
380
380
To1 = shortcut_bs_test(To0, Is, D),
397
I = {test,Op,{f,To},Ops0},
398
is_eq_exact -> combine_eqs(To, Ops0, D, Acc);
399
_ -> {test,Op,{f,To},Ops0}
398
401
backward(Is, D, [I|Acc]);
399
402
backward([{test,Op,{f,To0},Live,Ops0,Dst}|Is], D, Acc) ->
400
403
To1 = shortcut_bs_test(To0, Is, D),
520
523
not_possible() -> throw(not_possible).
525
%% combine_eqs(To, Operands, Acc) -> Instruction.
526
%% Combine two is_eq_exact instructions or (an is_eq_exact
527
%% instruction and a select_val instruction) to a select_val
528
%% instruction if possible.
532
%% is_eq_exact F1 Reg Lit1 select_val Reg F2 [ Lit1 L1
537
%% F1: is_eq_exact F2 Reg Lit2 F1: is_eq_exact F2 Reg Lit2
540
combine_eqs(To, [Reg,{Type,_}=Lit1]=Ops, D, [{label,L1}|_])
541
when Type =:= atom; Type =:= integer ->
542
case beam_utils:code_at(To, D) of
543
[{test,is_eq_exact,{f,F2},[Reg,{Type,_}=Lit2]},
544
{label,L2}|_] when Lit1 =/= Lit2 ->
545
{select_val,Reg,{f,F2},{list,[Lit1,{f,L1},Lit2,{f,L2}]}};
546
[{select_val,Reg,{f,F2},{list,[{Type,_}|_]=List0}}|_] ->
547
List = remove_from_list(Lit1, List0),
548
{select_val,Reg,{f,F2},{list,[Lit1,{f,L1}|List]}};
550
{test,is_eq_exact,{f,To},Ops}
552
combine_eqs(To, Ops, _D, _Acc) ->
553
{test,is_eq_exact,{f,To},Ops}.
555
remove_from_list(Lit, [Lit,{f,_}|T]) ->
557
remove_from_list(Lit, [Val,{f,_}=Fail|T]) ->
558
[Val,Fail|remove_from_list(Lit, T)];
559
remove_from_list(_, []) -> [].
523
561
%% shortcut_bs_test(TargetLabel, [Instruction], D) -> TargetLabel'
524
562
%% Try to shortcut the failure label for a bit syntax matching.