[pypy-svn] r44474 - in pypy/dist/pypy: objspace/flow translator/backendopt translator/backendopt/test

antocuni at codespeak.net antocuni at codespeak.net
Sat Jun 23 16:41:44 CEST 2007


Author: antocuni
Date: Sat Jun 23 16:41:43 2007
New Revision: 44474

Modified:
   pypy/dist/pypy/objspace/flow/model.py
   pypy/dist/pypy/translator/backendopt/inline.py
   pypy/dist/pypy/translator/backendopt/test/test_inline.py
Log:
- add a comment for the new check in checkgraph

- add a new test that really showed the problem

- fix it by inserting an ooupcast when needed



Modified: pypy/dist/pypy/objspace/flow/model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/model.py	(original)
+++ pypy/dist/pypy/objspace/flow/model.py	Sat Jun 23 16:41:43 2007
@@ -663,9 +663,15 @@
             for link in block.exits:
                 assert len(link.args) == len(link.target.inputargs)
                 assert link.prevblock is block
+
+                # checking for exact types is not strictly necessary
+                # for ootype, because upcasting could be implicit, but
+                # forcing them to be explicit makes the life of other
+                # parts of the toolchain much easier
                 for linkv, inputv in zip(link.args, link.target.inputargs):
                     if hasattr(linkv, 'concretetype') and hasattr(inputv, 'concretetype'):
                         assert linkv.concretetype == inputv.concretetype
+
                 exc_link = link in exc_links
                 if exc_link:
                     for v in [link.last_exception, link.last_exc_value]:

Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py	(original)
+++ pypy/dist/pypy/translator/backendopt/inline.py	Sat Jun 23 16:41:43 2007
@@ -431,7 +431,6 @@
         copiedexceptblock.recloseblock(Link(linkargs, blocks[0]))
         copiedexceptblock.operations += self.generate_keepalive(linkargs)
 
-      
     def do_inline(self, block, index_operation):
         splitlink = split_block_with_keepalive(block, index_operation)
         afterblock = splitlink.target
@@ -460,6 +459,23 @@
                 index = afterblock.inputargs.index(arg)
                 passon_args.append(linktoinlined.args[index])
         passon_args += self.original_passon_vars
+
+        if self.op.opname == 'oosend' and not isinstance(self.op.args[1], Constant):
+            # if we try to inline a graph defined in a superclass, the
+            # type of 'self' on the graph differs from the current
+            linkv = passon_args[0]
+            inputv = copiedstartblock.inputargs[0]
+            LINK_SELF = linkv.concretetype
+            INPUT_SELF = inputv.concretetype
+            if LINK_SELF != INPUT_SELF:
+                # need to insert an upcast
+                assert ootype.isSubclass(LINK_SELF, INPUT_SELF)
+                v = Variable()
+                v.concretetype = INPUT_SELF
+                upcast = SpaceOperation('ooupcast', [linkv], v)
+                block.operations.append(upcast)
+                passon_args[0] = v
+
         #rewire blocks
         linktoinlined.target = copiedstartblock
         linktoinlined.args = passon_args

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	Sat Jun 23 16:41:43 2007
@@ -17,7 +17,7 @@
 from pypy.translator.test.snippet import is_perfect_number
 from pypy.translator.backendopt.all import INLINE_THRESHOLD_FOR_TEST
 from pypy.conftest import option
-
+from pypy.translator.backendopt import removenoops
 
 def no_missing_concretetype(node):
     if isinstance(node, Block):
@@ -87,7 +87,7 @@
         return eval_func
 
     def check_auto_inlining(self, func, sig, multiplier=None, call_count_check=False,
-                            checkvirtual=False):
+                            checkvirtual=False, remove_same_as=False):
         t = self.translate(func, sig)
         if checkvirtual:
             check_virtual_methods()
@@ -105,6 +105,10 @@
             call_count_pred = lambda lbl: True
             instrument_inline_candidates(t.graphs, threshold)
 
+        if remove_same_as:
+            for graph in t.graphs:
+                removenoops.remove_same_as(graph)
+            
         auto_inlining(t, threshold, call_count_pred=call_count_pred)
 
         sanity_check(t)
@@ -639,25 +643,41 @@
         assert res == expected
 
     def test_oosend_inherited(self):
-        py.test.skip('fixme, this prevents pypy-cli from being built')
-        class A:
-            def bar(self, x):
-                return x
-        class B(A):
-            def foo(self, x):
-                return self.bar(x)
-        class C(A):
+        class BaseStringFormatter:
+            def __init__(self):
+                self.fmtpos = 0
+            def forward(self):
+                self.fmtpos += 1
+
+        class StringFormatter(BaseStringFormatter):
+            def __init__(self, fmt):
+                BaseStringFormatter.__init__(self)
+                self.fmt = fmt
+            def peekchr(self):
+                return self.fmt[self.fmtpos]
+            def peel_num(self):
+                while True:
+                    self.forward()
+                    c = self.peekchr()
+                    if self.fmtpos == 2: break
+                return 0
+
+        class UnicodeStringFormatter(BaseStringFormatter):
             pass
+        
         def fn(x):
             if x:
-                b_obj = B()
-                return b_obj.foo(x)
+                fmt = StringFormatter('foo')
+                return fmt.peel_num()
             else:
-                c_obj = C()
-                return c_obj.bar(x)
-        eval_func, t = self.check_auto_inlining(fn, [int], checkvirtual=True)
-        expected = fn(42)
-        res = eval_func([42])
+                dummy = UnicodeStringFormatter()
+                dummy.forward()
+                return 0
+
+        eval_func, t = self.check_auto_inlining(fn, [int], checkvirtual=True,
+                                                remove_same_as=True)
+        expected = fn(1)
+        res = eval_func([1])
         assert res == expected
 
     def test_classattr(self):



More information about the Pypy-commit mailing list