[pypy-svn] r74970 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test
arigo at codespeak.net
arigo at codespeak.net
Mon May 31 15:26:45 CEST 2010
Author: arigo
Date: Mon May 31 15:26:44 2010
New Revision: 74970
Modified:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
Log:
Test and fix.
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py Mon May 31 15:26:44 2010
@@ -137,8 +137,10 @@
self.emitline("---")
def make_link(self, link):
- if link.target.exits == ():
- self.make_return(link.args)
+ if (link.target.exits == ()
+ and link.last_exception not in link.args
+ and link.last_exc_value not in link.args):
+ self.make_return(link.args) # optimization only
return
self.insert_renamings(link)
self.make_bytecode_block(link.target)
@@ -154,12 +156,6 @@
self.emitline("reraise")
self.emitline("---")
return # done
- if link.last_exception in link.args:
- self.emitline("last_exception",
- "->", self.getcolor(link.last_exception))
- if link.last_exc_value in link.args:
- self.emitline("last_exc_value",
- "->", self.getcolor(link.last_exc_value))
self.make_link(link)
def insert_exits(self, block):
@@ -298,7 +294,8 @@
renamings = {}
lst = [(self.getcolor(v), self.getcolor(link.target.inputargs[i]))
for i, v in enumerate(link.args)
- if v.concretetype is not lltype.Void]
+ if v.concretetype is not lltype.Void and
+ v not in (link.last_exception, link.last_exc_value)]
lst.sort(key=lambda(v, w): w.index)
for v, w in lst:
if v == w:
@@ -321,6 +318,17 @@
self.emitline('%s_pop' % kind, "->", w)
else:
self.emitline('%s_copy' % kind, v, "->", w)
+ self.generate_last_exc(link, link.target.inputargs)
+
+ def generate_last_exc(self, link, inputargs):
+ # Write 'last_exc_xxx' operations that load the last exception
+ # directly into the locations specified by 'inputargs'. This
+ # must be done at the end of the link renamings.
+ for v, w in zip(link.args, inputargs):
+ if v is link.last_exception:
+ self.emitline("last_exception", "->", self.getcolor(w))
+ if v is link.last_exc_value:
+ self.emitline("last_exc_value", "->", self.getcolor(w))
def emitline(self, *line):
self.ssarepr.insns.append(line)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py Mon May 31 15:26:44 2010
@@ -372,8 +372,7 @@
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
last_exc_value -> %r0
- ref_copy %r0 -> %r1
- getfield_gc_i %r1, <Descr> -> %i1
+ getfield_gc_i %r0, <Descr> -> %i1
int_return %i1
---
L2:
@@ -431,13 +430,11 @@
void_return
---
L1:
- last_exception -> %i1
last_exc_value -> %r0
- int_copy %i1 -> %i2
- ref_copy %r0 -> %r1
+ last_exception -> %i1
setfield_gc_i $<* struct test.Foo>, <Descr>, $5
-live-
- raise %r1
+ raise %r0
""", transform=True)
def test_goto_if_not_int_is_true(self):
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py Mon May 31 15:26:44 2010
@@ -2,11 +2,12 @@
from pypy.jit.codewriter import support
from pypy.jit.codewriter.regalloc import perform_register_allocation
from pypy.jit.codewriter.flatten import flatten_graph, ListOfKind
-from pypy.jit.codewriter.format import format_assembler
+from pypy.jit.codewriter.format import assert_format
+from pypy.jit.metainterp.history import AbstractDescr
from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
from pypy.objspace.flow.model import FunctionGraph, Block, Link
from pypy.objspace.flow.model import c_last_exception
-from pypy.rpython.lltypesystem import lltype, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rlib.objectmodel import keepalive_until_here
@@ -17,17 +18,19 @@
self.rtyper = support.annotate(func, values, type_system=type_system)
return self.rtyper.annotator.translator.graphs
- def check_assembler(self, graph, expected, transform=False):
+ def check_assembler(self, graph, expected, transform=False,
+ callcontrol=None):
# 'transform' can be False only for simple graphs. More complex
# graphs must first be transformed by jtransform.py before they can be
# subjected to register allocation and flattening.
if transform:
from pypy.jit.codewriter.jtransform import transform_graph
- transform_graph(graph)
+ transform_graph(graph, callcontrol=callcontrol)
regalloc = perform_register_allocation(graph, 'int')
- ssarepr = flatten_graph(graph, {'int': regalloc})
- asm = format_assembler(ssarepr)
- assert asm == str(py.code.Source(expected).strip()) + '\n'
+ regalloc2 = perform_register_allocation(graph, 'ref')
+ ssarepr = flatten_graph(graph, {'int': regalloc,
+ 'ref': regalloc2})
+ assert_format(ssarepr, expected)
def test_regalloc_simple(self):
def f(a, b):
@@ -240,3 +243,61 @@
L1:
int_return %i2
""", transform=True)
+
+ def test_regalloc_bug_2(self):
+ class FakeDescr(AbstractDescr):
+ def __repr__(self):
+ return '<Descr>'
+ class FakeCallControl:
+ def guess_call_kind(self, op):
+ return 'residual'
+ def getcalldescr(self, op):
+ return FakeDescr()
+ def calldescr_canraise(self, calldescr):
+ return True
+ class FooError(Exception):
+ def __init__(self, num):
+ self.num = num
+ def g(n):
+ if n > 100:
+ raise FooError(n)
+ return lltype.nullptr(llmemory.GCREF.TO)
+ def foo(e):
+ print "hello"
+ return e
+ def bar(e):
+ print "world"
+ return e
+ def f(n, kref):
+ kref2 = bar(kref)
+ try:
+ return g(n)
+ except FooError, e:
+ if foo(e):
+ return kref
+ else:
+ return kref2
+ graph = self.make_graphs(f, [5, lltype.nullptr(llmemory.GCREF.TO)])[0]
+ # this used to produce bogus code, containing these two
+ # lines in the following broken order:
+ # last_exc_value -> %r0
+ # ref_copy %r0 -> %r2 -- but expect to read the old value of %r0!
+ self.check_assembler(graph, """
+ residual_call_r_r $<* fn bar>, <Descr>, R[%r0] -> %r1
+ -live-
+ residual_call_ir_r $<* fn g>, <Descr>, I[%i0], R[] -> %r2
+ -live-
+ catch_exception L1
+ ref_return %r2
+ ---
+ L1:
+ goto_if_exception_mismatch $<* struct object_vtable>, L2
+ ref_copy %r0 -> %r2
+ last_exc_value -> %r0
+ residual_call_r_r $<* fn foo>, <Descr>, R[%r0] -> %r0
+ -live-
+ ref_return %r2
+ ---
+ L2:
+ reraise
+ """, transform=True, callcontrol=FakeCallControl())
More information about the Pypy-commit
mailing list