Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: small-unroll-improvements
Changeset: r70507:605961f3e5de
Date: 2014-04-09 16:34 +0200
http://bitbucket.org/pypy/pypy/changeset/605961f3e5de/

Log:    start using generate_guards to implement generalization_of

diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py 
b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
@@ -57,7 +57,7 @@
             info1.position = 0
             info2 = NotVirtualStateInfo(value2)
             info2.position = 0
-            return info1.generalization_of(info2, {}, {})
+            return info1.generalization_of(info2, {}, {}, LLtypeMixin.cpu)
 
         assert isgeneral(OptValue(BoxInt()), OptValue(ConstInt(7)))
         assert not isgeneral(OptValue(ConstInt(7)), OptValue(BoxInt()))
@@ -66,9 +66,10 @@
         nonnull = OptValue(BoxPtr())
         nonnull.make_nonnull(0)
         knownclass = OptValue(BoxPtr())
-        knownclass.make_constant_class(ConstPtr(self.someptr1), 0)
+        clsbox = LLtypeMixin.cpu.ts.cls_of_box(BoxPtr(LLtypeMixin.myptr))
+        knownclass.make_constant_class(clsbox, 0)
         const = OptValue(BoxPtr)
-        const.make_constant_class(ConstPtr(self.someptr1), 0)
+        const.make_constant_class(clsbox, 0)
         const.make_constant(ConstPtr(self.someptr1))
         inorder = [ptr, nonnull, knownclass, const]
         for i in range(len(inorder)):
@@ -179,12 +180,14 @@
 
     def check_no_guards(self, info1, info2, box_or_value=None):
         value, _ = self._box_or_value(box_or_value)
+        info1.position = info2.position = 0
         guards = []
         info1.generate_guards(info2, value, self.cpu, guards, {})
         assert not guards
 
     def check_invalid(self, info1, info2, box_or_value=None):
         value, _ = self._box_or_value(box_or_value)
+        info1.position = info2.position = 0
         guards = []
         with py.test.raises(InvalidLoop):
             info1.generate_guards(info2, value, self.cpu, guards, {})
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py 
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -388,7 +388,8 @@
         #debug_start('jit-log-virtualstate')
         #virtual_state.debug_print('Closed loop with ')
         bad = {}
-        if not virtual_state.generalization_of(final_virtual_state, bad):
+        if not virtual_state.generalization_of(final_virtual_state, bad,
+                                               cpu=self.optimizer.cpu):
             # We ended up with a virtual state that is not compatible
             # and we are thus unable to jump to the start of the loop
             #final_virtual_state.debug_print("Bad virtual state at end of 
loop, ",
@@ -558,7 +559,9 @@
 
             bad = {}
             debugmsg = 'Did not match '
-            if target.virtual_state.generalization_of(virtual_state, bad):
+            if target.virtual_state.generalization_of(
+                    virtual_state, bad,
+                    cpu = self.optimizer.cpu):
                 ok = True
                 debugmsg = 'Matched '
             else:
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py 
b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -17,16 +17,15 @@
 class AbstractVirtualStateInfo(resume.AbstractVirtualInfo):
     position = -1
 
-    def generalization_of(self, other, renum, bad):
-        assert self.position != -1
-        if self.position in renum:
-            result = renum[self.position] == other.position
-        else:
-            renum[self.position] = other.position
-            result = self.generalization_of_renumbering_done(other, renum, bad)
-        if not result:
-            bad[self] = bad[other] = None
-        return result
+    def generalization_of(self, other, renum, bad, cpu=None):
+        # cpu can be None for testing only
+        guards = []
+        try:
+            self.generate_guards(other, None, cpu, guards, renum, bad)
+            assert not guards
+            return True
+        except InvalidLoop:
+            return False
 
     def generate_guards(self, other, value, cpu, extra_guards, renum, 
bad=None):
         """ generate guards (output in the list extra_guards) that make runtime
@@ -38,6 +37,7 @@
         the value) as a guiding heuristic whether making such guards makes
         sense. if None is passed in for value, no guard is ever generated, and
         this function degenerates to a generalization check."""
+        assert self.position != -1
         if bad is None:
             bad = {}
         assert value is None or isinstance(value, OptValue)
@@ -93,43 +93,27 @@
     def __init__(self, fielddescrs):
         self.fielddescrs = fielddescrs
 
-    def generalization_of_renumbering_done(self, other, renum, bad):
+    def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
         if not self._generalization_of_structpart(other):
-            return False
+            raise InvalidLoop("different kinds of structs")
 
         assert isinstance(other, AbstractVirtualStructStateInfo)
         assert len(self.fielddescrs) == len(self.fieldstate)
         assert len(other.fielddescrs) == len(other.fieldstate)
