[pypy-svn] r74108 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Apr 27 13:50:02 CEST 2010
Author: arigo
Date: Tue Apr 27 13:50:00 2010
New Revision: 74108
Modified:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/regalloc.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
Log:
Tests and fixes. Also generate "try_catch" just before the
instruction that can actually raise, instead of just after.
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 Tue Apr 27 13:50:00 2010
@@ -116,7 +116,7 @@
self.emitline("%s_return" % kind, self.getcolor(args[0]))
elif len(args) == 2:
# exception block, raising an exception from a function
- xxx
+ self.emitline("raise", self.getcolor(args[1]))
else:
raise Exception("?")
@@ -145,6 +145,35 @@
assert link.exitcase is None
self.make_link(link)
#
+ elif block.exitswitch is c_last_exception:
+ # An exception block. See test_exc_exitswitch in test_flatten.py
+ # for an example of what kind of code this makes.
+ assert block.exits[0].exitcase is None # is this always True?
+ self.emitlinebefore('_call', 'try_catch', TLabel(block.exits[0]))
+ self.make_link(block.exits[0])
+ self.emitline(Label(block.exits[0]))
+ for link in block.exits[1:]:
+ if link.exitcase is Exception:
+ # this link captures all exceptions
+ if (link.target.operations == ()
+ and link.args == [link.last_exception,
+ link.last_exc_value]):
+ # the link is going directly to the except block
+ self.emitline("reraise")
+ else:
+ self.make_exception_link(link)
+ break
+ self.emitline('goto_if_exception_mismatch',
+ Constant(link.llexitcase,
+ lltype.typeOf(link.llexitcase)),
+ TLabel(link))
+ self.make_exception_link(link)
+ self.emitline(Label(link))
+ else:
+ # no link captures all exceptions, so we have to put a reraise
+ # for the other exceptions
+ self.emitline("reraise")
+ #
elif len(block.exits) == 2 and (
isinstance(block.exitswitch, tuple) or
block.exitswitch.concretetype == lltype.Bool):
@@ -169,39 +198,6 @@
self.emitline(Label(linkfalse))
self.make_link(linkfalse)
#
- elif block.exitswitch is c_last_exception:
- # An exception block. Would create something like:
- # if exception jump first check
- # defaultcase
- # if not exc_1 jmp next check
- # exc_1 case
- # if not exc_2 jmp next check
- # exc_2 case
- # reraise
- assert block.exits[0].exitcase is None # is this always True?
- self.emitline('catch', TLabel(block.exits[0]))
- self.make_link(block.exits[0])
- self.emitline(Label(block.exits[0]))
- for link in block.exits[1:]:
- if link.exitcase is Exception:
- # this link captures all exceptions
- if (link.target.operations == ()
- and len(link.target.inputargs) == 2):
- # the link is going directly to the except block
- self.emitline("reraise")
- else:
- self.make_exception_link(link)
- break
- self.emitline('goto_if_exception_mismatch',
- Constant(link.llexitcase,
- lltype.typeOf(link.llexitcase)),
- TLabel(link))
- self.make_exception_link(link)
- self.emitline(Label(link))
- else:
- # no link captures all exceptions, so we have to put a reraise
- # for the other exceptions
- self.emitline("reraise")
else:
# A switch.
#
@@ -278,6 +274,13 @@
def emitline(self, *line):
self.ssarepr.insns.append(line)
+ def emitlinebefore(self, name_extract, *line):
+ assert name_extract in self.ssarepr.insns[-1][0], (
+ "emitlinebefore: the %s operation should be inserted before %s,"
+ " but it does not look like a %r operation" % (
+ line, self.ssarepr.insns[-1], name_extract))
+ self.ssarepr.insns.insert(-1, line)
+
def flatten_list(self, arglist):
args = []
for v in arglist:
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/regalloc.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/regalloc.py Tue Apr 27 13:50:00 2010
@@ -83,6 +83,10 @@
# than the start, given that we resume execution from the
# middle during blackholing.
for link in block.exits:
+ if link.last_exception is not None:
+ self._depgraph.add_node(link.last_exception)
+ if link.last_exc_value is not None:
+ self._depgraph.add_node(link.last_exc_value)
for i, v in enumerate(link.args):
self._try_coalesce(v, link.target.inputargs[i])
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 Tue Apr 27 13:50:00 2010
@@ -243,8 +243,8 @@
return 3
self.encoding_test(f, [65], """
+ try_catch L1
direct_call $<* fn g>, %i0
- catch L1
int_return $3
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
@@ -273,8 +273,8 @@
return 4
self.encoding_test(f, [65], """
+ try_catch L1
residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
- catch L1
int_return $4
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
@@ -285,3 +285,31 @@
L2:
int_return $3
""", transform=True)
+
+ def test_exc_raise_1(self):
+ class FooError(Exception):
+ pass
+ fooerror = FooError()
+ def f(i):
+ raise fooerror
+
+ self.encoding_test(f, [65], """
+ raise $<* struct object>
+ """)
+
+ def test_exc_raise_2(self):
+ def g(i):
+ pass
+ def f(i):
+ try:
+ g(i)
+ except Exception:
+ raise KeyError
+
+ self.encoding_test(f, [65], """
+ try_catch L1
+ direct_call $<* fn g>, %i0
+ void_return
+ L1:
+ raise $<* struct object>
+ """)
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 Tue Apr 27 13:50:00 2010
@@ -5,7 +5,8 @@
from pypy.jit.codewriter.format import format_assembler
from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
from pypy.objspace.flow.model import FunctionGraph, Block, Link
-from pypy.rpython.lltypesystem import lltype
+from pypy.objspace.flow.model import c_last_exception
+from pypy.rpython.lltypesystem import lltype, rclass
class TestRegAlloc:
@@ -145,3 +146,33 @@
rescall I[%i0, %i1], %i0
int_return %i0
""")
+
+ def test_regalloc_exitswitch_2(self):
+ v1 = Variable(); v1.concretetype = rclass.CLASSTYPE
+ v2 = Variable(); v2.concretetype = rclass.CLASSTYPE
+ v3 = Variable(); v3.concretetype = rclass.CLASSTYPE
+ v4 = Variable(); v4.concretetype = rclass.CLASSTYPE
+ block = Block([])
+ block.operations = [
+ SpaceOperation('res_call', [], v1),
+ ]
+ graph = FunctionGraph('f', block, v4)
+ exclink = Link([v2], graph.returnblock)
+ exclink.llexitcase = 123 # normally an exception class
+ exclink.last_exception = v2
+ exclink.last_exc_value = "unused"
+ block.exitswitch = c_last_exception
+ block.closeblock(Link([v1], graph.returnblock),
+ exclink)
+ #
+ self.check_assembler(graph, """
+ try_catch L1
+ res_call %i0
+ int_return %i0
+ L1:
+ goto_if_exception_mismatch $123, L2
+ last_exception %i0
+ int_return %i0
+ L2:
+ reraise
+ """)
More information about the Pypy-commit
mailing list