~ubuntu-branches/ubuntu/lucid/erlang/lucid-updates

« back to all changes in this revision

Viewing changes to lib/compiler/src/beam_jump.erl

  • Committer: Elliot Murphy
  • Date: 2009-12-22 02:56:21 UTC
  • mfrom: (3.3.5 sid)
  • Revision ID: elliot@elliotmurphy.com-20091222025621-qv3rja8gbpiabkbe
Tags: 1:13.b.3-dfsg-2ubuntu1
* Merge with Debian testing; remaining Ubuntu changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to. (LP #438365)
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
* Fixed dialyzer(1) manpage which was placed into section 3 and conflicted
  with dialyzer(3erl).
* New upstream release (it adds a new binary package erlang-erl-docgen).
* Refreshed patches, removed most of emacs.patch which is applied upstream.
* Linked run_test binary from erlang-common-test package to /usr/bin.
* Fixed VCS headers in debian/control.
* Moved from prebuilt manpages to generated from sources. This adds
  erlang-manpages binary package and xsltproc build dependency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
98
98
%%%      labels.)
99
99
%%%
100
100
%%% Note: This modules depends on (almost) all branches and jumps only
101
 
%%% going forward, so that we can remove instructions (including defintion
 
101
%%% going forward, so that we can remove instructions (including definition
102
102
%%% of labels) after any label that has not been referenced by the code
103
103
%%% preceeding the labels. Regarding the few instructions that have backward
104
104
%%% references to labels, we assume that they only transfer control back
105
 
%%% to an instruction that has already been executed. That is,
106
 
%%% code such as
 
105
%%% to an instruction that has already been executed. That is, code such as
107
106
%%%
108
107
%%%         jump L_entry
109
108
%%%
117
116
%%%           .
118
117
%%%         jump L_again;
119
118
%%%           
120
 
%%% is NOT allowed (and such code is never generated by 
121
 
%%% the code generator).
 
119
%%% is NOT allowed (and such code is never generated by the code generator).
122
120
%%%
123
121
%%% Terminology note: The optimisation done here is called unreachable-code
124
 
%%% elimination, NOT dead-code elimination.  Dead code elimination
125
 
%%% means the removal of instructions that are executed, but have no visible
126
 
%%% effect on the program state.
 
122
%%% removal, NOT dead-code elimination.  Dead code elimination means the
 
123
%%% removal of instructions that are executed, but have no visible effect
 
124
%%% on the program state.
127
125
%%% 
128
126
 
129
 
-import(lists, [reverse/1,reverse/2,foldl/3,any/2,dropwhile/2]).
 
127
-import(lists, [reverse/1,reverse/2,foldl/3,dropwhile/2]).
130
128
 
131
129
module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
132
130
    Fs = [function(F) || F <- Fs0],
375
373
%%  referenced label, then call opt/3 to optimize the rest
376
374
%%  of the instruction sequence.
377
375
%%
378
 
skip_unreachable([{label,L}|Is], [{jump,{f,L}}|Acc], St) ->
379
 
    opt([{label,L}|Is], Acc, St);
 
376
skip_unreachable([{label,L}|_Is]=Is0, [{jump,{f,L}}|Acc], St) ->
 
377
    opt(Is0, Acc, St);
380
378
skip_unreachable([{label,L}|Is]=Is0, Acc, St) ->
381
379
    case is_label_used(L, St) of
382
380
        true  -> opt(Is0, Acc, St);
399
397
is_label_used(L, St) ->
400
398
    gb_sets:is_member(L, St#st.labels).
401
399
 
402
 
%% is_unreachable_after(Instruction) -> true|false
 
400
%% is_unreachable_after(Instruction) -> boolean()
403
401
%%  Test whether the code after Instruction is unreachable.
404
402
 
405
403
is_unreachable_after({func_info,_M,_F,_A}) -> true;
416
414
is_unreachable_after({wait,_}) -> true;
417
415
is_unreachable_after(I) -> is_exit_instruction(I).
418
416
 
419
 
%% is_exit_instruction(Instruction) -> true|false
 
417
%% is_exit_instruction(Instruction) -> boolean()
420
418
%%  Test whether the instruction Instruction always
421
419
%%  causes an exit/failure.
422
420
 
432
430
is_exit_instruction({badmatch,_}) -> true;
433
431
is_exit_instruction(_) -> false.
434
432
 
435
 
%% is_label_used_in(LabelNumber, [Instruction]) -> true|false
 
433
%% is_label_used_in(LabelNumber, [Instruction]) -> boolean()
436
434
%%  Check whether the label is used in the instruction sequence
437
435
%%  (including inside blocks).
438
436
 
440
438
    is_label_used_in_1(Is, Lbl, gb_sets:empty()).
441
439
 
442
440
is_label_used_in_1([{block,Block}|Is], Lbl, Empty) ->
443
 
    case any(fun(I) -> is_label_used_in_2(I, Lbl) end, Block) of
444
 
        true -> true;
445
 
        false -> is_label_used_in_1(Is, Lbl, Empty)
446
 
    end;
 
441
    lists:any(fun(I) -> is_label_used_in_2(I, Lbl) end, Block)
 
442
        orelse is_label_used_in_1(Is, Lbl, Empty);
447
443
is_label_used_in_1([I|Is], Lbl, Empty) ->
448
444
    Used = ulbl(I, Empty),
449
 
    case gb_sets:is_member(Lbl, Used) of
450
 
        false ->
451
 
            is_label_used_in_1(Is, Lbl, Empty);
452
 
        true ->
453
 
            true
454
 
    end;
 
445
    gb_sets:is_member(Lbl, Used) orelse is_label_used_in_1(Is, Lbl, Empty);
455
446
is_label_used_in_1([], _, _) -> false.
456
447
 
457
448
is_label_used_in_2({set,_,_,Info}, Lbl) ->