Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
3.4 KiB

  1. package B::Bblock;
  2. use Exporter ();
  3. @ISA = "Exporter";
  4. @EXPORT_OK = qw(find_leaders);
  5. use B qw(peekop walkoptree walkoptree_exec
  6. main_root main_start svref_2object);
  7. use B::Terse;
  8. use strict;
  9. my $bblock;
  10. my @bblock_ends;
  11. sub mark_leader {
  12. my $op = shift;
  13. if ($$op) {
  14. $bblock->{$$op} = $op;
  15. }
  16. }
  17. sub find_leaders {
  18. my ($root, $start) = @_;
  19. $bblock = {};
  20. mark_leader($start);
  21. walkoptree($root, "mark_if_leader");
  22. return $bblock;
  23. }
  24. # Debugging
  25. sub walk_bblocks {
  26. my ($root, $start) = @_;
  27. my ($op, $lastop, $leader, $bb);
  28. $bblock = {};
  29. mark_leader($start);
  30. walkoptree($root, "mark_if_leader");
  31. my @leaders = values %$bblock;
  32. while ($leader = shift @leaders) {
  33. $lastop = $leader;
  34. $op = $leader->next;
  35. while ($$op && !exists($bblock->{$$op})) {
  36. $bblock->{$$op} = $leader;
  37. $lastop = $op;
  38. $op = $op->next;
  39. }
  40. push(@bblock_ends, [$leader, $lastop]);
  41. }
  42. foreach $bb (@bblock_ends) {
  43. ($leader, $lastop) = @$bb;
  44. printf "%s .. %s\n", peekop($leader), peekop($lastop);
  45. for ($op = $leader; $$op != $$lastop; $op = $op->next) {
  46. printf " %s\n", peekop($op);
  47. }
  48. printf " %s\n", peekop($lastop);
  49. }
  50. print "-------\n";
  51. walkoptree_exec($start, "terse");
  52. }
  53. sub walk_bblocks_obj {
  54. my $cvref = shift;
  55. my $cv = svref_2object($cvref);
  56. walk_bblocks($cv->ROOT, $cv->START);
  57. }
  58. sub B::OP::mark_if_leader {}
  59. sub B::COP::mark_if_leader {
  60. my $op = shift;
  61. if ($op->label) {
  62. mark_leader($op);
  63. }
  64. }
  65. sub B::LOOP::mark_if_leader {
  66. my $op = shift;
  67. mark_leader($op->next);
  68. mark_leader($op->nextop);
  69. mark_leader($op->redoop);
  70. mark_leader($op->lastop->next);
  71. }
  72. sub B::LOGOP::mark_if_leader {
  73. my $op = shift;
  74. my $ppaddr = $op->ppaddr;
  75. mark_leader($op->next);
  76. if ($ppaddr eq "pp_entertry") {
  77. mark_leader($op->other->next);
  78. } else {
  79. mark_leader($op->other);
  80. }
  81. }
  82. sub B::CONDOP::mark_if_leader {
  83. my $op = shift;
  84. mark_leader($op->next);
  85. mark_leader($op->true);
  86. mark_leader($op->false);
  87. }
  88. sub B::PMOP::mark_if_leader {
  89. my $op = shift;
  90. if ($op->ppaddr ne "pp_pushre") {
  91. my $replroot = $op->pmreplroot;
  92. if ($$replroot) {
  93. mark_leader($replroot);
  94. mark_leader($op->next);
  95. mark_leader($op->pmreplstart);
  96. }
  97. }
  98. }
  99. # PMOP stuff omitted
  100. sub compile {
  101. my @options = @_;
  102. if (@options) {
  103. return sub {
  104. my $objname;
  105. foreach $objname (@options) {
  106. $objname = "main::$objname" unless $objname =~ /::/;
  107. eval "walk_bblocks_obj(\\&$objname)";
  108. die "walk_bblocks_obj(\\&$objname) failed: $@" if $@;
  109. }
  110. }
  111. } else {
  112. return sub { walk_bblocks(main_root, main_start) };
  113. }
  114. }
  115. # Basic block leaders:
  116. # Any COP (pp_nextstate) with a non-NULL label
  117. # [The op after a pp_enter] Omit
  118. # [The op after a pp_entersub. Don't count this one.]
  119. # The ops pointed at by nextop, redoop and lastop->op_next of a LOOP
  120. # The ops pointed at by op_next and op_other of a LOGOP, except
  121. # for pp_entertry which has op_next and op_other->op_next
  122. # The ops pointed at by op_true and op_false of a CONDOP
  123. # The op pointed at by op_pmreplstart of a PMOP
  124. # The op pointed at by op_other->op_pmreplstart of pp_substcont?
  125. # [The op after a pp_return] Omit
  126. 1;
  127. __END__
  128. =head1 NAME
  129. B::Bblock - Walk basic blocks
  130. =head1 SYNOPSIS
  131. perl -MO=Bblock[,OPTIONS] foo.pl
  132. =head1 DESCRIPTION
  133. See F<ext/B/README>.
  134. =head1 AUTHOR
  135. Malcolm Beattie, C<[email protected]>
  136. =cut