[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