[pypy-svn] r36621 - in pypy/dist/pypy/translator: . backendopt backendopt/test cli

antocuni at codespeak.net antocuni at codespeak.net
Fri Jan 12 21:21:56 CET 2007


Author: antocuni
Date: Fri Jan 12 21:21:49 2007
New Revision: 36621

Added:
   pypy/dist/pypy/translator/backendopt/checkvirtual.py   (contents, props changed)
   pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/cli/cts.py
   pypy/dist/pypy/translator/driver.py
Log:
the check_virtual_method backendopt allow backends to statically
dispatch some oosends that else would be dispatched at runtime. It
gives about 15% speedup on gencli.



Added: pypy/dist/pypy/translator/backendopt/checkvirtual.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/checkvirtual.py	Fri Jan 12 21:21:49 2007
@@ -0,0 +1,19 @@
+"""
+Visit all known INSTANCEs to see which methods can be marked as
+non-virtual: a method is marked as non-virtual when it's never
+overridden in the subclasses: this means that backends can translate
+oosends relative to that method into non-virtual call (or maybe
+switching back to a direct_call if the backend doesn't support
+non-virtual calls, such as JVM).
+"""
+
+def check_virtual_methods(INSTANCE, super_methods = {}):
+    my_methods = super_methods.copy()
+    for name, method in INSTANCE._methods.iteritems():
+        method._virtual = False
+        my_methods[name] = method
+        if name in super_methods:
+            super_methods[name]._virtual = True
+
+    for SUB_INSTANCE in INSTANCE._subclasses:
+        check_virtual_methods(SUB_INSTANCE, my_methods)

Added: pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py	Fri Jan 12 21:21:49 2007
@@ -0,0 +1,57 @@
+from pypy.rpython.ootypesystem.ootype import ROOT, Instance, \
+     addMethods, meth, Meth, Void
+from pypy.translator.backendopt.checkvirtual import check_virtual_methods
+
+def test_nonvirtual():
+    A = Instance("A", ROOT)
+    addMethods(A, {"foo": meth(Meth([], Void))})
+
+    check_virtual_methods(ROOT)
+    assert A._methods["foo"]._virtual == False
+
+def test_checkvirtual_simple():
+    A = Instance("A", ROOT)
+    B = Instance("B", A)
+
+    addMethods(A, {"foo": meth(Meth([], Void)),
+                   "bar": meth(Meth([], Void))})
+    
+    addMethods(B, {"foo": meth(Meth([], Void))})
+
+    check_virtual_methods(ROOT)
+    assert A._methods["foo"]._virtual == True
+    assert A._methods["bar"]._virtual == False
+    assert B._methods["foo"]._virtual == False
+
+def test_checkvirtual_deep():
+    A = Instance("A", ROOT)
+    B = Instance("B", A)
+    C = Instance("C", B)
+
+    addMethods(A, {"foo": meth(Meth([], Void)),
+                   "bar": meth(Meth([], Void))})
+    
+    addMethods(C, {"foo": meth(Meth([], Void))})
+
+    check_virtual_methods(ROOT)
+    assert A._methods["foo"]._virtual == True
+    assert A._methods["bar"]._virtual == False
+    assert "foo" not in B._methods
+    assert C._methods["foo"]._virtual == False
+
+def test_checkvirtual_brother():
+    A = Instance("A", ROOT)
+    B1 = Instance("B1", A)
+    B2 = Instance("B2", A)
+
+    addMethods(A, {"foo": meth(Meth([], Void)),
+                   "bar": meth(Meth([], Void))})
+    
+    addMethods(B1, {"foo": meth(Meth([], Void))})
+
+    check_virtual_methods(ROOT)
+    assert A._methods["foo"]._virtual == True
+    assert A._methods["bar"]._virtual == False
+    assert B1._methods["foo"]._virtual == False
+    assert "foo" not in B2._methods
+

Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py	(original)
+++ pypy/dist/pypy/translator/cli/cts.py	Fri Jan 12 21:21:49 2007
@@ -227,16 +227,18 @@
             if isinstance(name_or_desc, ootype._overloaded_meth_desc):
                 name = name_or_desc.name
                 METH = name_or_desc.TYPE
+                virtual = True
             else:
                 name = name_or_desc
                 owner, meth = TYPE._lookup(name)
                 METH = meth._TYPE
+                virtual = getattr(meth, '_virtual', True)
             class_name = self.db.class_name(TYPE)
             full_name = 'class %s::%s' % (class_name, name)
             returntype = self.lltype_to_cts(METH.RESULT)
             arg_types = [self.lltype_to_cts(ARG) for ARG in METH.ARGS if ARG is not ootype.Void]
             arg_list = ', '.join(arg_types)
-            return '%s %s(%s)' % (returntype, full_name, arg_list), True
+            return '%s %s(%s)' % (returntype, full_name, arg_list), virtual
 
         elif isinstance(TYPE, (ootype.BuiltinType, ootype.StaticMethod)):
             assert isinstance(name_or_desc, str)

Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py	(original)
+++ pypy/dist/pypy/translator/driver.py	Fri Jan 12 21:21:49 2007
@@ -355,6 +355,9 @@
             heap2stack=False,
             clever_malloc_removal=False)
         if self.config.translation.backend == 'cli':
+            from pypy.translator.backendopt.checkvirtual import check_virtual_methods
+            from pypy.rpython.ootypesystem import ootype
+            check_virtual_methods(ootype.ROOT)
             opt['merge_if_blocks'] = True
             opt['inline_threshold'] = 1
             opt['mallocs'] = True



More information about the Pypy-commit mailing list