[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