| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # Maintained now in B::C by Reini Urban | 
| 2 |  |  |  |  |  |  | package B::Bblock; | 
| 3 |  |  |  |  |  |  |  | 
| 4 |  |  |  |  |  |  | our $VERSION = '1.04'; | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 15 |  |  | 15 |  | 684 | use Exporter (); | 
|  | 15 |  |  |  |  | 17 |  | 
|  | 15 |  |  |  |  | 686 |  | 
| 7 |  |  |  |  |  |  | @ISA       = "Exporter"; | 
| 8 |  |  |  |  |  |  | our @EXPORT_OK = qw(find_leaders); | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 15 |  |  |  |  | 940 | use B qw(peekop walkoptree walkoptree_exec | 
| 11 |  |  |  |  |  |  | main_root main_start svref_2object | 
| 12 | 15 |  |  | 15 |  | 58 | OPf_SPECIAL OPf_STACKED ); | 
|  | 15 |  |  |  |  | 17 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 | 15 |  |  | 15 |  | 48 | use strict; | 
|  | 15 |  |  |  |  | 16 |  | 
|  | 15 |  |  |  |  | 12270 |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | my $bblock; | 
| 17 |  |  |  |  |  |  | my @bblock_ends; | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | sub mark_leader { | 
| 20 | 0 |  |  | 0 | 0 |  | my $op = shift; | 
| 21 | 0 | 0 |  |  |  |  | if ($$op) { | 
| 22 | 0 |  |  |  |  |  | $bblock->{$$op} = $op; | 
| 23 |  |  |  |  |  |  | } | 
| 24 |  |  |  |  |  |  | } | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | sub remove_sortblock { | 
| 27 | 0 |  |  | 0 | 0 |  | foreach ( keys %$bblock ) { | 
| 28 | 0 |  |  |  |  |  | my $leader = $$bblock{$_}; | 
| 29 | 0 | 0 |  |  |  |  | delete $$bblock{$_} if ( $leader == 0 ); | 
| 30 |  |  |  |  |  |  | } | 
| 31 |  |  |  |  |  |  | } | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | sub find_leaders { | 
| 34 | 0 |  |  | 0 | 1 |  | my ( $root, $start ) = @_; | 
| 35 | 0 |  |  |  |  |  | $bblock = {}; | 
| 36 | 0 | 0 |  |  |  |  | mark_leader($start) if ( ref $start ne "B::NULL" ); | 
| 37 | 0 | 0 |  |  |  |  | walkoptree( $root, "mark_if_leader" ) if ( ( ref $root ) ne "B::NULL" ); | 
| 38 | 0 |  |  |  |  |  | remove_sortblock(); | 
| 39 | 0 |  |  |  |  |  | return $bblock; | 
| 40 |  |  |  |  |  |  | } | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | # Debugging | 
| 43 |  |  |  |  |  |  | sub walk_bblocks { | 
| 44 | 0 |  |  | 0 | 0 |  | my ( $root, $start ) = @_; | 
| 45 | 0 |  |  |  |  |  | my ( $op, $lastop, $leader, $bb ); | 
| 46 | 0 |  |  |  |  |  | $bblock = {}; | 
| 47 | 0 |  |  |  |  |  | mark_leader($start); | 
| 48 | 0 |  |  |  |  |  | walkoptree( $root, "mark_if_leader" ); | 
| 49 | 0 |  |  |  |  |  | my @leaders = values %$bblock; | 
| 50 | 0 |  |  |  |  |  | while ( $leader = shift @leaders ) { | 
| 51 | 0 |  |  |  |  |  | $lastop = $leader; | 
| 52 | 0 |  |  |  |  |  | $op     = $leader->next; | 
| 53 | 0 |  | 0 |  |  |  | while ( $$op && !exists( $bblock->{$$op} ) ) { | 
| 54 | 0 |  |  |  |  |  | $bblock->{$$op} = $leader; | 
| 55 | 0 |  |  |  |  |  | $lastop         = $op; | 
| 56 | 0 |  |  |  |  |  | $op             = $op->next; | 
| 57 |  |  |  |  |  |  | } | 
| 58 | 0 |  |  |  |  |  | push( @bblock_ends, [ $leader, $lastop ] ); | 
| 59 |  |  |  |  |  |  | } | 
| 60 | 0 |  |  |  |  |  | foreach $bb (@bblock_ends) { | 
| 61 | 0 |  |  |  |  |  | ( $leader, $lastop ) = @$bb; | 
| 62 | 0 |  |  |  |  |  | printf "%s .. %s\n", peekop($leader), peekop($lastop); | 
| 63 | 0 |  |  |  |  |  | for ( $op = $leader ; $$op != $$lastop ; $op = $op->next ) { | 
| 64 | 0 |  |  |  |  |  | printf "    %s\n", peekop($op); | 
| 65 |  |  |  |  |  |  | } | 
| 66 | 0 |  |  |  |  |  | printf "    %s\n", peekop($lastop); | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  | } | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | sub walk_bblocks_obj { | 
| 71 | 0 |  |  | 0 | 0 |  | my $cvref = shift; | 
| 72 | 0 |  |  |  |  |  | my $cv    = svref_2object($cvref); | 
| 73 | 0 |  |  |  |  |  | walk_bblocks( $cv->ROOT, $cv->START ); | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  | 0 |  |  | sub B::OP::mark_if_leader { } | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | sub B::COP::mark_if_leader { | 
| 79 | 0 |  |  | 0 |  |  | my $op = shift; | 
| 80 | 0 | 0 |  |  |  |  | if ( $op->label ) { | 
| 81 | 0 |  |  |  |  |  | mark_leader($op); | 
| 82 |  |  |  |  |  |  | } | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | sub B::LOOP::mark_if_leader { | 
| 86 | 0 |  |  | 0 |  |  | my $op = shift; | 
| 87 | 0 |  |  |  |  |  | mark_leader( $op->next ); | 
| 88 | 0 |  |  |  |  |  | mark_leader( $op->nextop ); | 
| 89 | 0 |  |  |  |  |  | mark_leader( $op->redoop ); | 
| 90 | 0 |  |  |  |  |  | mark_leader( $op->lastop->next ); | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | sub B::LOGOP::mark_if_leader { | 
| 94 | 0 |  |  | 0 |  |  | my $op     = shift; | 
| 95 | 0 |  |  |  |  |  | my $opname = $op->name; | 
| 96 | 0 |  |  |  |  |  | mark_leader( $op->next ); | 
| 97 | 0 | 0 |  |  |  |  | if ( $opname eq "entertry" ) { | 
| 98 | 0 |  |  |  |  |  | mark_leader( $op->other->next ); | 
| 99 |  |  |  |  |  |  | } | 
| 100 |  |  |  |  |  |  | else { | 
| 101 | 0 |  |  |  |  |  | mark_leader( $op->other ); | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | sub B::LISTOP::mark_if_leader { | 
| 106 | 0 |  |  | 0 |  |  | my $op    = shift; | 
| 107 | 0 |  |  |  |  |  | my $first = $op->first; | 
| 108 | 0 |  |  |  |  |  | $first = $first->next while ( $first->name eq "null" ); | 
| 109 | 0 | 0 |  |  |  |  | mark_leader( $op->first ) unless ( exists( $bblock->{$$first} ) ); | 
| 110 | 0 |  |  |  |  |  | mark_leader( $op->next ); | 
| 111 | 0 | 0 | 0 |  |  |  | if (  $op->name eq "sort" | 
|  |  |  | 0 |  |  |  |  | 
| 112 |  |  |  |  |  |  | and $op->flags & OPf_SPECIAL | 
| 113 |  |  |  |  |  |  | and $op->flags & OPf_STACKED ) | 
| 114 |  |  |  |  |  |  | { | 
| 115 | 0 |  |  |  |  |  | my $root   = $op->first->sibling->first; | 
| 116 | 0 |  |  |  |  |  | my $leader = $root->first; | 
| 117 | 0 |  |  |  |  |  | $bblock->{$$leader} = 0; | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  | } | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | sub B::PMOP::mark_if_leader { | 
| 122 | 0 |  |  | 0 |  |  | my $op = shift; | 
| 123 | 0 | 0 | 0 |  |  |  | if (  $op->type | 
|  |  |  | 0 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
| 124 |  |  |  |  |  |  | and $op->name ne "pushre" | 
| 125 |  |  |  |  |  |  | and ($] > 5.008005 or $op->name ne "substcont") ) | 
| 126 |  |  |  |  |  |  | { | 
| 127 |  |  |  |  |  |  | #warn $op->name, $op->type if $] == 5.008004; | 
| 128 | 0 |  |  |  |  |  | my $replroot = $op->pmreplroot; | 
| 129 | 0 | 0 |  |  |  |  | if ($$replroot) { | 
| 130 | 0 |  |  |  |  |  | mark_leader( $replroot ); | 
| 131 | 0 |  |  |  |  |  | mark_leader( $op->next ); | 
| 132 | 0 |  |  |  |  |  | mark_leader( $op->pmreplstart ); | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  | } | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | # PMOP stuff omitted | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | sub compile { | 
| 140 | 0 |  |  | 0 | 0 |  | my @options = @_; | 
| 141 | 0 |  |  |  |  |  | my $have_B_Concise; | 
| 142 | 0 |  |  |  |  |  | B::clearsym(); | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 0 | 0 |  |  |  |  | eval { require B::Concise; 1 } and $have_B_Concise = 1; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 145 | 0 | 0 |  |  |  |  | B::Concise->import(qw(concise_cv concise_main set_style_standard)) | 
| 146 |  |  |  |  |  |  | if $have_B_Concise; | 
| 147 |  |  |  |  |  |  |  | 
| 148 | 0 | 0 | 0 |  |  |  | if ( @options and $have_B_Concise ) { | 
| 149 |  |  |  |  |  |  | return sub { | 
| 150 | 0 |  |  | 0 |  |  | my $objname; | 
| 151 | 0 |  |  |  |  |  | foreach $objname (@options) { | 
| 152 | 0 | 0 |  |  |  |  | $objname = "main::$objname" unless $objname =~ /::/; | 
| 153 | 0 |  |  |  |  |  | print "walk_bblocks $objname\n"; | 
| 154 | 0 |  |  |  |  |  | eval "walk_bblocks_obj(\\&$objname)"; | 
| 155 | 0 | 0 |  |  |  |  | die "walk_bblocks_obj(\\&$objname) failed: $@" if $@; | 
| 156 | 0 |  |  |  |  |  | print "-------\n"; | 
| 157 | 0 |  |  |  |  |  | set_style_standard("terse"); | 
| 158 | 0 |  |  |  |  |  | eval "concise_cv('exec', \\&$objname)"; | 
| 159 | 0 | 0 |  |  |  |  | die "concise_cv('exec', \\&$objname) failed: $@" if $@; | 
| 160 |  |  |  |  |  |  | } | 
| 161 |  |  |  |  |  |  | } | 
| 162 | 0 |  |  |  |  |  | } | 
| 163 |  |  |  |  |  |  | else { | 
| 164 |  |  |  |  |  |  | return sub { | 
| 165 | 0 |  |  | 0 |  |  | walk_bblocks( main_root, main_start ); | 
| 166 | 0 |  |  |  |  |  | print "-------\n"; | 
| 167 | 0 | 0 |  |  |  |  | if ($have_B_Concise) { | 
| 168 | 0 |  |  |  |  |  | set_style_standard("terse"); | 
| 169 | 0 |  |  |  |  |  | concise_main("exec"); | 
| 170 |  |  |  |  |  |  | } | 
| 171 | 0 |  |  |  |  |  | }; | 
| 172 |  |  |  |  |  |  | } | 
| 173 |  |  |  |  |  |  | } | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | 1; | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | __END__ |