Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: optresult
Changeset: r77565:b5d3b92eec4c
Date: 2015-05-26 11:42 +0200
http://bitbucket.org/pypy/pypy/changeset/b5d3b92eec4c/

Log:    start passing the merge-guards kind of tests

diff --git a/rpython/jit/metainterp/optimizeopt/info.py 
b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -49,11 +49,27 @@
 
     
 class NonNullPtrInfo(PtrInfo):
-    _attrs_ = ()
-
+    _attrs_ = ('last_guard_pos',)
+    last_guard_pos = -1
+    
     def is_nonnull(self):
         return True
 
+    def get_known_class(self, cpu):
+        return None
+
+    def get_last_guard(self, optimizer):
+        if self.last_guard_pos == -1:
+            return None
+        return optimizer._newoperations[self.last_guard_pos]
+
+    def reset_last_guard_pos(self):
+        self.last_guard_pos = -1
+
+    def mark_last_guard(self, optimizer):
+        self.last_guard_pos = len(optimizer._newoperations) - 1
+        assert self.get_last_guard(optimizer).is_guard()
+
 class AbstractVirtualPtrInfo(NonNullPtrInfo):
     _attrs_ = ('flags',)
 
@@ -111,7 +127,7 @@
         return count
 
 class InstancePtrInfo(AbstractStructPtrInfo):
-    _attrs_ = ('_known_class')
+    _attrs_ = ('_known_class',)
     _fields = None
 
     def __init__(self, known_class=None, is_virtual=False):
@@ -121,7 +137,7 @@
 
     def get_known_class(self, cpu):
         return self._known_class
-    
+
 class StructPtrInfo(AbstractStructPtrInfo):
     def __init__(self, is_virtual=False):
         if is_virtual:
@@ -260,6 +276,9 @@
         if not self._const.nonnull():
             return None
         return cpu.ts.cls_of_box(self._const)
+
+    def get_last_guard(self, optimizer):
+        return None
     
 class XPtrOptInfo(AbstractInfo):
     _attrs_ = ('_tag', 'known_class', 'last_guard_pos', 'lenbound')
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py 
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -295,12 +295,11 @@
             return ptrinfo.getnullness()
         assert False
 
-    def make_constant_class(self, op, class_const):
+    def make_constant_class(self, op, class_const, update_last_guard=True):
         op = self.get_box_replacement(op)
-        opinfo = op.get_forwarded()
-        if opinfo is not None:
-            return opinfo
         opinfo = info.InstancePtrInfo(class_const)
+        if update_last_guard:
+            opinfo.mark_last_guard(self.optimizer)
         op.set_forwarded(opinfo)
         return opinfo
 
@@ -466,7 +465,7 @@
         self.optimizations  = optimizations
 
     def replace_guard(self, op, value):
-        assert isinstance(value, PtrOptValue)
+        assert isinstance(value, info.InstancePtrInfo)
         if value.last_guard_pos == -1:
             return
         self.replaces_guard[op] = value.last_guard_pos
@@ -598,6 +597,10 @@
         opinfo = arg0.get_forwarded()
         if isinstance(opinfo, info.AbstractVirtualPtrInfo):
             return opinfo
+        elif opinfo is not None:
+            last_guard_pos = opinfo.last_guard_pos
+        else:
+            last_guard_pos = -1
         assert opinfo is None or opinfo.__class__ is info.NonNullPtrInfo
         if op.is_getfield() or op.getopnum() == rop.SETFIELD_GC:
             is_object = op.getdescr().parent_descr.is_object()
@@ -608,8 +611,11 @@
             opinfo.init_fields(op.getdescr().parent_descr)
         elif op.is_getarrayitem() or op.getopnum() == rop.SETARRAYITEM_GC:
             opinfo = info.ArrayPtrInfo(op.getdescr())
+        elif op.getopnum() == rop.GUARD_CLASS:
+            opinfo = info.InstancePtrInfo()
         else:
-            zzz
+            xxx
+        opinfo.last_guard_pos = last_guard_pos
         arg0.set_forwarded(opinfo)
         return opinfo
 
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py 
b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -12,6 +12,7 @@
         self.next_index = 0
 
     def add(self, op):
+        assert isinstance(op, AbstractResOp)
         next_index = self.next_index
         self.next_index = (next_index + 1) % self.REMEMBER_LIMIT
         self.lst[next_index] = op
@@ -180,7 +181,6 @@
         self.optimizer.optpure = self
 
     def pure(self, opnum, op):
