[pypy-svn] r29367 - in pypy/dist/pypy: objspace/flow rpython/lltypesystem rpython/lltypesystem/test translator/backendopt translator/backendopt/test

arigo at codespeak.net arigo at codespeak.net
Mon Jun 26 18:02:20 CEST 2006


Author: arigo
Date: Mon Jun 26 18:02:17 2006
New Revision: 29367

Modified:
   pypy/dist/pypy/objspace/flow/model.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/rtagged.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py
   pypy/dist/pypy/translator/backendopt/constfold.py
   pypy/dist/pypy/translator/backendopt/test/test_constfold.py
Log:
* an optimization in rtagged that avoids some tag-checking in cases
  where we know that the instance cannot be of the special tag class.
  Fixes a problem with constfold.py.

* turn hard folding errors into warnings in constfold.py.

* raise RuntimeError instead of TypeError in a cast situation in lltype
  that is not really a static typing error.

* move a test helper, summary(graph) -> {'opname': count}, into
  objspace/flow/model.py.



Modified: pypy/dist/pypy/objspace/flow/model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/model.py	(original)
+++ pypy/dist/pypy/objspace/flow/model.py	Mon Jun 26 18:02:17 2006
@@ -648,3 +648,12 @@
         if block and not hasattr(e, '__annotator_block'):
             setattr(e, '__annotator_block', block)
         raise
+
+def summary(graph):
+    # return a summary of the instructions found in a graph
+    insns = {}
+    for block in graph.iterblocks():
+        for op in block.operations:
+            if op.opname != 'same_as':
+                insns[op.opname] = insns.get(op.opname, 0) + 1
+    return insns

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Mon Jun 26 18:02:17 2006
@@ -1059,7 +1059,7 @@
             struc = parent
             u -= 1
         if PARENTTYPE != PTRTYPE.TO:
-            raise TypeError("widening %r inside %r instead of %r" % (CURTYPE, PARENTTYPE, PTRTYPE.TO))
+            raise RuntimeError("widening %r inside %r instead of %r" % (CURTYPE, PARENTTYPE, PTRTYPE.TO))
         return _ptr(PTRTYPE, struc, solid=self._solid)
 
     def _cast_to_int(self):

Modified: pypy/dist/pypy/rpython/lltypesystem/rtagged.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rtagged.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rtagged.py	Mon Jun 26 18:02:17 2006
@@ -1,5 +1,5 @@
 from pypy.objspace.flow.model import Constant
-from pypy.rpython.rclass import getclassrepr, get_type_repr
+from pypy.rpython.rclass import getclassrepr, getinstancerepr, get_type_repr
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.lltypesystem.rclass import InstanceRepr, CLASSTYPE
 from pypy.rpython.lltypesystem.rclass import MissingRTypeAttribute
@@ -66,9 +66,27 @@
         unboxedclass_repr = getclassrepr(self.rtyper, self.unboxedclassdef)
         cunboxedcls = inputconst(CLASSTYPE, unboxedclass_repr.getvtable())
         if self.is_parent:
+            # If the lltype of vinst shows that it cannot be a tagged value,
+            # we can directly read the typeptr.  Otherwise, call a helper that
+            # checks if the tag bit is set in the pointer.
+            unboxedinstance_repr = getinstancerepr(self.rtyper,
+                                                   self.unboxedclassdef)
+            try:
+                lltype.castable(unboxedinstance_repr.lowleveltype,
+                                vinst.concretetype)
+            except lltype.InvalidCast:
+                can_be_tagged = False
+            else:
+                can_be_tagged = True
             vinst = llops.genop('cast_pointer', [vinst],
                                 resulttype=self.common_repr())
-            return llops.gendirectcall(ll_unboxed_getclass, vinst, cunboxedcls)
+            if can_be_tagged:
+                return llops.gendirectcall(ll_unboxed_getclass, vinst,
+                                           cunboxedcls)
+            else:
+                ctypeptr = inputconst(lltype.Void, 'typeptr')
+                return llops.genop('getfield', [vinst, ctypeptr],
+                                   resulttype = CLASSTYPE)
         else:
             return cunboxedcls
 

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	Mon Jun 26 18:02:17 2006
@@ -148,7 +148,7 @@
     S1bis = Struct("s1b", ('sub1', S2))
     p1b = malloc(S1bis, immortal=True)
     p2 = p1b.sub1
