diff options
Diffstat (limited to 'tdecachegrind/converters/op2calltree')
-rwxr-xr-x | tdecachegrind/converters/op2calltree | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/tdecachegrind/converters/op2calltree b/tdecachegrind/converters/op2calltree new file mode 100755 index 00000000..ca121a2a --- /dev/null +++ b/tdecachegrind/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., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, 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; +} |