[pypy-svn] r22828 - in pypy/dist/pypy/jit: . test

arigo at codespeak.net arigo at codespeak.net
Sun Jan 29 12:53:04 CET 2006


Author: arigo
Date: Sun Jan 29 12:53:00 2006
New Revision: 22828

Added:
   pypy/dist/pypy/jit/hintvlist.py   (contents, props changed)
Modified:
   pypy/dist/pypy/jit/hintannotator.py
   pypy/dist/pypy/jit/hintbookkeeper.py
   pypy/dist/pypy/jit/hintcontainer.py
   pypy/dist/pypy/jit/hintmodel.py
   pypy/dist/pypy/jit/test/test_hint_annotation.py
Log:
Hint-annotator support for virtual lists.


Modified: pypy/dist/pypy/jit/hintannotator.py
==============================================================================
--- pypy/dist/pypy/jit/hintannotator.py	(original)
+++ pypy/dist/pypy/jit/hintannotator.py	Sun Jan 29 12:53:00 2006
@@ -5,8 +5,8 @@
 
 class HintAnnotator(RPythonAnnotator):
 
-    def __init__(self):
-        RPythonAnnotator.__init__(self)
+    def __init__(self, policy=None):
+        RPythonAnnotator.__init__(self, policy=policy)
         self.bookkeeper = HintBookkeeper(self) # XXX
 
     def consider_op_malloc(self, hs_TYPE):

Modified: pypy/dist/pypy/jit/hintbookkeeper.py
==============================================================================
--- pypy/dist/pypy/jit/hintbookkeeper.py	(original)
+++ pypy/dist/pypy/jit/hintbookkeeper.py	Sun Jan 29 12:53:00 2006
@@ -44,16 +44,21 @@
         op = block.operations[i]
         return op.result.concretetype
 
-    def getvirtualcontainerdef(self, TYPE):
+    def getvirtualcontainerdef(self, TYPE, constructor=None):
         try:
             res = self.virtual_containers[self.position_key]
             assert res.T == TYPE
         except KeyError:
-            from pypy.jit.hintcontainer import virtualcontainerdef
-            res = virtualcontainerdef(self, TYPE)
+            if constructor is None:
+                from pypy.jit.hintcontainer import virtualcontainerdef
+                constructor = virtualcontainerdef
+            res = constructor(self, TYPE)
             self.virtual_containers[self.position_key] = res
         return res
-        
+
+    def warning(self, msg):
+        return self.annotator.warning(msg)
+
 # get current bookkeeper
 
 def getbookkeeper():

Modified: pypy/dist/pypy/jit/hintcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/hintcontainer.py	(original)
+++ pypy/dist/pypy/jit/hintcontainer.py	Sun Jan 29 12:53:00 2006
@@ -3,6 +3,15 @@
 from pypy.jit import hintmodel
 from pypy.rpython.lltypesystem import lltype
 
