diff options
author | marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-06-24 16:22:44 +0000 |
---|---|---|
committer | marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-06-24 16:22:44 +0000 |
commit | fbf561f42d8ee8c1286cd3948d38835fdb77abd1 (patch) | |
tree | 58def27bed7c883fb39401708de460fccdea696c /contrib | |
parent | b6d48a7882da778bab9b1e72d0eb9f2e290028d8 (diff) | |
download | gcc-fbf561f42d8ee8c1286cd3948d38835fdb77abd1.tar.gz |
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/ChangeLog | 5 | ||||
-rwxr-xr-x | contrib/analyze_brprob.py | 33 |
2 files changed, 38 insertions, 0 deletions
diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 07019c2ccbe..d5f194af4d3 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 2526623ff55..c276d810a4f 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) |