[pypy-svn] rev 2139 - pypy/trunk/doc/translation

arigo at codespeak.net arigo at codespeak.net
Fri Oct 31 16:18:05 CET 2003


Author: arigo
Date: Fri Oct 31 16:18:04 2003
New Revision: 2139

Modified:
   pypy/trunk/doc/translation/annotation.txt
Log:
About lists and mutable objects.


Modified: pypy/trunk/doc/translation/annotation.txt
==============================================================================
--- pypy/trunk/doc/translation/annotation.txt	(original)
+++ pypy/trunk/doc/translation/annotation.txt	Fri Oct 31 16:18:04 2003
@@ -1,6 +1,9 @@
 Mixed control flow / annotation pass
 ====================================
 
+Factorial
+---------
+
 Say we want to make the control flow graph and type inference
 on the following program::
 
@@ -144,3 +147,79 @@
 
 The bindings are implemented as a dictionary, and the annotations as
 an AnnSet instance.
+
+
+Whole-program analysis
+----------------------
+
+A program of more than once function is analysed in exactly the same way,
+starting from an entry point and following calls.  We have a cache of all
+the blocks that the flow objspace produced, and a list of pending blocks
+that we have to type-analyse.  When the analysis of a block temporarily
+fails (as above for the first recursive call to ``f``) we move the block
+at the end of the pending list.  There is only one heap of annotations
+for the whole program, so that we can track where the objects come from
+and go through the whole program.  (This makes separate compilation very
+difficult, I guess.)
+
+
+Empty lists
+-----------
+
+Nothing special is required for empty lists.  Let's try::
+
+  def g(a, n):
+    a.append(n)
+
+  def f():
+    b = []
+    g(b, 5)
+    g(b, 6)
+
+As above, after simplification::
+
+  F_StartBlock():
+    v1 = newlist()
+    v2 = simple_call(g, v1, 5)
+    v3 = simple_call(g, v1, 6)
+
+  Analyse(F_StartBlock):
+    v1 -------> X1   type(X1)=list  len(X1)=0  getitem(X1,?)=?
+    v2 -------> crash
+
+The ``?`` is a special value meaning ``no analysis information``.  The type analysis fails because of the calls to ``g``, but it triggers the analysis of ``g`` with the input arguments' annotations::
+
+  G_StartBlock(v4, v5):
+    v6 = getattr(v4, 'append')
+    v7 = simple_call(v6, v5)
+
+  Analyse(G_StartBlock):
+    v4 -------> X1    # from the call above
+    v5 -------> 5     # from the call above
+    v6 -------> X6    im_self(X6)=X1  im_func(X6)=list_append
+    v7 -------> None  REMOVE{len(X1)=0}  getitem(X1,?)=5
+
+Note that the call to list_append corrects the annotations about ``X1``.
+This would invalidate any type inference that would depend on the modified
+annotations.  (Hopefully, we eventually reach a fixpoint; this could be
+enforced by requiring that we can only either remove annotations or give
+a value to a ``?``.)
+
+Only after this can the analysis of ``F_StartBlock`` proceed, and
+now we know that v1 points to the list ``X1`` with the correct annotations:
+unknown length, all items are ``5``.
+
+In the above example I also show a second call to ``g(b, 6)``, which
+triggers an intersection on the input argument types of ``g`` which was
+previously thought to be used with ``5`` only::
+
+  Intersection(G_StartBlock):
+    previous annotations for v5 -------> 5    type(5)=int
+    new annotations for v5 ------------> 6    type(6)=int
+    intersection of both is v5 --------> X5   type(X5)=int
+
+And so this time the list ``X1`` is updated with::
+
+    getitem(X1,?)=X5
+
+and now we know that we have a list of integers.


More information about the Pypy-commit mailing list