+
+class AbstractContainerDef(object):
+
+    def __init__(self, bookkeeper, TYPE):
+        self.T = TYPE
+        self.bookkeeper = bookkeeper
+
+# ____________________________________________________________
+
 def virtualcontainerdef(bookkeeper, T, vparent=None):
     """Build and return a VirtualXxxDef() corresponding to a
     freshly allocated virtual container.
@@ -35,11 +44,10 @@
             vstructdef.fields[self.name] = self
 
 
-class VirtualStructDef:
+class VirtualStructDef(AbstractContainerDef):
  
     def __init__(self, bookkeeper, TYPE, vparent=None):
-        self.T = TYPE
-        self.bookkeeper = bookkeeper
+        AbstractContainerDef.__init__(self, bookkeeper, TYPE)
         self.fields = {}
         self.names = TYPE._names
         for name in self.names:
@@ -96,11 +104,10 @@
             varraydef.arrayitem = self
 
 
-class VirtualArrayDef:
+class VirtualArrayDef(AbstractContainerDef):
 
     def __init__(self, bookkeeper, TYPE):
-        self.T = TYPE
-        self.bookkeeper = bookkeeper
+        AbstractContainerDef.__init__(self, bookkeeper, TYPE)
         hs = make_item_annotation(bookkeeper, TYPE.OF)
         self.arrayitem = ArrayItem(bookkeeper, hs)
         self.arrayitem.itemof[self] = True

Modified: pypy/dist/pypy/jit/hintmodel.py
==============================================================================
--- pypy/dist/pypy/jit/hintmodel.py	(original)
+++ pypy/dist/pypy/jit/hintmodel.py	Sun Jan 29 12:53:00 2006
@@ -126,12 +126,25 @@
 
     def direct_call(hs_f1, *args_hs):
         bookkeeper = getbookkeeper()
-        graph = hs_f1.const._obj.graph
-        hs_res = bookkeeper.annotator.recursivecall(graph, bookkeeper.position_key, args_hs)
+        fnobj = hs_f1.const._obj
+        if (getattr(bookkeeper.annotator.policy, 'oopspec', False) and
+            hasattr(fnobj._callable, 'oopspec')):
+            # try to handle the call as a high-level operation
+            try:
+                return handle_highlevel_operation(bookkeeper, fnobj._callable,
+                                                  *args_hs)
+            except NotImplementedError:
+                pass
+        # normal call
+        if not hasattr(fnobj, 'graph'):
+            raise NotImplementedError("XXX call to externals or primitives")
+        hs_res = bookkeeper.annotator.recursivecall(fnobj.graph,
+                                                    bookkeeper.position_key,
+                                                    args_hs)
         if isinstance(hs_res, SomeLLAbstractValue):
-            return hs_res.reorigin(bookkeeper)
-        else:
-            return hs_res # impossible value
+            hs_res = hs_res.reorigin(bookkeeper)
+        #else: it's a SomeImpossibleValue
+        return hs_res
 
     def int_neg(hs_c1):
         origin = getbookkeeper().myorigin()
@@ -248,3 +261,41 @@
 
     def union((hs_cont1, hs_cont2)):
         return SomeLLAbstractContainer(hs_cont1.contentdef.union(hs_cont2.contentdef))
+
+# ____________________________________________________________
+
+def handle_highlevel_operation(bookkeeper, ll_func, *args_hs):
+    # parse the oopspec and fill in the arguments
+    operation_name, args = ll_func.oopspec.split('(', 1)
+    assert args.endswith(')')
+    args = args[:-1] + ','     # trailing comma to force tuple syntax
+    argnames = ll_func.func_code.co_varnames[:len(args_hs)]
+    d = dict(zip(argnames, args_hs))
+    argtuple = eval(args, d)
+    args_hs = []
+    for hs in argtuple:
+        if not isinstance(hs, SomeLLAbstractValue):
+            hs = bookkeeper.immutablevalue(hs)
+        args_hs.append(hs)
+    # end of rather XXX'edly hackish parsing
+
+    if operation_name == 'newlist':
+        from pypy.jit.hintvlist import oop_newlist
+        handler = oop_newlist
+    else:
+        # dispatch on the 'self' argument if it is virtual
+        hs_self = args_hs[0]
+        args_hs = args_hs[1:]
+        type_name, operation_name = operation_name.split('.')
+        if not isinstance(hs_self, SomeLLAbstractContainer):
+            raise NotImplementedError
+        if getattr(hs_self.contentdef, 'type_name', None) != type_name:
+            raise NotImplementedError
+        try:
+            handler = getattr(hs_self.contentdef, 'oop_' + operation_name)
+        except AttributeError:
+            bookkeeper.warning('missing handler: oop_%s' % (operation_name,))
+            raise NotImplementedError
+
+    hs_result = handler(*args_hs)   # which may raise NotImplementedError
+    return hs_result

Added: pypy/dist/pypy/jit/hintvlist.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/hintvlist.py	Sun Jan 29 12:53:00 2006
@@ -0,0 +1,72 @@
+from pypy.annotation.listdef import ListItem
+from pypy.jit import hintmodel
+from pypy.jit.hintbookkeeper import getbookkeeper
+from pypy.jit.hintcontainer import AbstractContainerDef, make_item_annotation
+from pypy.rpython.lltypesystem import lltype
+
+class VirtualListDef(AbstractContainerDef):
+    type_name = 'list'
+
+    def __init__(self, bookkeeper, LIST):
+        AbstractContainerDef.__init__(self, bookkeeper, LIST)
+        hs = make_item_annotation(bookkeeper, LIST.ITEM)
+        self.listitem = ListItem(bookkeeper, hs)
+        self.listitem.itemof[self] = True
+
+    def read_item(self):
+        self.listitem.read_locations[self.bookkeeper.position_key] = True
+        return self.listitem.s_value
+
+    def generalize_item(self, hs_value):
+        assert hs_value.concretetype == self.T.ITEM
+        self.listitem.generalize(hs_value)
+
+    # ________________________________________
+    # OOP high-level operations
+
+    def oop_len(self):
+        origin = getbookkeeper().myorigin()
+        return hintmodel.SomeLLAbstractConstant(lltype.Signed, {origin: True})
+
+    def oop_nonzero(self):
+        origin = getbookkeeper().myorigin()
+        return hintmodel.SomeLLAbstractConstant(lltype.Bool, {origin: True})
+
+    def oop_getitem(self, hs_index):
+        assert hs_index.concretetype == lltype.Signed
+        return self.read_item()
+
+    def oop_setitem(self, hs_index, hs_value):
+        assert hs_index.concretetype == lltype.Signed
+        self.generalize_item(hs_value)
+
+    def oop_delitem(self, hs_index):
+        assert hs_index.concretetype == lltype.Signed
+
+    def oop_append(self, hs_value):
+        self.generalize_item(hs_value)
+
+    def oop_insert(self, hs_index, hs_value):
+        assert hs_index.concretetype == lltype.Signed
+        self.generalize_item(hs_value)
+
+    def oop_pop(self, hs_index=None):
+        assert hs_index is None or hs_index.concretetype == lltype.Signed
+        return self.read_item()
+
+    def oop_reverse(self):
+        pass
+
+    def oop_copy(self):
+        XXX
+
+    def oop_concat(self, hs_other):
+        XXX
+
+# ____________________________________________________________
+
+def oop_newlist(hs_numitems, hs_item=None):
+    bk = getbookkeeper()
+    LIST = bk.current_op_concretetype().TO
+    vlistdef = bk.getvirtualcontainerdef(LIST, VirtualListDef)
+    return hintmodel.SomeLLAbstractContainer(vlistdef)

Modified: pypy/dist/pypy/jit/test/test_hint_annotation.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_hint_annotation.py	(original)
+++ pypy/dist/pypy/jit/test/test_hint_annotation.py	Sun Jan 29 12:53:00 2006
@@ -6,8 +6,12 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.objectmodel import hint
 from pypy.annotation import model as annmodel
+from pypy.annotation.policy import AnnotatorPolicy
 
-def hannotate(func, argtypes):
+P_OOPSPEC = AnnotatorPolicy()
+P_OOPSPEC.oopspec = True
+
+def hannotate(func, argtypes, policy=None):
     # build the normal ll graphs for ll_function
     t = TranslationContext()
     a = t.buildannotator()
@@ -16,7 +20,7 @@
     rtyper.specialize()
     graph1 = graphof(t, func)
     # build hint annotator types
-    hannotator = HintAnnotator()
+    hannotator = HintAnnotator(policy=policy)
     hs = hannotator.build_graph_types(graph1, [SomeLLAbstractConstant(v.concretetype,
                                                                       {OriginTreeNode(): True})
                                                for v in graph1.getargs()])
@@ -213,6 +217,16 @@
     assert hs.concretetype == lltype.Signed
     assert len(hs.origins) == 1
 
+def test_simple_list_operations():
+    def ll_function(x, y, index):
+        l = [x]
+        l.append(y)
+        return l[index]
+    hs = hannotate(ll_function, [int, int, int], policy=P_OOPSPEC)
+    assert isinstance(hs, SomeLLAbstractConstant)
+    assert hs.concretetype == lltype.Signed
+    assert len(hs.origins) == 2
+
 def test_simple_cast_pointer():
     GCS1 = lltype.GcStruct('s1', ('x', lltype.Signed))
     GCS2 = lltype.GcStruct('s2', ('sub', GCS1), ('y', lltype.Signed))



More information about the Pypy-commit mailing list