4 @EXPORT_OK = qw(find_leaders);
6 use B
qw(peekop walkoptree walkoptree_exec
7 main_root main_start svref_2object
8 OPf_SPECIAL OPf_STACKED );
19 $bblock->{$$op} = $op;
24 foreach (keys %$bblock){
25 my $leader=$$bblock{$_};
26 delete $$bblock{$_} if( $leader == 0);
30 my ($root, $start) = @_;
32 mark_leader
($start) if ( ref $start ne "B::NULL" );
33 walkoptree
($root, "mark_if_leader") if ((ref $root) ne "B::NULL") ;
40 my ($root, $start) = @_;
41 my ($op, $lastop, $leader, $bb);
44 walkoptree
($root, "mark_if_leader");
45 my @leaders = values %$bblock;
46 while ($leader = shift @leaders) {
49 while ($$op && !exists($bblock->{$$op})) {
50 $bblock->{$$op} = $leader;
54 push(@bblock_ends, [$leader, $lastop]);
56 foreach $bb (@bblock_ends) {
57 ($leader, $lastop) = @
$bb;
58 printf "%s .. %s\n", peekop
($leader), peekop
($lastop);
59 for ($op = $leader; $$op != $$lastop; $op = $op->next) {
60 printf " %s\n", peekop
($op);
62 printf " %s\n", peekop
($lastop);
65 walkoptree_exec
($start, "terse");
68 sub walk_bblocks_obj
{
70 my $cv = svref_2object
($cvref);
71 walk_bblocks
($cv->ROOT, $cv->START);
74 sub B
::OP
::mark_if_leader
{}
76 sub B
::COP
::mark_if_leader
{
83 sub B
::LOOP
::mark_if_leader
{
85 mark_leader
($op->next);
86 mark_leader
($op->nextop);
87 mark_leader
($op->redoop);
88 mark_leader
($op->lastop->next);
91 sub B
::LOGOP
::mark_if_leader
{
93 my $opname = $op->name;
94 mark_leader
($op->next);
95 if ($opname eq "entertry") {
96 mark_leader
($op->other->next);
98 mark_leader
($op->other);
102 sub B
::LISTOP
::mark_if_leader
{
104 my $first=$op->first;
105 $first=$first->next while ($first->name eq "null");
106 mark_leader
($op->first) unless (exists( $bblock->{$$first}));
107 mark_leader
($op->next);
108 if ($op->name eq "sort" and $op->flags & OPf_SPECIAL
109 and $op->flags & OPf_STACKED
){
110 my $root=$op->first->sibling->first;
111 my $leader=$root->first;
112 $bblock->{$$leader} = 0;
116 sub B
::PMOP
::mark_if_leader
{
118 if ($op->name ne "pushre") {
119 my $replroot = $op->pmreplroot;
121 mark_leader
($replroot);
122 mark_leader
($op->next);
123 mark_leader
($op->pmreplstart);
136 foreach $objname (@options) {
137 $objname = "main::$objname" unless $objname =~ /::/;
138 eval "walk_bblocks_obj(\\&$objname)";
139 die "walk_bblocks_obj(\\&$objname) failed: $@" if $@
;
143 return sub { walk_bblocks
(main_root
, main_start
) };
147 # Basic block leaders:
148 # Any COP (pp_nextstate) with a non-NULL label
149 # [The op after a pp_enter] Omit
150 # [The op after a pp_entersub. Don't count this one.]
151 # The ops pointed at by nextop, redoop and lastop->op_next of a LOOP
152 # The ops pointed at by op_next and op_other of a LOGOP, except
153 # for pp_entertry which has op_next and op_other->op_next
154 # The op pointed at by op_pmreplstart of a PMOP
155 # The op pointed at by op_other->op_pmreplstart of pp_substcont?
156 # [The op after a pp_return] Omit
164 B::Bblock - Walk basic blocks
168 perl -MO=Bblock[,OPTIONS] foo.pl
172 This module is used by the B::CC back end. It walks "basic blocks".
173 A basic block is a series of operations which is known to execute from
174 start to finish, with no possiblity of branching or halting.
178 Malcolm Beattie, C<mbeattie@sable.ox.ac.uk>