[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