aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/maint/analyze_callgraph.py50
-rwxr-xr-xscripts/maint/display_callgraph.py2
2 files changed, 47 insertions, 5 deletions
diff --git a/scripts/maint/analyze_callgraph.py b/scripts/maint/analyze_callgraph.py
index b28460489a..8ce5827f07 100755
--- a/scripts/maint/analyze_callgraph.py
+++ b/scripts/maint/analyze_callgraph.py
@@ -9,19 +9,28 @@ import os
class Parser:
def __init__(self):
self.calls = {}
+ self.definedIn = {}
def enter_func(self, name):
- if self.infunc and not self.extern:
+ if self.infunc and not self.extern and self.calledfns:
+ if self.infunc in self.definedIn:
+ #print "{}: {} or {}?".format(
+ # self.infunc, self.definedIn[self.infunc], self.module)
+ self.definedIn[self.infunc] = 'nil'
+ else:
+ self.definedIn[self.infunc] = self.module
self.calls.setdefault(self.infunc, set()).update( self.calledfns )
self.calledfns = set()
self.infunc = name
self.extern = False
- def parse_callgraph_file(self, inp):
+ def parse_callgraph_file(self, inp, module):
self.infunc = None
self.extern = False
self.calledfns = set()
+ self.module = module
+
for line in inp:
m = re.match(r"Call graph node for function: '([^']+)'", line)
if m:
@@ -189,13 +198,27 @@ def connection_bottlenecks(callgraph):
if __name__ == '__main__':
p = Parser()
for fname in sys.argv[1:]:
+ modname = re.sub(r'.*/', '', fname).replace('.callgraph', '.c')
with open(fname, 'r') as f:
- p.parse_callgraph_file(f)
+ p.parse_callgraph_file(f, modname)
- sys.stdout.flush
+ sys.stdout.flush()
print "Building callgraph"
callgraph = p.extract_callgraph()
+ inModule = p.definedIn
+
+ print "Deriving module callgraph"
+ modCallgraph = {}
+ for fn in callgraph:
+ fnMod = inModule[fn]
+ for called in callgraph[fn]:
+ try:
+ calledMod = inModule[called]
+ except KeyError:
+ continue
+ modCallgraph.setdefault(fnMod, set()).add(calledMod)
+ del modCallgraph['nil']
print "Finding strongly connected components"
sccs = strongly_connected_components(callgraph)
@@ -206,11 +229,28 @@ if __name__ == '__main__':
print "Finding bottlenecks..."
bottlenecks = connection_bottlenecks(callgraph)
+ print "Finding module SCCs"
+ modSCCS = strongly_connected_components(modCallgraph)
+
+ print "Finding module TC"
+ modTC = transitive_closure(modCallgraph)
+
+ print "Finding module bottlenecks"
+ modB = connection_bottlenecks(modCallgraph)
+
data = {
'callgraph' : callgraph,
'sccs' : sccs,
'closure' : closure,
- 'bottlenecks' : bottlenecks }
+ 'bottlenecks' : bottlenecks,
+ 'modules' : p.definedIn,
+ 'modItems' : {
+ 'callgraph' : modCallgraph,
+ 'sccs' : modSCCS,
+ 'closure' : modTC,
+ 'bottlenecks' : modB,
+ }
+ }
with open('callgraph.pkl', 'w') as f:
cPickle.dump(data, f)
diff --git a/scripts/maint/display_callgraph.py b/scripts/maint/display_callgraph.py
index 211bfda28d..c9001c6d96 100755
--- a/scripts/maint/display_callgraph.py
+++ b/scripts/maint/display_callgraph.py
@@ -4,6 +4,8 @@ import cPickle
data = cPickle.load(open("callgraph.pkl"))
+# data = data['modItems']
+
callgraph = data['callgraph']
closure = data['closure']
sccs = data['sccs']