1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#! /usr/bin/perl -w 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- The cache simulation framework: instrumentation, recording ---## 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- and results printing. ---## 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- callgrind_annotate ---## 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# This file is part of Callgrind, a cache-simulator and call graph 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# tracer built on Valgrind. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Copyright (C) 2003 Josef Weidendorfer 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Josef.Weidendorfer@gmx.de 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# This file is based heavily on cg_annotate, part of Valgrind. 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Copyright (C) 2002 Nicholas Nethercote 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# njn@valgrind.org 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# This program is free software; you can redistribute it and/or 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# modify it under the terms of the GNU General Public License as 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# published by the Free Software Foundation; either version 2 of the 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# License, or (at your option) any later version. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# This program is distributed in the hope that it will be useful, but 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# WITHOUT ANY WARRANTY; without even the implied warranty of 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# General Public License for more details. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# You should have received a copy of the GNU General Public License 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# along with this program; if not, write to the Free Software 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 02111-1307, USA. 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# The GNU General Public License is contained in the file COPYING. 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Annotator for cachegrind/callgrind. 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# File format is described in /docs/techdocs.html. 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Performance improvements record, using cachegrind.out for cacheprof, doing no 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# source annotation (irrelevant ones removed): 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# user time 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 1. turned off warnings in add_hash_a_to_b() 3.81 --> 3.48s 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# [now add_array_a_to_b()] 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 6. make line_to_CC() return a ref instead of a hash 3.01 --> 2.77s 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#10. changed file format to avoid file/fn name repetition 2.40s 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# (not sure why higher; maybe due to new '.' entries?) 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#11. changed file format to drop unnecessary end-line "."s 2.36s 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# (shrunk file by about 37%) 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#12. switched from hash CCs to array CCs 1.61s 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#13. only adding b[i] to a[i] if b[i] defined (was doing it if 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# either a[i] or b[i] was defined, but if b[i] was undefined 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# it just added 0) 1.48s 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#14. Stopped converting "." entries to undef and then back 1.16s 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#15. Using foreach $i (x..y) instead of for ($i = 0...) in 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# add_array_a_to_b() 1.11s 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Auto-annotating primes: 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#16. Finding count lengths by int((length-1)/3), not by 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# commifying (halves the number of commify calls) 1.68s --> 1.47s 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse strict; 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Overview: the running example in the comments is for: 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - events = A,B,C,D 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - --show=C,A,D 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - --sort=D,C 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Global variables, main data structures 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# CCs are arrays, the counts corresponding to @events, with 'undef' 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# representing '.'. This makes things fast (faster than using hashes for CCs) 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# but we have to use @sort_order and @show_order below to handle the --sort and 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# --show options, which is a bit tricky. 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Total counts for summary (an array reference). 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $summary_CC; 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $totals_CC; 84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $summary_calculated = 0; 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Totals for each function, for overall summary. 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash(filename:fn_name => CC array) 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %fn_totals; 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Individual CCs, organised by filename and line_num for easy annotation. 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash(filename => hash(line_num => CC array)) 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %all_ind_CCs; 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Files chosen for annotation on the command line. 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# key = basename (trimmed of any directory), value = full filename 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %user_ann_files; 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Generic description string. 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $desc = ""; 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Command line of profiled program. 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $cmd = ""; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Info on the profiled process. 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $creator = ""; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $pid = ""; 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $part = ""; 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $thread = ""; 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Positions used for cost lines; default: line numbers 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $has_line = 1; 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $has_addr = 0; 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Events in input file, eg. (A,B,C,D) 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @events; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $events; 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Events to show, from command line, eg. (C,A,D) 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @show_events; 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Map from @show_events indices to @events indices, eg. (2,0,3). Gives the 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# order in which we must traverse @events in order to show the @show_events, 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# eg. (@events[$show_order[1]], @events[$show_order[2]]...) = @show_events. 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# (Might help to think of it like a hash (0 => 2, 1 => 0, 2 => 3).) 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @show_order; 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Print out the function totals sorted by these events, eg. (D,C). 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @sort_events; 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Map from @sort_events indices to @events indices, eg. (3,2). Same idea as 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# for @show_order. 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @sort_order; 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Thresholds, one for each sort event (or default to 1 if no sort events 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# specified). We print out functions and do auto-annotations until we've 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# handled this proportion of all the events thresholded. 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @thresholds; 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $default_threshold = 99; 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $single_threshold = $default_threshold; 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# If on, automatically annotates all files that are involved in getting over 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# all the threshold counts. 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $auto_annotate = 0; 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Number of lines to show around each annotated line. 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $context = 8; 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Directories in which to look for annotation files. 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @include_dirs = (""); 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Verbose mode 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $verbose = "1"; 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Inclusive statistics (with subroutine events) 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $inclusive = 0; 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Inclusive totals for each function, for overall summary. 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash(filename:fn_name => CC array) 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %cfn_totals; 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash( file:func => [ called file:func ]) 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $called_funcs; 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash( file:func => [ calling file:func ]) 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $calling_funcs; 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash( file:func,line => [called file:func ]) 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $called_from_line; 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash( file:func,line => file:func 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %func_of_line; 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash (file:func => object name) 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %obj_name; 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Print out the callers of a function 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $tree_caller = 0; 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Print out the called functions 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $tree_calling = 0; 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash( file:func,cfile:cfunc => call CC[]) 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %call_CCs; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash( file:func,cfile:cfunc => call counter) 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %call_counter; 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# hash(context, index) => realname for compressed traces 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy %compressed; 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Input file name, will be set in process_cmd_line 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $input_file = ""; 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Version number 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $version = "@VERSION@"; 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Usage message. 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $usage = <<END 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownusage: callgrind_annotate [options] [callgrind-out-file [source-files...]] 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown options for the user, with defaults in [ ], are: 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -h --help show this message 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --version show version 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --show=A,B,C only show figures for events A,B,C [all] 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --sort=A,B,C sort columns by events A,B,C [event column order] 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --threshold=<0--100> percentage of counts (of primary sort event) we 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are interested in [$default_threshold%] 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --auto=yes|no annotate all source files containing functions 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that helped reach the event count threshold [no] 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --context=N print N lines of context before and after 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown annotated lines [8] 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --inclusive=yes|no add subroutine costs to functions calls [no] 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --tree=none|caller| print for each function their callers, 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown calling|both the called functions or both [none] 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -I --include=<dir> add <dir> to list of directories to search for 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown source files 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEND 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown; 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Used in various places of output. 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $fancy = '-' x 80 . "\n"; 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Argument and option handling 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub process_cmd_line() 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for my $arg (@ARGV) { 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Option handling 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($arg =~ /^-/) { 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --version 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($arg =~ /^--version$/) { 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die("callgrind_annotate-$version\n"); 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --show=A,B,C 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--show=(.*)$/) { 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @show_events = split(/,/, $1); 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --sort=A,B,C 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--sort=(.*)$/) { 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @sort_events = split(/,/, $1); 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $th_specified = 0; 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (0 .. scalar @sort_events - 1) { 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($sort_events[$i] =~ /.*:([\d\.]+)%?$/) { 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $th = $1; 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ($th >= 0 && $th <= 100) or die($usage); 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $sort_events[$i] =~ s/:.*//; 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $thresholds[$i] = $th; 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $th_specified = 1; 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $thresholds[$i] = 0; 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (not $th_specified) { 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @thresholds = (); 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --threshold=X (tolerates a trailing '%') 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--threshold=([\d\.]+)%?$/) { 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $single_threshold = $1; 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ($1 >= 0 && $1 <= 100) or die($usage); 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --auto=yes|no 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--auto=(yes|no)$/) { 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $auto_annotate = 1 if ($1 eq "yes"); 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $auto_annotate = 0 if ($1 eq "no"); 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --context=N 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--context=([\d\.]+)$/) { 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $context = $1; 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($context < 0) { 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die($usage); 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --inclusive=yes|no 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--inclusive=(yes|no)$/) { 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $inclusive = 1 if ($1 eq "yes"); 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $inclusive = 0 if ($1 eq "no"); 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --tree=none|caller|calling|both 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^--tree=(none|caller|calling|both)$/) { 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tree_caller = 1 if ($1 eq "caller" || $1 eq "both"); 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tree_calling = 1 if ($1 eq "calling" || $1 eq "both"); 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # --include=A,B,C 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($arg =~ /^(-I|--include)=(.*)$/) { 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $inc = $2; 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $inc =~ s|/$||; # trim trailing '/' 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@include_dirs, "$inc/"); 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { # -h and --help fall under this case 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die($usage); 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Argument handling -- annotation file checking and selection. 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Stick filenames into a hash for quick 'n easy lookup throughout 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($input_file eq "") { 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $input_file = $arg; 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $readable = 0; 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $include_dir (@include_dirs) { 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (-r $include_dir . $arg) { 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $readable = 1; 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $readable or die("File $arg not found in any of: @include_dirs\n"); 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $user_ann_files{$arg} = 1; 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($input_file eq "") { 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $input_file = (<callgrind.out*>)[0]; 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!defined $input_file) { 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $input_file = (<cachegrind.out*>)[0]; 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (defined $input_file) or die($usage); 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "Reading data from '$input_file'...\n"; 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Reading of input file 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub max ($$) 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($x, $y) = @_; 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ($x > $y ? $x : $y); 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Add the two arrays; any '.' entries are ignored. Two tricky things: 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 1. If $a2->[$i] is undefined, it defaults to 0 which is what we want; we turn 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# off warnings to allow this. This makes things about 10% faster than 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# checking for definedness ourselves. 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 2. We don't add an undefined count or a ".", even though it's value is 0, 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# because we don't want to make an $a2->[$i] that is undef become 0 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# unnecessarily. 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub add_array_a_to_b ($$) 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($a1, $a2) = @_; 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $n = max(scalar @$a1, scalar @$a2); 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $^W = 0; 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (0 .. $n-1) { 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $a2->[$i] += $a1->[$i] if (defined $a1->[$i] && "." ne $a1->[$i]); 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $^W = 1; 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Is this a line with all events zero? 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub is_zero ($) 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($CC) = @_; 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $isZero = 1; 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (0 .. (scalar @$CC)-1) { 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $isZero = 0 if ($CC->[$i] >0); 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $isZero; 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Add each event count to the CC array. '.' counts become undef, as do 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# missing entries (implicitly). 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub line_to_CC ($) 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @CC = (split /\s+/, $_[0]); 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (@CC <= @events) or die("Line $.: too many event counts\n"); 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return \@CC; 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub uncompressed_name($$) 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($context, $name) = @_; 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($name =~ /^\((\d+)\)\s*(.*)$/) { 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $index = $1; 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $realname = $2; 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($realname eq "") { 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $realname = $compressed{$context,$index}; 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $compressed{$context,$index} = $realname; 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $realname; 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $name; 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub read_input_file() 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown open(INPUTFILE, "< $input_file") || die "File $input_file not opened\n"; 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $line; 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Read header 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while(<INPUTFILE>) { 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # remove comments 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/#.*$//; 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (/^$/) { ; } 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^version:\s*(\d+)/) { 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Can't read format with major version > 1 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ($1<2) or die("Can't read format with major version $1.\n"); 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^pid:\s+(.*)$/) { $pid = $1; } 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^thread:\s+(.*)$/) { $thread = $1; } 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^part:\s+(.*)$/) { $part = $1; } 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^desc:\s+(.*)$/) { 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $dline = $1; 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # suppress profile options in description output 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($dline =~ /^Option:/) {;} 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { $desc .= "$dline\n"; } 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^cmd:\s+(.*)$/) { $cmd = $1; } 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^creator:\s+(.*)$/) { $creator = $1; } 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^positions:\s+(.*)$/) { 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $positions = $1; 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $has_line = ($positions =~ /line/); 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $has_addr = ($positions =~ /(addr|instr)/); 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elsif (/^events:\s+(.*)$/) { 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $events = $1; 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # events line is last in header 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown last; 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown warn("WARNING: header line $. malformed, ignoring\n"); 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($verbose) { chomp; warn(" line: '$_'\n"); } 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Read "events:" line. We make a temporary hash in which the Nth event's 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # value is N, which is useful for handling --show/--sort options below. 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ($events ne "") or die("Line $.: missing events line\n"); 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @events = split(/\s+/, $events); 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my %events; 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $n = 0; 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $event (@events) { 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $events{$event} = $n; 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $n++ 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If no --show arg give, default to showing all events in the file. 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If --show option is used, check all specified events appeared in the 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # "events:" line. Then initialise @show_order. 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (@show_events) { 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $show_event (@show_events) { 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (defined $events{$show_event}) or 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die("--show event `$show_event' did not appear in input\n"); 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @show_events = @events; 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $show_event (@show_events) { 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@show_order, $events{$show_event}); 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Do as for --show, but if no --sort arg given, default to sorting by 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # column order (ie. first column event is primary sort key, 2nd column is 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # 2ndary key, etc). 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (@sort_events) { 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $sort_event (@sort_events) { 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (defined $events{$sort_event}) or 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die("--sort event `$sort_event' did not appear in input\n"); 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @sort_events = @events; 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $sort_event (@sort_events) { 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@sort_order, $events{$sort_event}); 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If multiple threshold args weren't given via --sort, stick in the single 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # threshold (either from --threshold if used, or the default otherwise) for 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # the primary sort event, and 0% for the rest. 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (not @thresholds) { 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $e (@sort_order) { 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@thresholds, 0); 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $thresholds[0] = $single_threshold; 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Current directory, used to strip from file names if absolute 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $pwd = `pwd`; 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chomp $pwd; 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $pwd .= '/'; 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_obj = ""; 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_file; 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_fn; 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_name; 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_line_num = 0; 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $prev_line_num = 0; 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_cobj = ""; 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_cfile = ""; 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_cfunc = ""; 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_cname; 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_call_counter = 0; 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_cfn_CC = []; 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_fn_CC = []; 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $curr_file_ind_CCs = {}; # hash(line_num => CC) 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Read body of input file. 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (<INPUTFILE>) { 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $prev_line_num = $curr_line_num; 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/#.*$//; # remove comments 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/^\+(\d+)/$prev_line_num+$1/e; 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/^\-(\d+)/$prev_line_num-$1/e; 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/^\*/$prev_line_num/e; 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s/^(-?\d+|0x\w+)\s+//) { 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_line_num = $1; 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($has_addr) { 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($has_line) { 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/^\+(\d+)/$prev_line_num+$1/e; 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/^\-(\d+)/$prev_line_num-$1/e; 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s/^\*/$prev_line_num/e; 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s/^(\d+)\s+//) { $curr_line_num = $1; } 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { $curr_line_num = 0; } 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $CC = line_to_CC($_); 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($curr_call_counter>0) { 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# print "Read ($curr_name => $curr_cname) $curr_call_counter\n"; 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 542f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (!defined $call_CCs{$curr_name,$curr_cname}) { 543f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root $call_CCs{$curr_name,$curr_cname} = []; 544f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root $call_counter{$curr_name,$curr_cname} = 0; 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 546f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root add_array_a_to_b($CC, $call_CCs{$curr_name,$curr_cname}); 547f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root $call_counter{$curr_name,$curr_cname} += $curr_call_counter; 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp = $called_from_line->{$curr_file,$curr_line_num}; 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!defined $tmp) { 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $func_of_line{$curr_file,$curr_line_num} = $curr_name; 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tmp = {} unless defined $tmp; 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $$tmp{$curr_cname} = 1; 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $called_from_line->{$curr_file,$curr_line_num} = $tmp; 556f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (!defined $call_CCs{$curr_name,$curr_cname,$curr_line_num}) { 557f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root $call_CCs{$curr_name,$curr_cname,$curr_line_num} = []; 558f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root $call_counter{$curr_name,$curr_cname,$curr_line_num} = 0; 559f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 560f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root add_array_a_to_b($CC, $call_CCs{$curr_name,$curr_cname,$curr_line_num}); 561f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root $call_counter{$curr_name,$curr_cname,$curr_line_num} += $curr_call_counter; 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_call_counter = 0; 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # inclusive costs 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cfn_CC = $cfn_totals{$curr_cname}; 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cfn_CC = [] unless (defined $curr_cfn_CC); 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_array_a_to_b($CC, $curr_cfn_CC); 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $cfn_totals{$curr_cname} = $curr_cfn_CC; 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($inclusive) { 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_array_a_to_b($CC, $curr_fn_CC); 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown next; 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_array_a_to_b($CC, $curr_fn_CC); 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If curr_file is selected, add CC to curr_file list. We look for 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # full filename matches; or, if auto-annotating, we have to 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # remember everything -- we won't know until the end what's needed. 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($auto_annotate || defined $user_ann_files{$curr_file}) { 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp = $curr_file_ind_CCs->{$curr_line_num}; 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tmp = [] unless defined $tmp; 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_array_a_to_b($CC, $tmp); 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file_ind_CCs->{$curr_line_num} = $tmp; 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^fn=(.*)$//) { 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Commit result from previous function 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $fn_totals{$curr_name} = $curr_fn_CC if (defined $curr_name); 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Setup new one 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_fn = uncompressed_name("fn",$1); 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_name = "$curr_file:$curr_fn"; 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $obj_name{$curr_name} = $curr_obj; 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_fn_CC = $fn_totals{$curr_name}; 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_fn_CC = [] unless (defined $curr_fn_CC); 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^ob=(.*)$//) { 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_obj = uncompressed_name("ob",$1); 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^fl=(.*)$//) { 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $all_ind_CCs{$curr_file} = $curr_file_ind_CCs 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $curr_file); 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file = uncompressed_name("fl",$1); 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $curr_file =~ s/^\Q$pwd\E//; 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file_ind_CCs = $all_ind_CCs{$curr_file}; 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file_ind_CCs = {} unless (defined $curr_file_ind_CCs); 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^(fi|fe)=(.*)$//) { 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (defined $curr_name) or die("Line $.: Unexpected fi/fe line\n"); 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $fn_totals{$curr_name} = $curr_fn_CC; 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $all_ind_CCs{$curr_file} = $curr_file_ind_CCs; 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file = uncompressed_name("fl",$2); 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov $curr_file =~ s/^\Q$pwd\E//; 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_name = "$curr_file:$curr_fn"; 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file_ind_CCs = $all_ind_CCs{$curr_file}; 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file_ind_CCs = {} unless (defined $curr_file_ind_CCs); 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_fn_CC = $fn_totals{$curr_name}; 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_fn_CC = [] unless (defined $curr_fn_CC); 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^\s*$//) { 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # blank, do nothing 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^cob=(.*)$//) { 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cobj = uncompressed_name("ob",$1); 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 631436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } elsif (s/^cf[il]=(.*)$//) { 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cfile = uncompressed_name("fl",$1); 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^cfn=(.*)$//) { 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cfunc = uncompressed_name("fn",$1); 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($curr_cfile eq "") { 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cname = "$curr_file:$curr_cfunc"; 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cname = "$curr_cfile:$curr_cfunc"; 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_cfile = ""; 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp = $calling_funcs->{$curr_cname}; 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tmp = {} unless defined $tmp; 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $$tmp{$curr_name} = 1; 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $calling_funcs->{$curr_cname} = $tmp; 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp2 = $called_funcs->{$curr_name}; 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $tmp2 = {} unless defined $tmp2; 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $$tmp2{$curr_cname} = 1; 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $called_funcs->{$curr_name} = $tmp2; 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^calls=(\d+)//) { 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_call_counter = $1; 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^(jump|jcnd)=//) { 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown #ignore jump information 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^jfi=(.*)$//) { 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # side effect needed: possibly add compression mapping 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uncompressed_name("fl",$1); 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # ignore jump information 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^jfn=(.*)$//) { 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # side effect needed: possibly add compression mapping 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uncompressed_name("fn",$1); 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # ignore jump information 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^totals:\s+//) { 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $totals_CC = line_to_CC($_); 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif (s/^summary:\s+//) { 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $summary_CC = line_to_CC($_); 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown warn("WARNING: line $. malformed, ignoring\n"); 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($verbose) { chomp; warn(" line: '$_'\n"); } 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Finish up handling final filename/fn_name counts 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $fn_totals{"$curr_file:$curr_fn"} = $curr_fn_CC 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $curr_file && defined $curr_fn); 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $all_ind_CCs{$curr_file} = 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_file_ind_CCs if (defined $curr_file); 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Correct inclusive totals 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($inclusive) { 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $name (keys %cfn_totals) { 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $fn_totals{$name} = $cfn_totals{$name}; 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown close(INPUTFILE); 696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((not defined $summary_CC) || is_zero($summary_CC)) { 698436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov $summary_CC = $totals_CC; 699436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 700436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov # if neither 'summary:' nor 'totals:' line is given, 701436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov # calculate summary from fn_totals hash 702436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((not defined $summary_CC) || is_zero($summary_CC)) { 703436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov $summary_calculated = 1; 704436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov $summary_CC = []; 705436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov foreach my $name (keys %fn_totals) { 706436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov add_array_a_to_b($fn_totals{$name}, $summary_CC); 707436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 708436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 709436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Print options used 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub print_options () 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "Profile data file '$input_file'"; 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($creator ne "") { print " (creator: $creator)"; } 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "\n"; 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($desc); 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $target = $cmd; 725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ($target eq "") { $target = "(unknown)"; } 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($pid ne "") { 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $target .= " (PID $pid"; 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($part ne "") { $target .= ", part $part"; } 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($thread ne "") { $target .= ", thread $thread"; } 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $target .= ")"; 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("Profiled target: $target\n"); 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("Events recorded: @events\n"); 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("Events shown: @show_events\n"); 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("Event sort order: @sort_events\n"); 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("Thresholds: @thresholds\n"); 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @include_dirs2 = @include_dirs; # copy @include_dirs 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift(@include_dirs2); # remove "" entry, which is always the first 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unshift(@include_dirs2, "") if (0 == @include_dirs2); 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $include_dir = shift(@include_dirs2); 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("Include dirs: $include_dir\n"); 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $include_dir (@include_dirs2) { 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" $include_dir\n"); 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @user_ann_files = keys %user_ann_files; 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unshift(@user_ann_files, "") if (0 == @user_ann_files); 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $user_ann_file = shift(@user_ann_files); 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("User annotated: $user_ann_file\n"); 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach $user_ann_file (@user_ann_files) { 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" $user_ann_file\n"); 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $is_on = ($auto_annotate ? "on" : "off"); 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("Auto-annotation: $is_on\n"); 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n"); 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Print summary and sorted function totals 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub mycmp ($$) 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($c, $d) = @_; 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Iterate through sort events (eg. 3,2); return result if two are different 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (@sort_order) { 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($x, $y); 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $x = $c->[$i]; 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $y = $d->[$i]; 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $x = -1 unless defined $x; 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $y = -1 unless defined $y; 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $cmp = $y <=> $x; # reverse sort 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 != $cmp) { 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $cmp; 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Exhausted events, equal 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub commify ($) { 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($val) = @_; 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1 while ($val =~ s/^(\d+)(\d{3})/$1,$2/); 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $val; 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Because the counts can get very big, and we don't want to waste screen space 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# and make lines too long, we compute exactly how wide each column needs to be 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# by finding the widest entry for each one. 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub compute_CC_col_widths (@) 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @CCs = @_; 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $CC_col_widths = []; 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Initialise with minimum widths (from event names) 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $event (@events) { 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@$CC_col_widths, length($event)); 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Find maximum width count for each column. @CC_col_width positions 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # correspond to @CC positions. 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $CC (@CCs) { 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (0 .. scalar(@$CC)-1) { 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $CC->[$i]) { 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Find length, accounting for commas that will be added 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $length = length $CC->[$i]; 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $clength = $length + int(($length - 1) / 3); 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $CC_col_widths->[$i] = max($CC_col_widths->[$i], $clength); 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $CC_col_widths; 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Print the CC with each column's size dictated by $CC_col_widths. 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub print_CC ($$) 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($CC, $CC_col_widths) = @_; 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (@show_order) { 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $count = (defined $CC->[$i] ? commify($CC->[$i]) : "."); 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $space = ' ' x ($CC_col_widths->[$i] - length($count)); 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("$space$count "); 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub print_events ($) 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($CC_col_widths) = @_; 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (@show_order) { 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $event = $events[$i]; 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $event_width = length($event); 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $col_width = $CC_col_widths->[$i]; 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $space = ' ' x ($col_width - $event_width); 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("$space$event "); 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Prints summary and function totals (with separate column widths, so that 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# function names aren't pushed over unnecessarily by huge summary figures). 845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Also returns a hash containing all the files that are involved in getting the 846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# events count above the thresholds (ie. all the interesting ones). 847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub print_summary_and_fn_totals () 848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @fn_fullnames = keys %fn_totals; 850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Work out the size of each column for printing (summary and functions 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # separately). 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $summary_CC_col_widths = compute_CC_col_widths($summary_CC); 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $fn_CC_col_widths = compute_CC_col_widths(values %fn_totals); 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Header and counts for summary 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_events($summary_CC_col_widths); 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n"); 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($summary_CC, $summary_CC_col_widths); 862436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov print(" PROGRAM TOTALS"); 863436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ($summary_calculated) { 864436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov print(" (calculated)"); 865436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 866436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov print("\n\n"); 867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Header for functions 869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_events($fn_CC_col_widths); 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" file:function\n"); 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Sort function names into order dictated by --sort option. 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown @fn_fullnames = sort { 876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mycmp($fn_totals{$a}, $fn_totals{$b}) 877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } @fn_fullnames; 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Assertion 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (scalar @sort_order == scalar @thresholds) or 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die("sort_order length != thresholds length:\n", 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " @sort_order\n @thresholds\n"); 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $threshold_files = {}; 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # @curr_totals has the same shape as @sort_order and @thresholds 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @curr_totals = (); 888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $e (@thresholds) { 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@curr_totals, 0); 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print functions, stopping when the threshold has been reached. 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $fn_name (@fn_fullnames) { 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Stop when we've reached all the thresholds 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $reached_all_thresholds = 1; 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (0 .. scalar @thresholds - 1) { 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $prop = $curr_totals[$i] * 100; 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($summary_CC->[$sort_order[$i]] >0) { 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $prop = $prop / $summary_CC->[$sort_order[$i]]; 901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $reached_all_thresholds &&= ($prop >= $thresholds[$i]); 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown last if $reached_all_thresholds; 905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($tree_caller || $tree_calling) { print "\n"; } 907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($tree_caller && ($fn_name ne "???:???")) { 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print function callers 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp1 = $calling_funcs->{$fn_name}; 911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $tmp1) { 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $calling (keys %$tmp1) { 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $call_counter{$calling,$fn_name}) { 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($call_CCs{$calling,$fn_name}, $fn_CC_col_widths); 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print" < $calling ("; 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print $call_counter{$calling,$fn_name} . "x)"; 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $obj_name{$calling}) { 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print " [$obj_name{$calling}]"; 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "\n"; 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print function results 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $fn_CC = $fn_totals{$fn_name}; 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($fn_CC, $fn_CC_col_widths); 929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($tree_caller || $tree_calling) { print " * "; } 930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" $fn_name"); 931436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((defined $obj_name{$fn_name}) && 932436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ($obj_name{$fn_name} ne "")) { 933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print " [$obj_name{$fn_name}]"; 934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "\n"; 936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($tree_calling && ($fn_name ne "???:???")) { 938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print called functions 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp2 = $called_funcs->{$fn_name}; 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $tmp2) { 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $called (keys %$tmp2) { 942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $call_counter{$fn_name,$called}) { 943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($call_CCs{$fn_name,$called}, $fn_CC_col_widths); 944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print" > $called ("; 945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print $call_counter{$fn_name,$called} . "x)"; 946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $obj_name{$called}) { 947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print " [$obj_name{$called}]"; 948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print "\n"; 950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Update the threshold counts 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $filename = $fn_name; 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $filename =~ s/:.+$//; # remove function name 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $threshold_files->{$filename} = 1; 959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $i (0 .. scalar @sort_order - 1) { 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($inclusive) { 961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_totals[$i] = $summary_CC->[$sort_order[$i]] - 962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $fn_CC->[$sort_order[$i]] 963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $fn_CC->[$sort_order[$i]]); 964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $curr_totals[$i] += $fn_CC->[$sort_order[$i]] 966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $fn_CC->[$sort_order[$i]]); 967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n"); 971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return $threshold_files; 973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Annotate selected files 977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------- 978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Issue a warning that the source file is more recent than the input file. 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub warning_on_src_more_recent_than_inputfile ($) 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $src_file = $_[0]; 983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $warning = <<END 985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ 987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@ Source file '$src_file' is more recent than input file '$input_file'. 989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@ Annotations may not be correct. 990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEND 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown; 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($warning); 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# If there is information about lines not in the file, issue a warning 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# explaining possible causes. 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub warning_on_nonexistent_lines ($$$) 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($src_more_recent_than_inputfile, $src_file, $excess_line_nums) = @_; 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $cause_and_solution; 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($src_more_recent_than_inputfile) { 1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $cause_and_solution = <<END 1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ cause: '$src_file' has changed since information was gathered. 1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ If so, a warning will have already been issued about this. 1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ solution: Recompile program and rerun under "valgrind --cachesim=yes" to 1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ gather new information. 1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEND 1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # We suppress warnings about .h files 1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } elsif ($src_file =~ /\.h$/) { 1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $cause_and_solution = <<END 1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ cause: bug in the Valgrind's debug info reader that screws up with .h 1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ files sometimes 1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ solution: none, sorry 1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEND 1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $cause_and_solution = <<END 1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ cause: not sure, sorry 1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEND 1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $warning = <<END 1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ 1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ 1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ Information recorded about lines past the end of '$src_file'. 1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ 1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@ Probable cause and solution: 1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown$cause_and_solution@@ 1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownEND 1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown; 1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($warning); 1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub annotate_ann_files($) 1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my ($threshold_files) = @_; 1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my %all_ann_files; 1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @unfound_auto_annotate_files; 1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $printed_totals_CC = []; 1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If auto-annotating, add interesting files (but not "???") 1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($auto_annotate) { 1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delete $threshold_files->{"???"}; 1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown %all_ann_files = (%user_ann_files, %$threshold_files) 1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown %all_ann_files = %user_ann_files; 1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Track if we did any annotations. 1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $did_annotations = 0; 1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LOOP: 1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $src_file (keys %all_ann_files) { 1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $opened_file = ""; 1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $full_file_name = ""; 1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $include_dir (@include_dirs) { 1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $try_name = $include_dir . $src_file; 1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (open(INPUTFILE, "< $try_name")) { 1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $opened_file = $try_name; 1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $full_file_name = ($include_dir eq "" 1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? $src_file 1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "$include_dir + $src_file"); 1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown last; 1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (not $opened_file) { 1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Failed to open the file. If chosen on the command line, die. 1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If arose from auto-annotation, print a little message. 1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $user_ann_files{$src_file}) { 1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown die("File $src_file not opened in any of: @include_dirs\n"); 1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@unfound_auto_annotate_files, $src_file); 1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # File header (distinguish between user- and auto-selected files). 1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("$fancy"); 1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $ann_type = 1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (defined $user_ann_files{$src_file} ? "User" : "Auto"); 1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("-- $ann_type-annotated source: $full_file_name\n"); 1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("$fancy"); 1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Get file's CCs 1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $src_file_CCs = $all_ind_CCs{$src_file}; 1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!defined $src_file_CCs) { 1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" No information has been collected for $src_file\n\n"); 1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown next LOOP; 1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $did_annotations = 1; 1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Numeric, not lexicographic sort! 1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @line_nums = sort {$a <=> $b} keys %$src_file_CCs; 1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If $src_file more recent than cachegrind.out, issue warning 1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $src_more_recent_than_inputfile = 0; 1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((stat $opened_file)[9] > (stat $input_file)[9]) { 1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $src_more_recent_than_inputfile = 1; 1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown warning_on_src_more_recent_than_inputfile($src_file); 1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Work out the size of each column for printing 1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $CC_col_widths = compute_CC_col_widths(values %$src_file_CCs); 1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Events header 1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_events($CC_col_widths); 1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n\n"); 1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Shift out 0 if it's in the line numbers (from unknown entries, 1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # likely due to bugs in Valgrind's stabs debug info reader) 1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift(@line_nums) if (0 == $line_nums[0]); 1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Finds interesting line ranges -- all lines with a CC, and all 1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # lines within $context lines of a line with a CC. 1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $n = @line_nums; 1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my @pairs; 1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (my $i = 0; $i < $n; $i++) { 1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@pairs, $line_nums[$i] - $context); # lower marker 1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ($i < $n-1 && 1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $line_nums[$i] + 2*$context >= $line_nums[$i+1]) { 1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $i++; 1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown push(@pairs, $line_nums[$i] + $context); # upper marker 1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Annotate chosen lines, tracking total counts of lines printed 1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $pairs[0] = 1 if ($pairs[0] < 1); 1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (@pairs) { 1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $low = shift @pairs; 1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $high = shift @pairs; 1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ($. < $low-1) { 1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp = <INPUTFILE>; 1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown last unless (defined $tmp); # hack to detect EOF 1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $src_line; 1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print line number, unless start of file 1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("-- line $low " . '-' x 40 . "\n") if ($low != 1); 1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (($. < $high) && ($src_line = <INPUTFILE>)) { 1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $line_nums[0] && $. == $line_nums[0]) { 1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($src_file_CCs->{$.}, $CC_col_widths); 1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_array_a_to_b($src_file_CCs->{$.}, 1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $printed_totals_CC); 1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift(@line_nums); 1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC( [], $CC_col_widths); 1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" $src_line"); 1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $tmp = $called_from_line->{$src_file,$.}; 1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $func = $func_of_line{$src_file,$.}; 1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $tmp) { 1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $called (keys %$tmp) { 1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (defined $call_CCs{$func,$called,$.}) { 1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($call_CCs{$func,$called,$.}, $CC_col_widths); 1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print " => $called ("; 1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print $call_counter{$func,$called,$.} . "x)\n"; 1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print line number, unless EOF 1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($src_line) { 1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("-- line $high " . '-' x 40 . "\n"); 1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown last; 1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If there was info on lines past the end of the file... 1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (@line_nums) { 1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $line_num (@line_nums) { 1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($src_file_CCs->{$line_num}, $CC_col_widths); 1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" <bogus line $line_num>\n"); 1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n"); 1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown warning_on_nonexistent_lines($src_more_recent_than_inputfile, 1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $src_file, \@line_nums); 1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n"); 1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print summary of counts attributed to file but not to any 1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # particular line (due to incomplete debug info). 1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($src_file_CCs->{0}) { 1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($src_file_CCs->{0}, $CC_col_widths); 1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" <counts for unidentified lines in $src_file>\n\n"); 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown close(INPUTFILE); 1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # Print list of unfound auto-annotate selected files. 1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (@unfound_auto_annotate_files) { 1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("$fancy"); 1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("The following files chosen for auto-annotation could not be found:\n"); 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach my $f (@unfound_auto_annotate_files) { 1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" $f\n"); 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n"); 1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # If we did any annotating, print what proportion of events were covered by 1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown # annotated lines above. 1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ($did_annotations) { 1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $percent_printed_CC; 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown foreach (my $i = 0; $i < @$summary_CC; $i++) { 1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $percent_printed_CC->[$i] = 1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sprintf("%.0f", 1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown $printed_totals_CC->[$i] / $summary_CC->[$i] * 100); 1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown my $pp_CC_col_widths = compute_CC_col_widths($percent_printed_CC); 1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_events($pp_CC_col_widths); 1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print("\n"); 1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print($fancy); 1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_CC($percent_printed_CC, $pp_CC_col_widths); 1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print(" percentage of events annotated\n\n"); 1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# "main()" 1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#---------------------------------------------------------------------------- 1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprocess_cmd_line(); 1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownread_input_file(); 1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint_options(); 1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $threshold_files = print_summary_and_fn_totals(); 1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownannotate_ann_files($threshold_files); 1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- end vg_annotate.in ---## 1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------## 1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1247