-    py.test.raises(TypeError, "cast_pointer(Ptr(S1), p2)")
+    py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p2)")
 
 def test_cast_simple_widening2():
     S2 = GcStruct("s2", ('a', Signed))
@@ -199,7 +199,7 @@
     p3 = p1b.sub.sub
     assert typeOf(p3) == Ptr(S3)
     assert p1b == cast_pointer(Ptr(S1bis), p3)
-    py.test.raises(TypeError, "cast_pointer(Ptr(S1), p3)")
+    py.test.raises(RuntimeError, "cast_pointer(Ptr(S1), p3)")
 
 def test_best_effort_gced_parent_detection():
     S2 = Struct("s2", ('a', Signed))

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rtagged.py	Mon Jun 26 18:02:17 2006
@@ -2,6 +2,8 @@
 from pypy.rpython.test.test_llinterp import interpret, get_interpreter
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.objectmodel import UnboxedValue
+from pypy.translator.translator import graphof
+from pypy.objspace.flow.model import summary
 from pypy.translator.backendopt.all import backend_optimizations
 from pypy import conftest
 
@@ -11,6 +13,7 @@
         raise NotImplementedError
 
 class B(A):
+    attrvalue = 66
     def __init__(self, normalint):
         self.normalint = normalint
     def meth(self, x):
@@ -21,6 +24,9 @@
     def meth(self, x):
         return self.smallint + x + 3
 
+class D(B):
+    attrvalue = 68
+
 # ____________________________________________________________
 
 def test_instantiate():
@@ -174,3 +180,25 @@
     interp.frame_class = MyFrame
     res = interp.eval_graph(graph, [-1000])
     assert res == -897
+
+def test_untagged_subclasses():
+    def g(x):
+        return x.attrvalue   # should not produce a call to ll_unboxed_getclass
+    def fn(n):
+        y = C(12)
+        if n > 0:
+            x = B(5)
+        else:
+            x = D(5)
+        return g(x)
+
+    interp, graph = get_interpreter(fn, [-1000])
+
+    t = interp.typer.annotator.translator
+    ggraph = graphof(t, g)
+    assert summary(ggraph) == {'cast_pointer': 2, 'getfield': 2}
+
+    res = interp.eval_graph(graph, [-1000])
+    assert res == 68
+    res = interp.eval_graph(graph, [3])
+    assert res == 66

Modified: pypy/dist/pypy/translator/backendopt/constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/constfold.py	Mon Jun 26 18:02:17 2006
@@ -1,5 +1,6 @@
 from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
 from pypy.translator.backendopt.support import split_block_with_keepalive
+from pypy.translator.backendopt.support import log
 from pypy.translator.simplify import eliminate_empty_blocks
 from pypy.translator.unsimplify import insert_empty_block
 from pypy.rpython.lltypesystem.lloperation import llop
@@ -33,6 +34,11 @@
                     result = op(RESTYPE, *args)
                 except TypeError:
                     pass
+                except (KeyboardInterrupt, SystemExit):
+                    raise
+                except Exception, e:
+                    log.WARNING('constant-folding %r:' % (spaceop,))
+                    log.WARNING('  %s: %s' % (e.__class__.__name__, e))
                 else:
                     # success in folding this space operation
                     constants[spaceop.result] = Constant(result, RESTYPE)

Modified: pypy/dist/pypy/translator/backendopt/test/test_constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_constfold.py	Mon Jun 26 18:02:17 2006
@@ -1,4 +1,4 @@
-from pypy.objspace.flow.model import checkgraph, Constant
+from pypy.objspace.flow.model import checkgraph, Constant, summary
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.rpython.lltypesystem import lltype
@@ -22,15 +22,6 @@
     res = interp.eval_graph(graph, args)
     assert res == expected_result
 
-def summary(graph):
-    # return a summary of the instructions left in a graph
-    insns = {}
-    for block in graph.iterblocks():
-        for op in block.operations:
-            if op.opname != 'same_as':
-                insns[op.opname] = insns.get(op.opname, 0) + 1
-    return insns
-
 
 def test_simple():
     S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})



More information about the Pypy-commit mailing list