[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