Author: Maciej Fijalkowski <[email protected]>
Branch: result-in-resops
Changeset: r57481:d72856f2e3a4
Date: 2012-09-23 18:03 +0200
http://bitbucket.org/pypy/pypy/changeset/d72856f2e3a4/

Log:    hack enough to pass the overflow propagation. I think by now the op
        propagation is done correctly.

diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py 
b/pypy/jit/metainterp/optimizeopt/intbounds.py
--- a/pypy/jit/metainterp/optimizeopt/intbounds.py
+++ b/pypy/jit/metainterp/optimizeopt/intbounds.py
@@ -113,6 +113,7 @@
                 # nonneg % power-of-two ==> nonneg & (power-of-two - 1)
                 arg1 = op.getarg(0)
                 arg2 = ConstInt(val-1)
+                xxx
                 op = op.copy_and_change(rop.INT_AND, args=[arg1, arg2])
         self.emit_operation(op)
         if v2.is_constant():
@@ -202,7 +203,7 @@
             # Transform into INT_ADD.  The following guard will be killed
             # by optimize_GUARD_NO_OVERFLOW; if we see instead an
             # optimize_GUARD_OVERFLOW, then InvalidLoop.
-            op = op.copy_and_change(rop.INT_ADD)
+            op = self.optimizer.copy_and_change(op, rop.INT_ADD)
         self.emit_operation(op) # emit the op
         r = self.getvalue(op)
         r.intbound.intersect(resbound)
@@ -212,6 +213,7 @@
         v2 = self.getvalue(op.getarg(1))
         resbound = v1.intbound.sub_bound(v2.intbound)
         if resbound.bounded():
+            xxx
             op = op.copy_and_change(rop.INT_SUB)
         self.emit_operation(op) # emit the op
         r = self.getvalue(op)
@@ -222,6 +224,7 @@
         v2 = self.getvalue(op.getarg(1))
         resbound = v1.intbound.mul_bound(v2.intbound)
         if resbound.bounded():
+            xxx
             op = op.copy_and_change(rop.INT_MUL)
         self.emit_operation(op)
         r = self.getvalue(op)
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py 
b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -6,7 +6,7 @@
                                                      IntLowerBound, MININT, 
MAXINT
 from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from pypy.jit.metainterp.resoperation import rop, AbstractResOp, opgroups,\
-     Const, ConstInt, ConstFloat
+     Const, ConstInt, ConstFloat, AbstractValue
 from pypy.jit.metainterp.typesystem import llhelper
 from pypy.rlib.objectmodel import specialize
 
@@ -29,13 +29,14 @@
         return LenBound(self.mode, self.descr, self.bound.clone())
 
 class OptValue(object):
-    _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound', 
'lenbound')
+    _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound', 
'lenbound', 'is_bool_box')
     last_guard = None
 
     level = LEVEL_UNKNOWN
     known_class = None
     intbound = ImmutableIntUnbounded()
     lenbound = None
+    is_bool_box = False
 
     def __init__(self, box, level=None, known_class=None, intbound=None):
         self.box = box
@@ -282,8 +283,8 @@
     def make_constant_int(self, box, intconst):
         return self.optimizer.make_constant_int(box, intconst)
 
-    def make_equal_to(self, box, value):
-        return self.optimizer.make_equal_to(box, value)
+    def replace(self, box, value):
+        return self.optimizer.replace(box, value)
 
     def get_constant_box(self, box):
         return self.optimizer.get_constant_box(box)
@@ -348,7 +349,6 @@
         self.interned_refs = self.cpu.ts.new_ref_dict()
         self.interned_ints = {}
         self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd)
-        self.bool_boxes = {}
         self.pendingfields = []
         self.quasi_immutable_deps = None
         self.opaque_pointers = {}
@@ -437,6 +437,19 @@
         self.ensure_imported(value)
         return value
 
+    def copy_op_if_modified_by_optimization(self, op):
+        new_op = op.copy_if_modified_by_optimization(self)
+        if new_op is not op:
+            self.replace(op, new_op)
+        return new_op
+
+    @specialize.arg(2)
+    def copy_and_change(self, op, opnum, *args, **kwds): 
+        new_op = op.copy_and_change(opnum, *args, **kwds)
+        if new_op is not op:
+            self.replace(op, new_op)
+        return new_op
+
     def ensure_imported(self, value):
         pass
 