-        op = self.get_box_replacement(op)
         recentops = self.getrecentops(opnum)
         recentops.add(op)
 
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py 
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -287,52 +287,49 @@
                                   'fail' % r)
         self.emit_operation(op)
         self.make_nonnull(op.getarg(0))
+        self.getptrinfo(op.getarg(0)).mark_last_guard(self.optimizer)
 
     def optimize_GUARD_VALUE(self, op):
-        ## value = self.getvalue(op.getarg(0))
-        ## if value.is_virtual():
-        ##     arg = value.get_constant_class(self.optimizer.cpu)
-        ##     if arg:
-        ##         addr = arg.getaddr()
-        ##         name = 
self.optimizer.metainterp_sd.get_name_from_address(addr)
-        ##     else:
-        ##         name = "<unknown>"
-        ##     raise InvalidLoop('A promote of a virtual %s (a recently 
allocated object) never makes sense!' % name)
-        ## old_guard_op = value.get_last_guard(self.optimizer)
-        ## if old_guard_op and not isinstance(old_guard_op.getdescr(),
-        ##                                    compile.ResumeAtPositionDescr):
-        ##     # there already has been a guard_nonnull or guard_class or
-        ##     # guard_nonnull_class on this value, which is rather silly.
-        ##     # replace the original guard with a guard_value
-        ##     if old_guard_op.getopnum() != rop.GUARD_NONNULL:
-        ##         # This is only safe if the class of the guard_value matches 
the
-        ##         # class of the guard_*_class, otherwise the intermediate 
ops might
-        ##         # be executed with wrong classes.
-        ##         previous_classbox = 
value.get_constant_class(self.optimizer.cpu)
-        ##         expected_classbox = 
self.optimizer.cpu.ts.cls_of_box(op.getarg(1))
-        ##         assert previous_classbox is not None
-        ##         assert expected_classbox is not None
-        ##         if not previous_classbox.same_constant(expected_classbox):
-        ##             r = 
self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
-        ##             raise InvalidLoop('A GUARD_VALUE (%s) was proven to 
always fail' % r)
-        ##     descr = compile.ResumeGuardValueDescr()
-        ##     op = old_guard_op.copy_and_change(rop.GUARD_VALUE,
-        ##                 args = [old_guard_op.getarg(0), op.getarg(1)],
-        ##                 descr = descr)
-        ##     # Note: we give explicitly a new descr for 'op'; this is why the
-        ##     # old descr must not be ResumeAtPositionDescr (checked above).
-        ##     # Better-safe-than-sorry but it should never occur: we should
-        ##     # not put in short preambles guard_xxx and guard_value
-        ##     # on the same box.
-        ##     self.optimizer.replace_guard(op, value)
-        ##     descr.make_a_counter_per_value(op)
-        ##     # to be safe
-        ##     if isinstance(value, PtrOptValue):
-        ##         value.last_guard_pos = -1
+        arg0 = op.getarg(0)
+        if arg0.type == 'r':
+            info = self.getptrinfo(arg0)
+            if info:
+                if info.is_virtual():
+                    xxx
+                old_guard_op = info.get_last_guard(self.optimizer)
+                if old_guard_op is not None:
+                    op = self.replace_guard_class_with_guard_value(op, info,
+                                                              old_guard_op)
         constbox = op.getarg(1)
         assert isinstance(constbox, Const)
         self.optimize_guard(op, constbox)
 
+    def replace_guard_class_with_guard_value(self, op, info, old_guard_op):
+        if old_guard_op.opnum != rop.GUARD_NONNULL:
+            previous_classbox = info.get_known_class(self.optimizer.cpu)
+            expected_classbox = self.optimizer.cpu.ts.cls_of_box(op.getarg(1))
+            assert previous_classbox is not None
+            assert expected_classbox is not None
+            if not previous_classbox.same_constant(
+                    expected_classbox):
+                r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+                raise InvalidLoop('A GUARD_VALUE (%s) was proven to '
+                                  'always fail' % r)
+        descr = compile.ResumeGuardValueDescr()
+        op = old_guard_op.copy_and_change(rop.GUARD_VALUE,
+                         args = [old_guard_op.getarg(0), op.getarg(1)],
+                         descr = descr)
+        # Note: we give explicitly a new descr for 'op'; this is why the
+        # old descr must not be ResumeAtPositionDescr (checked above).
+        # Better-safe-than-sorry but it should never occur: we should
+        # not put in short preambles guard_xxx and guard_value
+        # on the same box.
+        self.optimizer.replace_guard(op, info)
+        descr.make_a_counter_per_value(op)
+        # to be safe
+        info.reset_last_guard_pos()
+        return op
+
     def optimize_GUARD_TRUE(self, op):
         self.optimize_guard(op, CONST_1)
 
