[pypy-svn] r40028 - in pypy/dist/pypy: rpython/ootypesystem rpython/ootypesystem/test translator/backendopt translator/backendopt/test

antocuni at codespeak.net antocuni at codespeak.net
Wed Mar 7 14:34:13 CET 2007


Author: antocuni
Date: Wed Mar  7 14:34:11 2007
New Revision: 40028

Modified:
   pypy/dist/pypy/rpython/ootypesystem/ootype.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
   pypy/dist/pypy/translator/backendopt/inline.py
   pypy/dist/pypy/translator/backendopt/test/test_inline.py
Log:
make inline_once aware that most of methods of BuiltinTypes don't
raise exceptions. This allow much more inlining and make
test_list_iteration passing.



Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py	Wed Mar  7 14:34:11 2007
@@ -292,20 +292,23 @@
 
 class BuiltinADTType(BuiltinType):
 
-    def _setup_methods(self, generic_types):
+    def _setup_methods(self, generic_types, can_raise=[]):
         methods = {}
         for name, meth in self._GENERIC_METHODS.iteritems():
             args = [self._specialize_type(arg, generic_types) for arg in meth.ARGS]
             result = self._specialize_type(meth.RESULT, generic_types)
             methods[name] = Meth(args, result)
         self._METHODS = frozendict(methods)
+        self._can_raise = tuple(can_raise)
 
     def _lookup(self, meth_name):
         METH = self._METHODS.get(meth_name)
         meth = None
         if METH is not None:
             cls = self._get_interp_class()
-            meth = _meth(METH, _name=meth_name, _callable=getattr(cls, meth_name))
+            can_raise = meth_name in self._can_raise
+            meth = _meth(METH, _name=meth_name, _callable=getattr(cls, meth_name), _can_raise=can_raise)
+            meth._virtual = False
         return self, meth
 
 
@@ -600,8 +603,7 @@
             "ll_current_key": Meth([], self.KEYTYPE_T),
             "ll_current_value": Meth([], self.VALUETYPE_T),
         })
-
-        self._setup_methods(generic_types)
+        self._setup_methods(generic_types, can_raise=['ll_go_next'])
 
     def __str__(self):
         return '%s%s' % (self.__class__.__name__,

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py	Wed Mar  7 14:34:11 2007
@@ -443,3 +443,11 @@
     assert not B._subclasses
     assert C in A._subclasses
     assert D in C._subclasses
+
+def test_canraise():
+    LT = List(Signed)
+    _, meth = LT._lookup('ll_length')
+    assert meth._can_raise == False
+    DT = DictItemsIterator(String, Signed)
+    _, meth = DT._lookup('ll_go_next')
+    assert meth._can_raise == True

Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py	(original)
+++ pypy/dist/pypy/translator/backendopt/inline.py	Wed Mar  7 14:34:11 2007
@@ -30,7 +30,11 @@
     else:
         return meth
 
-def collect_called_graphs(graph, translator):
+class CanRaise:
+    def __init__(self, can_raise):
+        self.can_raise = can_raise
+
+def collect_called_graphs(graph, translator, include_oosend=True):
     graphs_or_something = {}
     for block in graph.iterblocks():
         for op in block.operations:
@@ -47,9 +51,14 @@
                 else:
                     for graph in graphs:
                         graphs_or_something[graph] = True
-            if op.opname == 'oosend':
+            if op.opname == 'oosend' and include_oosend:
                 meth = get_meth_from_oosend(op)
-                key = getattr(meth, 'graph', op.args[0])
+                if hasattr(meth, 'graph'):
+                    key = meth.graph
+                elif hasattr(meth, '_can_raise'):
+                    key = CanRaise(meth._can_raise)
+                else:
+                    key = op.args[0]
                 graphs_or_something[key] = True
     return graphs_or_something
 
@@ -144,11 +153,15 @@
     return False
 
 def any_call_to_raising_graphs(from_graph, translator, raise_analyzer):
-    for graph in collect_called_graphs(from_graph, translator):
-        if not isinstance(graph, FunctionGraph):
-            return True     # conservatively
-        if does_raise_directly(graph, raise_analyzer):
-            return True
+    for graph_or_something in collect_called_graphs(from_graph, translator):
+        if isinstance(graph_or_something, FunctionGraph):
+            if does_raise_directly(graph_or_something, raise_analyzer):
+                return True
+        elif isinstance(graph_or_something, CanRaise):
+            if graph_or_something.can_raise:
+                return True
+        else:
+            return True # conservatively
     return False
 
 class BaseInliner(object):
@@ -435,7 +448,7 @@
         assert afterblock.operations[n].opname == self.op.opname
         self.op = afterblock.operations.pop(n)
         #vars that need to be passed through the blocks of the inlined function
-        linktoinlined = splitlink 
+        linktoinlined = splitlink
         copiedstartblock = self.copy_block(self.graph_to_inline.startblock)
         copiedstartblock.isstartblock = False
         #find args passed to startblock of inlined function

Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_inline.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_inline.py	Wed Mar  7 14:34:11 2007
@@ -519,9 +519,10 @@
                 tot += item
             return tot
 
-        eval_func, t = self.check_auto_inlining(f, [])
+        eval_func, t = self.check_auto_inlining(f, [], checkvirtual=True)
         f_graph = graphof(t, f)
-        assert len(collect_called_graphs(f_graph, t)) == 0
+        called_graphs = collect_called_graphs(f_graph, t, include_oosend=False)
+        assert len(called_graphs) == 0
 
         result = eval_func([])
         assert result == 6
@@ -649,6 +650,3 @@
         eval_func, t = self.check_auto_inlining(fn5, [], checkvirtual=True)
         res = eval_func([])
         assert res == 42
-
-    def test_list_iteration(self):
-        py.test.skip('fixme!')



More information about the Pypy-commit mailing list