| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package optimizer; |
|
2
|
2
|
|
|
2
|
|
7214
|
use Carp; |
|
|
2
|
|
|
|
|
6
|
|
|
|
2
|
|
|
|
|
153
|
|
|
3
|
2
|
|
|
2
|
|
10
|
use B; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
69
|
|
|
4
|
2
|
|
|
2
|
|
10
|
{ no warnings 'redefine'; |
|
|
2
|
|
|
|
|
14
|
|
|
|
2
|
|
|
|
|
76
|
|
|
5
|
2
|
|
|
2
|
|
1911
|
use B::Generate; |
|
|
2
|
|
|
|
|
4913
|
|
|
|
2
|
|
|
|
|
84
|
|
|
6
|
|
|
|
|
|
|
} |
|
7
|
2
|
|
|
2
|
|
46
|
use 5.007002; |
|
|
2
|
|
|
|
|
8
|
|
|
|
2
|
|
|
|
|
73
|
|
|
8
|
2
|
|
|
2
|
|
11
|
use strict; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
60
|
|
|
9
|
2
|
|
|
2
|
|
9
|
use warnings; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
103
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
BEGIN { |
|
12
|
|
|
|
|
|
|
# op_seq workaround for 5.10, store it as package global. |
|
13
|
2
|
|
|
2
|
|
5
|
my $seq = 0; |
|
14
|
2
|
50
|
|
|
|
14
|
if ($] > 5.009) { |
|
15
|
2
|
0
|
|
0
|
|
3567
|
eval q( |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
16
|
|
|
|
|
|
|
package B::OP; |
|
17
|
|
|
|
|
|
|
sub seq { |
|
18
|
|
|
|
|
|
|
shift; |
|
19
|
|
|
|
|
|
|
@_ ? $optimizer::seq = shift : $optimizer::seq; |
|
20
|
|
|
|
|
|
|
} |
|
21
|
|
|
|
|
|
|
); |
|
22
|
|
|
|
|
|
|
} |
|
23
|
|
|
|
|
|
|
} |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
require DynaLoader; |
|
26
|
|
|
|
|
|
|
our $VERSION = '0.08'; |
|
27
|
|
|
|
|
|
|
our @ISA = q(DynaLoader); |
|
28
|
|
|
|
|
|
|
our %callbacks; |
|
29
|
|
|
|
|
|
|
bootstrap optimizer $VERSION; |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my ($file, $line) = ("unknown", "unknown"); |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
{ |
|
34
|
|
|
|
|
|
|
sub _preparewarn { |
|
35
|
0
|
|
|
0
|
|
0
|
my $args = join '', @_; |
|
36
|
0
|
0
|
|
|
|
0
|
$args = "Something's wrong " unless $args; |
|
37
|
0
|
0
|
|
|
|
0
|
$args .= " at $file line $line.\n" unless substr($args, length($args) -1) eq "\n"; |
|
38
|
|
|
|
|
|
|
} |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub _update { |
|
41
|
0
|
|
|
0
|
|
0
|
my $cop = shift; $file = $cop->file; $line = $cop->line; |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
|
|
44
|
0
|
|
|
0
|
|
0
|
sub _die (@) { CORE::die(preparewarn(@_)) } |
|
45
|
0
|
|
|
0
|
|
0
|
sub _warn (@) { CORE::warn(preparewarn(@_)) } |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub import { |
|
49
|
3
|
|
|
3
|
|
79
|
my ($class,$type) = (shift, shift); |
|
50
|
3
|
50
|
|
|
|
12
|
if (!defined $type) { |
|
51
|
0
|
|
|
|
|
0
|
CORE::warn("Must pass an action to ${class}'s importer"); |
|
52
|
|
|
|
|
|
|
return |
|
53
|
0
|
|
|
|
|
0
|
} |
|
54
|
3
|
50
|
33
|
|
|
64
|
if ($type eq 'C' or $type eq 'c') { |
|
|
|
50
|
33
|
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
0
|
optimizer::uninstall(); |
|
56
|
|
|
|
|
|
|
} elsif ($type =~ /^Perl$/i) { |
|
57
|
0
|
|
|
0
|
|
0
|
optimizer::install( sub { optimizer::peepextend($_[0], sub {}) }); |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
58
|
|
|
|
|
|
|
} elsif ($type eq "callback" or $type eq "extend" or $type eq "mine") { |
|
59
|
0
|
|
|
|
|
0
|
my $subref = shift; |
|
60
|
0
|
0
|
|
|
|
0
|
croak "Supplied callback was not a subref" unless ref $subref eq "CODE"; |
|
61
|
0
|
0
|
|
0
|
|
0
|
optimizer::install( sub { callbackoptimizer($_[0], $subref) }) if $type eq "callback"; |
|
|
0
|
|
|
|
|
0
|
|
|
62
|
0
|
0
|
|
0
|
|
0
|
optimizer::install( sub { optimizer::peepextend($_[0], $subref) }) if $type eq "extend"; |
|
|
0
|
|
|
|
|
0
|
|
|
63
|
0
|
0
|
|
|
|
0
|
optimizer::install( $subref ) if $type eq "mine"; |
|
64
|
|
|
|
|
|
|
} elsif ($type eq 'extend-c') { |
|
65
|
0
|
|
|
|
|
0
|
optimizer::c_extend_install(shift); |
|
66
|
|
|
|
|
|
|
} elsif ($type eq 'sub-detect') { |
|
67
|
3
|
|
|
|
|
11
|
my ($package, $filename, $line) = caller; |
|
68
|
3
|
|
|
|
|
7
|
$callbacks{$package} = shift; |
|
69
|
3
|
|
|
|
|
141
|
optimizer::c_sub_detect_install(); |
|
70
|
0
|
|
|
|
|
|
} else { croak "Unknown optimizer option '$type'"; } |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub unimport { |
|
74
|
0
|
|
|
0
|
|
|
optimizer::install(sub {callbackoptimizer($_[0], sub{})}); |
|
|
0
|
|
|
0
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub callbackoptimizer { |
|
78
|
0
|
|
|
0
|
1
|
|
my ($op, $callback) = @_; |
|
79
|
0
|
|
|
|
|
|
while ($$op) { |
|
80
|
0
|
|
|
|
|
|
$op->seq(optimizer::op_seqmax_inc()); |
|
81
|
0
|
0
|
|
|
|
|
_update($op) if $op->isa("B::COP"); |
|
82
|
|
|
|
|
|
|
# crashes: wrong op_sv, strange cv |
|
83
|
|
|
|
|
|
|
#_relocatetopad($op, $op->find_cv()) if $op->name eq "const"; # For thread safety |
|
84
|
|
|
|
|
|
|
|
|
85
|
0
|
|
|
|
|
|
$callback->($op); |
|
86
|
0
|
|
|
|
|
|
$op = $op->next; |
|
87
|
0
|
0
|
|
|
|
|
last unless $op->can("next"); # Shouldn't get here |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub peepextend { |
|
92
|
|
|
|
|
|
|
# Oh boy |
|
93
|
0
|
|
|
0
|
1
|
|
my ($o, $callback) = @_; |
|
94
|
0
|
|
|
|
|
|
my $oldop = 0; |
|
95
|
|
|
|
|
|
|
|
|
96
|
0
|
0
|
0
|
|
|
|
return if !$$o or $o->seq; |
|
97
|
|
|
|
|
|
|
|
|
98
|
0
|
0
|
|
|
|
|
op_seqmax_inc() unless op_seqmax(); |
|
99
|
0
|
|
|
|
|
|
while ($$o) { |
|
100
|
|
|
|
|
|
|
#warn ("Trying op $o ($$o) -> ".$o->name."\n"); |
|
101
|
0
|
0
|
0
|
|
|
|
if ($o->isa("B::COP")) { |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
102
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
103
|
0
|
|
|
|
|
|
_update($o); # For warnings |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
} elsif ($o->name eq "const") { |
|
106
|
0
|
0
|
|
|
|
|
optimizer::_die("Bareword ",$o->sv->sv, " not allowed while \"strict subs\" in use") |
|
107
|
|
|
|
|
|
|
if ($o->private & 8); |
|
108
|
|
|
|
|
|
|
# crashes: wrong op_sv, strange cv |
|
109
|
|
|
|
|
|
|
#_relocatetopad($o, $o->find_cv()); |
|
110
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
111
|
|
|
|
|
|
|
} elsif ($o->name eq "concat") { |
|
112
|
0
|
0
|
0
|
|
|
|
if ($o->next && $o->next->name eq "stringify" and !($o->flags &64)) { |
|
|
|
|
0
|
|
|
|
|
|
113
|
0
|
0
|
|
|
|
|
if ($o->next->private & 16) { |
|
114
|
0
|
|
|
|
|
|
$o->targ($o->next->targ); |
|
115
|
0
|
|
|
|
|
|
$o->next->targ(0); |
|
116
|
|
|
|
|
|
|
} |
|
117
|
|
|
|
|
|
|
#$o->null; |
|
118
|
|
|
|
|
|
|
} |
|
119
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
120
|
|
|
|
|
|
|
#} elsif ($o->name eq "stub") { |
|
121
|
|
|
|
|
|
|
# CORE::die "Eep."; |
|
122
|
|
|
|
|
|
|
#} elsif ($o->name eq "null") { |
|
123
|
|
|
|
|
|
|
# CORE::die "Eep."; |
|
124
|
|
|
|
|
|
|
} elsif ($o->name eq "scalar" or $o->name eq "lineseq" or $o->name eq "scope") { |
|
125
|
0
|
0
|
0
|
|
|
|
if ($$oldop and ${$o->next}) { |
|
|
0
|
|
|
|
|
|
|
|
126
|
0
|
|
|
|
|
|
$oldop->next($o->next); |
|
127
|
0
|
|
|
|
|
|
$o=$o->next; |
|
128
|
0
|
|
|
|
|
|
next; |
|
129
|
|
|
|
|
|
|
} |
|
130
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
131
|
|
|
|
|
|
|
#} elsif ($o->name eq "gv") { |
|
132
|
|
|
|
|
|
|
# CORE::die "Eep."; |
|
133
|
|
|
|
|
|
|
} elsif ($o->name =~ /^((map|grep)while|(and|or)(assign)?|cond_expr|range)$/) { |
|
134
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
135
|
0
|
|
|
|
|
|
$o->other($o->other->next) while $o->other->name eq "null"; |
|
136
|
0
|
|
|
|
|
|
peepextend($o->other, $callback); # Weee. |
|
137
|
|
|
|
|
|
|
} elsif ($o->name =~ /^enter(loop|iter|given|when)/) { |
|
138
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
139
|
0
|
|
|
|
|
|
$o->redoop($o->redoop->next) while $o->redoop->name eq "null"; |
|
140
|
0
|
|
|
|
|
|
peepextend($o->redoop, $callback); |
|
141
|
0
|
|
|
|
|
|
$o->nextop($o->nextop->next) while $o->nextop->name eq "null"; |
|
142
|
0
|
|
|
|
|
|
peepextend($o->nextop, $callback); |
|
143
|
0
|
|
|
|
|
|
$o->lastop($o->lastop->next) while $o->lastop->name eq "null"; |
|
144
|
0
|
|
|
|
|
|
peepextend($o->lastop, $callback); |
|
145
|
|
|
|
|
|
|
} elsif ($o->name eq "qr" or $o->name eq "match" or $o->name eq "subst") { |
|
146
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
147
|
0
|
|
|
|
|
|
$o->pmreplstart($o->pmreplstart->next) |
|
148
|
0
|
|
0
|
|
|
|
while ${$o->pmreplstart} and $o->pmreplstart->name eq "null"; |
|
149
|
0
|
|
|
|
|
|
peepextend($o->pmreplstart, $callback); |
|
150
|
|
|
|
|
|
|
} elsif ($o->name eq "exec") { |
|
151
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
152
|
0
|
0
|
0
|
|
|
|
if (${$o->next} and $o->next->name eq "nextstate" and |
|
|
0
|
|
0
|
|
|
|
|
|
|
0
|
|
0
|
|
|
|
|
|
153
|
|
|
|
|
|
|
${$o->next->sibling} and $o->next->sibling->type !~ /exit|warn|die/) { |
|
154
|
0
|
|
|
|
|
|
optimizer::_warn("Statement unlikely to be reached"); |
|
155
|
0
|
|
|
|
|
|
optimizer::_warn("\t(Maybe you meant system() when you said exec()?)\n"); |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
} else { |
|
158
|
|
|
|
|
|
|
# Screw pseudohashes. |
|
159
|
0
|
|
|
|
|
|
$o->seq(optimizer::op_seqmax_inc()); |
|
160
|
|
|
|
|
|
|
} |
|
161
|
0
|
|
|
|
|
|
my $plop = $o; |
|
162
|
|
|
|
|
|
|
|
|
163
|
0
|
|
|
|
|
|
$callback->($o); |
|
164
|
0
|
|
|
|
|
|
$oldop = $o; |
|
165
|
0
|
|
|
|
|
|
$o = $o->next; |
|
166
|
0
|
0
|
|
|
|
|
last unless $o->can("next"); # Shouldn't get here |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
} |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
1; |
|
171
|
|
|
|
|
|
|
__END__ |