@@ -351,42 +348,39 @@
 
     def optimize_GUARD_CLASS(self, op):
         expectedclassbox = op.getarg(1)
-        info = self.getptrinfo(op.getarg(0))
+        info = self.ensure_ptr_info_arg0(op)
         assert isinstance(expectedclassbox, Const)
-        if info is not None:
-            realclassbox = info.get_known_class(self.optimizer.cpu)
-            if realclassbox is not None:
-                if realclassbox.same_constant(expectedclassbox):
-                    return
-                r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
-                raise InvalidLoop('A GUARD_CLASS (%s) was proven to always 
fail'
-                                  % r)
-            old_guard_op = info.get_last_guard(self.optimizer)
-            if old_guard_op and not isinstance(old_guard_op.getdescr(),
-                                               compile.ResumeAtPositionDescr):
-                xxx
-                # there already has been a guard_nonnull or guard_class or
-                # guard_nonnull_class on this value.
-                if old_guard_op.getopnum() == rop.GUARD_NONNULL:
-                    # it was a guard_nonnull, which we replace with a
-                    # guard_nonnull_class.
-                    descr = compile.ResumeGuardNonnullClassDescr()
-                    op = old_guard_op.copy_and_change (rop.GUARD_NONNULL_CLASS,
-                                args = [old_guard_op.getarg(0), op.getarg(1)],
-                                descr=descr)
-                    # Note: we give explicitly a new descr for 'op'; this is 
why the
-                    # old descr must not be ResumeAtPositionDescr (checked 
above).
-                    # Better-safe-than-sorry but it should never occur: we 
should
-                    # not put in short preambles guard_nonnull and guard_class
-                    # on the same box.
-                    self.optimizer.replace_guard(op, value)
-                    # not emitting the guard, so we have to pass None to
-                    # make_constant_class, so last_guard_pos is not updated
-                    self.emit_operation(op)
-                    value.make_constant_class(None, expectedclassbox)
-                    return
+        realclassbox = info.get_known_class(self.optimizer.cpu)
+        if realclassbox is not None:
+            if realclassbox.same_constant(expectedclassbox):
+                return
+            r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
+            raise InvalidLoop('A GUARD_CLASS (%s) was proven to always fail'
+                              % r)
+        old_guard_op = info.get_last_guard(self.optimizer)
+        if old_guard_op and not isinstance(old_guard_op.getdescr(),
+                                           compile.ResumeAtPositionDescr):
+            # there already has been a guard_nonnull or guard_class or
+            # guard_nonnull_class on this value.
+            if old_guard_op.getopnum() == rop.GUARD_NONNULL:
+                # it was a guard_nonnull, which we replace with a
+                # guard_nonnull_class.
+                descr = compile.ResumeGuardNonnullClassDescr()
+                op = old_guard_op.copy_and_change (rop.GUARD_NONNULL_CLASS,
+                            args = [old_guard_op.getarg(0), op.getarg(1)],
+                            descr=descr)
+                # Note: we give explicitly a new descr for 'op'; this is why 
the
+                # old descr must not be ResumeAtPositionDescr (checked above).
+                # Better-safe-than-sorry but it should never occur: we should
+                # not put in short preambles guard_nonnull and guard_class
+                # on the same box.
+                self.optimizer.replace_guard(op, info)
+                self.emit_operation(op)
+                self.make_constant_class(op.getarg(0), expectedclassbox,
+                                         False)
+                return
+        self.emit_operation(op)
         self.make_constant_class(op.getarg(0), expectedclassbox)
-        self.emit_operation(op)
 
     def optimize_GUARD_NONNULL_CLASS(self, op):
         value = self.getvalue(op.getarg(0))
diff --git a/rpython/jit/metainterp/test/test_resume.py 
b/rpython/jit/metainterp/test/test_resume.py
--- a/rpython/jit/metainterp/test/test_resume.py
+++ b/rpython/jit/metainterp/test/test_resume.py
@@ -2,9 +2,6 @@
 import py
 import sys
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
-from rpython.jit.metainterp.optimizeopt.optimizer import OptValue
-from rpython.jit.metainterp.optimizeopt.virtualize import VirtualValue, 
VArrayValue
-from rpython.jit.metainterp.optimizeopt.virtualize import VStructValue, 
AbstractVirtualValue
 from rpython.jit.metainterp.resume import *
 from rpython.jit.metainterp.history import BoxInt, BoxPtr, ConstInt
 from rpython.jit.metainterp.history import ConstPtr, ConstFloat
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to