summaryrefslogtreecommitdiffstats
path: root/kcachegrind/converters/op2calltree
diff options
context:
space:
mode:
Diffstat (limited to 'kcachegrind/converters/op2calltree')
-rwxr-xr-xkcachegrind/converters/op2calltree238
1 files changed, 238 insertions, 0 deletions
diff --git a/kcachegrind/converters/op2calltree b/kcachegrind/converters/op2calltree
new file mode 100755
index 00000000..ff755390
--- /dev/null
+++ b/kcachegrind/converters/op2calltree
@@ -0,0 +1,238 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2004
+# Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
+#
+# op2calltree is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+#
+# Converter from OProfile's output of "opreport -gdf" (v 0.8)
+# into callgrind format.
+#
+# Generate a OProfile report with opreport and flags -gdf
+# and pipe this as standard input into this script.
+# This will generate separate cachegrind files for every application.
+#
+
+
+# parse symbol line. example (with 1 event type, $has_image==0):
+# 308 0.1491 /path/source.c:6 /path/app main
+sub parseSymSpec {
+ $e = 0;
+ while($e < $eventCount) {
+ ($line) = ($line =~ /\d+\s+\S+\s+(.*)/);
+ $e++;
+ }
+ if ($line =~ s/^\(no location information\)\s+//) {
+ $file = "???";
+ $linenr = 0;
+ }
+ else {
+ ($file,$linenr) = ($line =~ s/(\S+?):(\d+)\s+//);
+ }
+ if ($has_image) {
+ if ($line =~ s/^(\S+)\s+//) { $img = $1; }
+ }
+ if ($has_app) {
+ if ($line =~ s/^(\S+)\s+//) { $app = $1; }
+ if (!$has_image) { $img = $app; }
+ }
+ $sym = $line;
+
+ $app =~ s/^.*\///;
+ if ($sym eq "(no symbols)") { $sym = "???"; }
+ $file{$sym} = $file;
+ $linenr{$sym} = $linenr;
+ $app{$sym} = $app;
+ $img{$app,$sym} = $img;
+ $syms{$app}++;
+
+ if ($app ne $oldApp) {
+ $oldApp = $app;
+ print "\n\nApp $app\n";
+ }
+ print " Symbol $sym (Image $img)\n";
+}
+
+
+
+$eventCount = 0;
+$descCount = 0;
+$lnr = 0;
+$has_image = 0;
+$has_app = 0;
+$app = "unnamed";
+$img = "???";
+
+# first loop till first symbol specification
+while(<>) {
+ $lnr++;
+ chomp;
+ if (/^CPU:/) {
+ $desc[$descCount++] = $_;
+ next;
+ }
+ if (/^Counted\s*(\S+)/) {
+ $desc[$descCount++] = $_;
+ $eventCount++;
+ $events[$eventCount] = $1;
+ next;
+ }
+ if (/^(Profiling through timer.*)/) {
+ $desc[$descCount++] = $_;
+ $eventCount++;
+ $events[$eventCount] = "Timer";
+ next;
+ }
+ if (/^vma/) {
+ # title row: adapt to separation options of OProfile
+ if (/image/) { $has_image = 1; }
+ if (/app/) { $has_app = 1; }
+ next;
+ }
+ if (/^([0-9a-fA-F]+)\s*(.*)$/) {
+ $vmaSym = $1;
+ $line = $2;
+ last;
+ }
+}
+
+if ($eventCount == 0) {
+ die "No Events found";
+}
+
+print "Description:\n";
+foreach $d (@desc) { print " $d\n"; }
+print "\n";
+
+print "Events:";
+foreach $e (@events) { print " $e"; }
+print "\n";
+
+parseSymSpec;
+
+while(<>) {
+ $lnr++;
+ if (/^([0-9a-fA-F]+)\s*(.*)$/) {
+ $vmaSym = $1;
+ $line = $2;
+
+ parseSymSpec;
+ next;
+ }
+ if (/^\s+([0-9a-fA-F]+)\s*(.*)$/) {
+
+ $sampleCount{$app,$sym}++;
+ $sc = $sampleCount{$app,$sym};
+
+ $vma{$app,$sym,$sc} = $1;
+ $line = $2;
+
+ $e = 1;
+ while($e <= $eventCount) {
+ ($cost, $line) = ($line =~ /(\d+)\s+\S+\s+(.*)/);
+ $summary{$app,$e} += $cost;
+ $cost{"$app,$sym,$sc,$e"} = $cost;
+ $e++;
+ }
+ if ($line =~ /\(no location information\)/) {
+ $file = "???";
+ $linenr = 0;
+ }
+ else {
+ ($file,$linenr) = ($line =~ /(\S+?):(\d+)/);
+ }
+ $sFile{$app,$sym,$sc} = $file;
+ $linenr{$app,$sym,$sc} = $linenr;
+
+ $file =~ s/^.*\///;
+ print " Sample $sc: $vma{$app,$sym,$sc} ($file:$linenr):";
+ foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; print " $c"; }
+ print "\n";
+ next;
+ }
+ die "ERROR: Reading line $lnr '$_'\n";
+}
+
+foreach $app (keys %syms) {
+ if ($app eq "") { next; }
+ print "Generating dump for App '$app'...\n";
+
+ $out = "# Generated by op2cg, using OProfile with opreport -gdf\n";
+ $out .= "positions: instr line\n";
+
+ $out .= "events:";
+ foreach $e (@events) { $out .= " $e"; }
+ $out .= "\n";
+
+ $out .= "summary:";
+ foreach $e (1 .. $eventCount) { $out .= " $summary{$app,$e}"; }
+ $out .= "\n\n";
+
+ %fileNum = ();
+ $fileNum = 1;
+ $sf = "";
+
+ $img = "";
+
+ foreach $sym (keys %file) {
+ if ($sampleCount{$app,$sym} eq "") { next; }
+
+ if ($img{$app,$sym} ne $img) {
+ $img = $img{$app,$sym};
+ $out .= "ob=$img\n";
+ }
+
+ $file = $file{$sym};
+ if ($sf ne $file) {
+ if ($fileNum{$file} eq "") {
+ $fileNum{$file} = $fileNum;
+ $out .= "fl=($fileNum) $file\n";
+ $fileNum++;
+ }
+ else {
+ $out .= "fl=($fileNum{$file})\n";
+ }
+ $sf = $file;
+ }
+
+ $out .= "fn=$sym\n";
+ foreach $sc (1 .. $sampleCount{$app,$sym}) {
+ if ($sf ne $sFile{$app,$sym,$sc}) {
+ $sf = $sFile{$app,$sym,$sc};
+ if ($sf eq $file) {
+ $out .= "fe=($fileNum{$file})\n";
+ }
+ else {
+ if ($fileNum{$sf} eq "") {
+ $fileNum{$sf} = $fileNum;
+ $out .= "fi=($fileNum) $sf\n";
+ $fileNum++;
+ }
+ else {
+ $out .= "fi=($fileNum{$sf})\n";
+ }
+ }
+ }
+ $out .= "0x$vma{$app,$sym,$sc} $linenr{$app,$sym,$sc}";
+ foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; $out .= " $c"; }
+ $out .= "\n";
+ }
+ }
+
+ open OUT, ">oprof.out.$app";
+ print OUT $out;
+ close OUT;
+}