+        if value is not None:
+            assert isinstance(value, virtualize.AbstractVirtualStructValue)
+            assert value.is_virtual()
+
         if len(self.fielddescrs) != len(other.fielddescrs):
-            return False
+            raise InvalidLoop("field descrs don't match")
 
         for i in range(len(self.fielddescrs)):
             if other.fielddescrs[i] is not self.fielddescrs[i]:
-                return False
-            if not self.fieldstate[i].generalization_of(other.fieldstate[i],
-                                                        renum, bad):
-                return False
-
-        return True
-
-
-    def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
-        if not self._generalization_of_structpart(other):
-            raise InvalidLoop("XXX")
-
-        assert isinstance(other, AbstractVirtualStructStateInfo)
-        assert len(self.fielddescrs) == len(self.fieldstate)
-        assert len(other.fielddescrs) == len(other.fieldstate)
-        assert isinstance(value, virtualize.AbstractVirtualStructValue)
-        assert value.is_virtual()
-
-        if len(self.fielddescrs) != len(other.fielddescrs):
-            raise InvalidLoop("XXX")
-
-        for i in range(len(self.fielddescrs)):
-            if other.fielddescrs[i] is not self.fielddescrs[i]:
-                raise InvalidLoop("XXX")
-            v = value._fields[self.fielddescrs[i]] # must be there
+                raise InvalidLoop("field descrs don't match")
+            if value is not None:
+                v = value._fields[self.fielddescrs[i]] # must be there
+            else:
+                v = None
             self.fieldstate[i].generate_guards(other.fieldstate[i], v, cpu, 
extra_guards, renum)
 
 
@@ -187,18 +171,18 @@
     def __init__(self, arraydescr):
         self.arraydescr = arraydescr
 
-    def generalization_of_renumbering_done(self, other, renum, bad):
+    def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
         if not isinstance(other, VArrayStateInfo):
-            return False
+            raise InvalidLoop("other is not an array")
         if self.arraydescr is not other.arraydescr:
-            return False
+            raise InvalidLoop("other is a different kind of array")
         if len(self.fieldstate) != len(other.fieldstate):
-            return False
+            raise InvalidLoop("other has a different length")
         for i in range(len(self.fieldstate)):
-            if not self.fieldstate[i].generalization_of(other.fieldstate[i],
-                                                        renum, bad):
-                return False
-        return True
+            # XXX value
+            self.fieldstate[i].generate_guards(other.fieldstate[i],
+                                               None, cpu, extra_guards,
+                                               renum, bad)
 
     def enum_forced_boxes(self, boxes, value, optimizer):
         if not isinstance(value, virtualize.VArrayValue):
@@ -226,27 +210,29 @@
         self.arraydescr = arraydescr
         self.fielddescrs = fielddescrs
 
-    def generalization_of_renumbering_done(self, other, renum, bad):
+    def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
+        # XXX this needs a test in test_virtualstate!!!
         if not isinstance(other, VArrayStructStateInfo):
-            return False
+            raise InvalidLoop("other is not an VArrayStructStateInfo")
         if not self.arraydescr is not other.arraydescr:
-            return False
+            raise InvalidLoop("other is a different kind of array")
 
         if len(self.fielddescrs) != len(other.fielddescrs):
-            return False
+            raise InvalidLoop("other has a different length")
 
         p = 0
         for i in range(len(self.fielddescrs)):
             if len(self.fielddescrs[i]) != len(other.fielddescrs[i]):
-                return False
+                raise InvalidLoop("other has a different length")
             for j in range(len(self.fielddescrs[i])):
                 if self.fielddescrs[i][j] is not other.fielddescrs[i][j]:
-                    return False
-                if not 
self.fieldstate[p].generalization_of(other.fieldstate[p],
-                                                            renum, bad):
-                    return False
+                    raise InvalidLoop("other has a different length")
+                self.fieldstate[p].generate_guards(other.fieldstate[p],
+                                                   None, # XXX
+                                                   cpu,
+                                                   extra_guards,
+                                                   renum, bad)
                 p += 1
-        return True
 
     def _enum(self, virtual_state):
         for s in self.fieldstate:
@@ -315,17 +301,15 @@
         return True
 
     def _generate_guards(self, other, value, cpu, extra_guards, renum, bad):
-        if value is not None:
+        if value is None or self.is_opaque:
+            box = None # generating guards for opaque pointers isn't safe
+        else:
             box = value.box
-        else:
-            box = None
         if not isinstance(other, NotVirtualStateInfo):
             raise InvalidLoop('The VirtualStates does not match as a ' +
                               'virtual appears where a pointer is needed ' +
                               'and it is too late to force it.')
 
-        if self.is_opaque:
-            raise InvalidLoop('Generating guards for opaque pointers is not 
safe')
 
         if self.lenbound and not 
self.lenbound.generalization_of(other.lenbound):
             raise InvalidLoop()
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to