@@ -462,17 +475,18 @@
     def clear_newoperations(self):
         self._newoperations = []
 
-    def make_equal_to(self, box, value, replace=False):
-        assert isinstance(value, OptValue)
-        if replace:
-            assert not box.has_extra("optimize_value")
-        box.set_extra("optimize_value", value)
+    def replace(self, what, with_):
+        assert isinstance(what, AbstractValue)
+        assert isinstance(with_, AbstractValue)
+        val = self.getvalue(with_)
+        # completely remove the old optimize value
+        what.set_extra("optimize_value", val)
 
     def make_constant(self, box, constbox):
-        self.make_equal_to(box, ConstantValue(constbox))
+        self.getvalue(box).make_constant(constbox)
 
     def make_constant_int(self, box, intvalue):
-        self.make_constant(box, ConstInt(intvalue))
+        self.getvalue(box).make_constant(ConstInt(intvalue))
 
     def new_ptr_box(self):
         return self.cpu.ts.BoxRef()
@@ -531,7 +545,7 @@
 
     def emit_operation(self, op):
         if op.returns_bool_result():
-            self.bool_boxes[self.getvalue(op)] = None
+            self.getvalue(op).is_bool_box = True
         self._emit_operation(op)
 
     def get_value_replacement(self, v):
@@ -549,7 +563,7 @@
     @specialize.argtype(0)
     def _emit_operation(self, op):
         assert op.getopnum() not in opgroups.CALL_PURE
-        op = op.copy_if_modified_by_optimization(self)
+        op = self.copy_op_if_modified_by_optimization(op)
         if isinstance(op, Const):
             return
         self.metainterp_sd.profiler.count(jitprof.Counters.OPT_OPS)
@@ -579,6 +593,7 @@
     def store_final_boxes_in_guard(self, op):
         if op.getdescr() is not None:
             # means we need to copy the op and attach a new descr
+            xxx
             op = op.copy_and_change(op.getopnum(), descr=None)
         descr = op.invent_descr()
         modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
@@ -591,7 +606,7 @@
         descr.store_final_boxes(op, newboxes)
         #
         if op.getopnum() == rop.GUARD_VALUE:
-            if self.getvalue(op.getarg(0)) in self.bool_boxes:
+            if self.getvalue(op.getarg(0)).is_bool_box:
                 # Hack: turn guard_value(bool) into guard_true/guard_false.
                 # This is done after the operation is emitted to let
                 # store_final_boxes_in_guard set the guard_opnum field of the
diff --git a/pypy/jit/metainterp/optimizeopt/pure.py 
b/pypy/jit/metainterp/optimizeopt/pure.py
--- a/pypy/jit/metainterp/optimizeopt/pure.py
+++ b/pypy/jit/metainterp/optimizeopt/pure.py
@@ -51,7 +51,7 @@
         # otherwise, the operation remains
         self.emit_operation(op)
         if op.returns_bool_result():
-            self.optimizer.bool_boxes[self.getvalue(op)] = None        
+            self.getvalue(op).is_bool_box = True
         if nextop:
             self.emit_operation(nextop)
 
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py 
b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -133,6 +133,7 @@
                     # x & (x - 1) == 0 is a quick test for power of 2
                     if x & (x - 1) == 0:
                         new_rhs = ConstInt(highest_bit(lhs.box.getint()))
+                        xxx
                         op = op.copy_and_change(rop.INT_LSHIFT, args=[rhs.box, 
new_rhs])
                         break
             self.emit_operation(op)
