4 @EXPORT_OK = qw(find_leaders);
6 use B qw(peekop walkoptree walkoptree_exec
7 main_root main_start svref_2object);
17 $bblock->{$$op} = $op;
22 my ($root, $start) = @_;
25 walkoptree($root, "mark_if_leader");
31 my ($root, $start) = @_;
32 my ($op, $lastop, $leader, $bb);
35 walkoptree($root, "mark_if_leader");
36 my @leaders = values %$bblock;
37 while ($leader = shift @leaders) {
40 while ($$op && !exists($bblock->{$$op})) {
41 $bblock->{$$op} = $leader;
45 push(@bblock_ends, [$leader, $lastop]);
47 foreach $bb (@bblock_ends) {
48 ($leader, $lastop) = @$bb;
49 printf "%s .. %s\n", peekop($leader), peekop($lastop);
50 for ($op = $leader; $$op != $$lastop; $op = $op->next) {
51 printf " %s\n", peekop($op);
53 printf " %s\n", peekop($lastop);
56 walkoptree_exec($start, "terse");
59 sub walk_bblocks_obj {
61 my $cv = svref_2object($cvref);
62 walk_bblocks($cv->ROOT, $cv->START);
65 sub B::OP::mark_if_leader {}
67 sub B::COP::mark_if_leader {
74 sub B::LOOP::mark_if_leader {
76 mark_leader($op->next);
77 mark_leader($op->nextop);
78 mark_leader($op->redoop);
79 mark_leader($op->lastop->next);
82 sub B::LOGOP::mark_if_leader {
84 my $ppaddr = $op->ppaddr;
85 mark_leader($op->next);
86 if ($ppaddr eq "pp_entertry") {
87 mark_leader($op->other->next);
89 mark_leader($op->other);
93 sub B::CONDOP::mark_if_leader {
95 mark_leader($op->next);
96 mark_leader($op->true);
97 mark_leader($op->false);
100 sub B::PMOP::mark_if_leader {
102 if ($op->ppaddr ne "pp_pushre") {
103 my $replroot = $op->pmreplroot;
105 mark_leader($replroot);
106 mark_leader($op->next);
107 mark_leader($op->pmreplstart);
119 foreach $objname (@options) {
120 $objname = "main::$objname" unless $objname =~ /::/;
121 eval "walk_bblocks_obj(\\&$objname)";
122 die "walk_bblocks_obj(\\&$objname) failed: $@" if $@;
126 return sub { walk_bblocks(main_root, main_start) };
130 # Basic block leaders:
131 # Any COP (pp_nextstate) with a non-NULL label
132 # [The op after a pp_enter] Omit
133 # [The op after a pp_entersub. Don't count this one.]
134 # The ops pointed at by nextop, redoop and lastop->op_next of a LOOP
135 # The ops pointed at by op_next and op_other of a LOGOP, except
136 # for pp_entertry which has op_next and op_other->op_next
137 # The ops pointed at by op_true and op_false of a CONDOP
138 # The op pointed at by op_pmreplstart of a PMOP
139 # The op pointed at by op_other->op_pmreplstart of pp_substcont?
140 # [The op after a pp_return] Omit