File indexing completed on 2024-04-28 09:36:43

0001 #!/usr/bin/perl
0002 #
0003 # Copyright (c) 2004
0004 # Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0005 #
0006 # op2calltree is free software; you can redistribute it and/or
0007 # modify it under the terms of the GNU General Public
0008 # License as published by the Free Software Foundation, version 2.
0009 #
0010 # This program is distributed in the hope that it will be useful,
0011 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013 # General Public License for more details.
0014 
0015 # You should have received a copy of the GNU General Public License
0016 # along with this program; see the file COPYING.  If not, write to
0017 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018 # Boston, MA 02110-1301, USA.
0019 #
0020 #
0021 # Converter from OProfile's output of "opreport -gdf" (v 0.8)
0022 # into callgrind format.
0023 #
0024 # Generate a OProfile report with opreport and flags -gdf
0025 # and pipe this as standard input into this script.
0026 # This will generate separate cachegrind files for every application.
0027 #
0028 
0029 
0030 # parse symbol line. example (with 1 event type, $has_image==0):
0031 #   308  0.1491  /path/source.c:6 /path/app main
0032 sub parseSymSpec {
0033   $e = 0;
0034   while($e < $eventCount) {
0035     ($line) = ($line =~ /\d+\s+\S+\s+(.*)/);
0036     $e++;
0037   }
0038   if ($line =~ s/^\(no location information\)\s+//) {
0039     $file = "???";
0040     $linenr = 0;
0041   }
0042   else {
0043     ($file,$linenr) = ($line =~ s/(\S+?):(\d+)\s+//);
0044   }
0045   if ($has_image) {
0046     if ($line =~ s/^(\S+)\s+//) { $img = $1; }
0047   }
0048   if ($has_app) {
0049     if ($line =~ s/^(\S+)\s+//) { $app = $1; }
0050     if (!$has_image) { $img = $app; }
0051   }
0052   $sym = $line;
0053 
0054   $app =~ s/^.*\///;
0055   if ($sym eq "(no symbols)") { $sym = "???"; }
0056   $file{$sym} = $file;
0057   $linenr{$sym} = $linenr;
0058   $app{$sym} = $app;
0059   $img{$app,$sym} = $img;
0060   $syms{$app}++;
0061 
0062   if ($app ne $oldApp) {
0063     $oldApp = $app;
0064     print "\n\nApp $app\n";
0065   }
0066   print " Symbol $sym (Image $img)\n";
0067 }
0068 
0069 
0070 
0071 $eventCount = 0;
0072 $descCount = 0;
0073 $lnr = 0;
0074 $has_image = 0;
0075 $has_app = 0;
0076 $app = "unnamed";
0077 $img = "???";
0078 
0079 # first loop till first symbol specification
0080 while(<>) {
0081   $lnr++;
0082   chomp;
0083   if (/^CPU:/) {
0084     $desc[$descCount++] = $_;
0085     next;
0086   }
0087   if (/^Counted\s*(\S+)/) {
0088     $desc[$descCount++] = $_;
0089     $eventCount++;
0090     $events[$eventCount] = $1;
0091     next;
0092   }
0093   if (/^(Profiling through timer.*)/) {
0094     $desc[$descCount++] = $_;
0095     $eventCount++;
0096     $events[$eventCount] = "Timer";
0097     next;
0098   }
0099   if (/^vma/) {
0100     # title row: adapt to separation options of OProfile
0101     if (/image/) { $has_image = 1; }
0102     if (/app/) { $has_app = 1; }
0103     next;
0104   }
0105   if (/^([0-9a-fA-F]+)\s*(.*)$/) {
0106     $vmaSym = $1;
0107     $line = $2;
0108     last;
0109   }
0110 }
0111 
0112 if ($eventCount == 0) {
0113   die "No Events found";
0114 }
0115 
0116 print "Description:\n";
0117 foreach $d (@desc) { print " $d\n"; }
0118 print "\n";
0119 
0120 print "Events:";
0121 foreach $e (@events) { print " $e"; }
0122 print "\n";
0123 
0124 parseSymSpec;
0125 
0126 while(<>) {
0127   $lnr++;
0128   if (/^([0-9a-fA-F]+)\s*(.*)$/) {
0129     $vmaSym = $1;
0130     $line = $2;
0131 
0132     parseSymSpec;
0133     next;
0134   }
0135   if (/^\s+([0-9a-fA-F]+)\s*(.*)$/) {
0136 
0137     $sampleCount{$app,$sym}++;
0138     $sc = $sampleCount{$app,$sym};
0139 
0140     $vma{$app,$sym,$sc} = $1;
0141     $line = $2;
0142 
0143     $e = 1;
0144     while($e <= $eventCount) {
0145       ($cost, $line) = ($line =~ /(\d+)\s+\S+\s+(.*)/);
0146       $summary{$app,$e} += $cost;
0147       $cost{"$app,$sym,$sc,$e"} = $cost;
0148       $e++;
0149     }
0150     if ($line =~ /\(no location information\)/) {
0151       $file = "???";
0152       $linenr = 0;
0153     }
0154     else {
0155       ($file,$linenr) = ($line =~ /(\S+?):(\d+)/);
0156     }
0157     $sFile{$app,$sym,$sc} = $file;
0158     $linenr{$app,$sym,$sc} = $linenr;
0159 
0160     $file =~ s/^.*\///;
0161     print "  Sample $sc: $vma{$app,$sym,$sc} ($file:$linenr):";
0162     foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; print " $c"; }
0163     print "\n";
0164     next;
0165   }
0166   die "ERROR: Reading line $lnr '$_'\n";
0167 }
0168 
0169 foreach $app (keys %syms) {
0170   if ($app eq "") { next; }
0171   print "Generating dump for App '$app'...\n";
0172 
0173   $out = "# Generated by op2cg, using OProfile with opreport -gdf\n";
0174   $out .= "positions: instr line\n";
0175 
0176   $out .= "events:";
0177   foreach $e (@events) { $out .= " $e"; }
0178   $out .= "\n";
0179 
0180   $out .= "summary:";
0181   foreach $e (1 .. $eventCount) { $out .= " $summary{$app,$e}"; }
0182   $out .= "\n\n";
0183 
0184   %fileNum = ();
0185   $fileNum = 1;
0186   $sf = "";
0187 
0188   $img = "";
0189 
0190   foreach $sym (keys %file) {
0191     if ($sampleCount{$app,$sym} eq "") { next; }
0192 
0193     if ($img{$app,$sym} ne $img) {
0194       $img = $img{$app,$sym};
0195       $out .= "ob=$img\n";
0196     }
0197 
0198     $file = $file{$sym};
0199     if ($sf ne $file) {
0200       if ($fileNum{$file} eq "") {
0201     $fileNum{$file} = $fileNum;
0202     $out .= "fl=($fileNum) $file\n";
0203     $fileNum++;
0204       }
0205       else {
0206     $out .= "fl=($fileNum{$file})\n";
0207       }
0208       $sf = $file;
0209     }
0210 
0211     $out .= "fn=$sym\n";
0212     foreach $sc (1 .. $sampleCount{$app,$sym}) {
0213       if ($sf ne $sFile{$app,$sym,$sc}) {
0214     $sf = $sFile{$app,$sym,$sc};
0215     if ($sf eq $file) {
0216       $out .= "fe=($fileNum{$file})\n";
0217     }
0218     else {
0219       if ($fileNum{$sf} eq "") {
0220         $fileNum{$sf} = $fileNum;
0221         $out .= "fi=($fileNum) $sf\n";
0222         $fileNum++;
0223       }
0224       else {
0225         $out .= "fi=($fileNum{$sf})\n";
0226       }
0227     }
0228       }
0229       $out .= "0x$vma{$app,$sym,$sc} $linenr{$app,$sym,$sc}";
0230       foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; $out .= " $c"; }
0231       $out .= "\n";
0232     }
0233   }
0234 
0235   open OUT, ">oprof.out.$app";
0236   print OUT $out;
0237   close OUT;
0238 }