@@ -240,6 +241,7 @@
                 assert expected_classbox is not None
                 if not previous_classbox.same_constant(expected_classbox):
                     raise InvalidLoop('A GUARD_VALUE was proven to always 
fail')
+            xxx
             op = old_guard_op.copy_and_change(rop.GUARD_VALUE,
                                       args = [old_guard_op.getarg(0), 
op.getarg(1)])
             self.optimizer.replaces_guard[op] = old_guard_op
@@ -288,6 +290,7 @@
             if old_guard_op.getopnum() == rop.GUARD_NONNULL:
                 # it was a guard_nonnull, which we replace with a
                 # guard_nonnull_class.
+                xxx
                 op = old_guard_op.copy_and_change (rop.GUARD_NONNULL_CLASS,
                                          args = [old_guard_op.getarg(0), 
op.getarg(1)])
                 self.optimizer.replaces_guard[op] = old_guard_op
@@ -322,6 +325,7 @@
         # change the op to be a normal call, from the backend's point of view
         # there is no reason to have a separate operation for this
         self.loop_invariant_producer[key] = op
+        xxx
         op = op.copy_and_change(rop.CALL)
         self.emit_operation(op)
         resvalue = self.getvalue(op)
@@ -340,7 +344,7 @@
             self.emit_operation(op)
 
     def optimize_INT_IS_TRUE(self, op):
-        if self.getvalue(op.getarg(0)) in self.optimizer.bool_boxes:
+        if self.getvalue(op.getarg(0)).is_bool_box:
             self.make_equal_to(op, self.getvalue(op.getarg(0)))
             return
         self._optimize_nullness(op, op.getarg(0), True)
@@ -487,6 +491,7 @@
         if v1.intbound.known_ge(IntBound(0, 0)) and v2.is_constant():
             val = v2.box.getint()
             if val & (val - 1) == 0 and val > 0: # val == 2**shift
+                xxx
                 op = op.copy_and_change(rop.INT_RSHIFT,
                                         args = [op.getarg(0), 
ConstInt(highest_bit(val))])
         self.emit_operation(op)
diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py 
b/pypy/jit/metainterp/optimizeopt/simplify.py
--- a/pypy/jit/metainterp/optimizeopt/simplify.py
+++ b/pypy/jit/metainterp/optimizeopt/simplify.py
@@ -10,6 +10,7 @@
 
     def _new_optimize_call(tp):
         def optimize_call(self, op):
+            xxx
             self.emit_operation(op.copy_and_change(getattr(rop, 'CALL_' + tp)))
     optimize_CALL_PURE_i = _new_optimize_call('i')
     optimize_CALL_PURE_f = _new_optimize_call('f')
@@ -39,6 +40,7 @@
         if not self.unroll:
             descr = op.getdescr()
             if isinstance(descr, JitCellToken):
+                xxx
                 return self.optimize_JUMP(op.copy_and_change(rop.JUMP))
             self.last_label_descr = op.getdescr()
         self.emit_operation(op)
@@ -58,7 +60,8 @@
                 assert len(descr.target_tokens) == 1
                 newdescr = descr.target_tokens[0]
             if newdescr is not descr or op.opnum != rop.JUMP:
-                op = op.copy_and_change(op.opnum, descr=newdescr)
+                op = self.optimizer.copy_and_change(op, op.opnum,
+                                                    descr=newdescr)
         self.emit_operation(op)
 
 dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_',
diff --git a/pypy/jit/metainterp/resoperation.py 
b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -1036,8 +1036,12 @@
         new_arg = opt.get_value_replacement(self._arg0)
         if new_arg is None:
             return self
-        return create_resop_1(self.opnum, self.getresult(), new_arg,
-                              self.getdescr())
+        res = create_resop_1(self.opnum, self.getresult(), new_arg,
+                             self.getdescr())
+        if self.is_guard():
+            res.set_rd_frame_info_list(self.get_rd_frame_info_list())
+            res.set_rd_snapshot(self.get_rd_snapshot())
+        return res
 
     @specialize.arg(1)
     def copy_and_change(self, newopnum, arg0=None, descr=None):
@@ -1091,10 +1095,14 @@
         new_arg1 = opt.get_value_replacement(self._arg1)
         if new_arg0 is None and new_arg1 is None:
             return self
-        return create_resop_2(self.opnum, self.getresult(),
-                              new_arg0 or self._arg0,
-                              new_arg1 or self._arg1,
-                              self.getdescr())
+        res = create_resop_2(self.opnum, self.getresult(),
+                             new_arg0 or self._arg0,
+                             new_arg1 or self._arg1,
+                             self.getdescr())
+        if self.is_guard():
+            res.set_rd_frame_info_list(self.get_rd_frame_info_list())
+            res.set_rd_snapshot(self.get_rd_snapshot())
+        return res
 
     @specialize.arg(1)
     def copy_and_change(self, newopnum, arg0=None, arg1=None, descr=None):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to