summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authormarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-24 16:22:44 +0000
committermarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-24 16:22:44 +0000
commitfbf561f42d8ee8c1286cd3948d38835fdb77abd1 (patch)
tree58def27bed7c883fb39401708de460fccdea696c /contrib
parentb6d48a7882da778bab9b1e72d0eb9f2e290028d8 (diff)
Dump profile-based number of iterations
* analyze_brprob.py: Parse and display average number of loop iterations. * cfgloop.c (flow_loop_dump): Dump average number of loop iterations. * cfgloop.h: Change 'struct loop' to 'const struct loop' for a few functions. * cfgloopanal.c (expected_loop_iterations_unbounded): Set a new argument to true if the expected number of iterations is loop-based. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237762 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'contrib')
-rw-r--r--contrib/ChangeLog5
-rwxr-xr-xcontrib/analyze_brprob.py33
2 files changed, 38 insertions, 0 deletions
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 07019c2ccbe9..d5f194af4d3c 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-24 Martin Liska <mliska@suse.cz>
+
+ * analyze_brprob.py: Parse and display average number
+ of loop iterations.
+
2016-06-23 Andi Kleen <ak@linux.intel.com>
* gen_autofdo_event.py: New file to regenerate
diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
index 2526623ff550..c276d810a4f6 100755
--- a/contrib/analyze_brprob.py
+++ b/contrib/analyze_brprob.py
@@ -67,9 +67,26 @@ import os
import re
import argparse
+from math import *
+
def percentage(a, b):
return 100.0 * a / b
+def average(values):
+ return 1.0 * sum(values) / len(values)
+
+def average_cutoff(values, cut):
+ l = len(values)
+ skip = floor(l * cut / 2)
+ if skip > 0:
+ values.sort()
+ values = values[skip:-skip]
+ return average(values)
+
+def median(values):
+ values.sort()
+ return values[int(len(values) / 2)]
+
class Summary:
def __init__(self, name):
self.name = name
@@ -93,6 +110,7 @@ class Profile:
def __init__(self, filename):
self.filename = filename
self.heuristics = {}
+ self.niter_vector = []
def add(self, name, prediction, count, hits):
if not name in self.heuristics:
@@ -106,6 +124,10 @@ class Profile:
s.hits += hits
s.fits += max(hits, count - hits)
+ def add_loop_niter(self, niter):
+ if niter > 0:
+ self.niter_vector.append(niter)
+
def branches_max(self):
return max([v.branches for k, v in self.heuristics.items()])
@@ -127,6 +149,13 @@ class Profile:
percentage(v.hits, v.count), percentage(v.fits, v.count),
v.count, v.count_formatted(), percentage(v.count, self.count_max()) ))
+ print ('\nLoop count: %d' % len(self.niter_vector)),
+ print(' avg. # of iter: %.2f' % average(self.niter_vector))
+ print(' median # of iter: %.2f' % median(self.niter_vector))
+ for v in [1, 5, 10, 20, 30]:
+ cut = 0.01 * v
+ print(' avg. (%d%% cutoff) # of iter: %.2f' % (v, average_cutoff(self.niter_vector, cut)))
+
parser = argparse.ArgumentParser()
parser.add_argument('dump_file', metavar = 'dump_file', help = 'IPA profile dump file')
parser.add_argument('-s', '--sorting', dest = 'sorting', choices = ['branches', 'hitrate', 'coverage'], default = 'branches')
@@ -135,6 +164,7 @@ args = parser.parse_args()
profile = Profile(sys.argv[1])
r = re.compile(' (.*) heuristics( of edge [0-9]*->[0-9]*)?( \\(.*\\))?: (.*)%.*exec ([0-9]*) hit ([0-9]*)')
+loop_niter_str = ';; profile-based iteration count: '
for l in open(args.dump_file).readlines():
m = r.match(l)
if m != None and m.group(3) == None:
@@ -144,5 +174,8 @@ for l in open(args.dump_file).readlines():
hits = int(m.group(6))
profile.add(name, prediction, count, hits)
+ elif l.startswith(loop_niter_str):
+ v = int(l[len(loop_niter_str):])
+ profile.add_loop_niter(v)
profile.dump(args.sorting)