[pypy-svn] r19298 - pypy/dist/pypy/translator

tismer at codespeak.net tismer at codespeak.net
Mon Oct 31 20:54:32 CET 2005


Author: tismer
Date: Mon Oct 31 20:54:31 2005
New Revision: 19298

Modified:
   pypy/dist/pypy/translator/translator.py
Log:
added some provision to get the complete callgraph.

The problem was that we do some initial callgraph,
but in the later transformations, we don't update that,
and it would be not so trivial to enforce this.

Therefore, I created a property complete_callgraph,
which is recomputed whenever new graphs are added.

Modified: pypy/dist/pypy/translator/translator.py
==============================================================================
--- pypy/dist/pypy/translator/translator.py	(original)
+++ pypy/dist/pypy/translator/translator.py	Mon Oct 31 20:54:31 2005
@@ -15,7 +15,7 @@
 log = py.log.Producer("getflowgraph") 
 py.log.setconsumer("getflowgraph", ansi_log) 
 
-class Translator:
+class Translator(object):
 
     def __init__(self, func=None, verbose=False, simplifying=True,
                  do_imports_immediately=True,
@@ -37,6 +37,8 @@
         self.frozen = False   # when frozen, no more flowgraphs can be generated
         #self.concretetypes = {}  # see getconcretetype()
         #self.ctlist = []         #  "
+        # the following is an index into self.functions from where to check
+        self._callgraph_complete = 0
         if self.entrypoint:
             self.getflowgraph()
 
@@ -161,6 +163,7 @@
             checkgraph(graph)
 
     def specialize(self, **flags):
+        self._callgraph_complete = 0
         if self.annotator is None:
             raise ValueError("you need to call annotate() first")
         if self.rtyper is not None:
@@ -172,6 +175,7 @@
         self.rtyper.specialize(**flags)
 
     def backend_optimizations(self, **kwds):
+        self._callgraph_complete = 0
         from pypy.translator.backendopt.all import backend_optimizations
         backend_optimizations(self, **kwds)
 
@@ -364,3 +368,34 @@
 ##            result = self.concretetypes[cls, args] = cls(self, *args)
 ##            self.ctlist.append(result)
 ##            return result
+
+    def get_complete_callgraph(self):
+        if self._callgraph_complete < len(self.functions):
+            self._complete_callgraph()
+        return self.callgraph
+    complete_callgraph = property(get_complete_callgraph)
+
+    def _complete_callgraph(self):
+        # walk through all functions, which may grow
+        # if we pull new graphs in.
+        graphs = self.flowgraphs
+        funcs = self.functions
+        was_frozen = self.frozen
+        self.frozen = False
+        complete = self._callgraph_complete
+        while complete < len(funcs):
+            sofar = len(funcs)
+            for func in funcs[complete:]:
+                graph = graphs[func]
+                for block in graph.iterblocks():
+                    for op in block.operations:
+                        if op.opname == 'direct_call':
+                            fnarg = op.args[0]
+                            if isinstance(fnarg, Constant):
+                                fnptr = fnarg.value
+                                fn = fnptr._obj._callable
+                                fg = self.getflowgraph(fn, called_by = func,
+                                                       call_tag = block)
+            complete = sofar
+        self.frozen = was_frozen
+        self._callgraph_complete = complete



More information about the Pypy-commit mailing list