[pypy-commit] pypy result-in-resops: fixes to virtuals

fijal noreply at buildbot.pypy.org
Tue Sep 25 13:36:29 CEST 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: result-in-resops
Changeset: r57564:f723c2f185c2
Date: 2012-09-25 12:04 +0200
http://bitbucket.org/pypy/pypy/changeset/f723c2f185c2/

Log:	fixes to virtuals

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
@@ -247,13 +247,13 @@
 
     def __repr__(self):
         if self.level == LEVEL_UNKNOWN:
-            return '<Opt %r>' % self.box
+            return '<Opt %r>' % self.op
         if self.level == LEVEL_NONNULL:
-            return '<OptNonNull %r>' % self.box
+            return '<OptNonNull %r>' % self.op
         if self.level == LEVEL_KNOWNCLASS:
-            return '<OptKnownClass (%s) %r>' % (self.known_class, self.box)
+            return '<OptKnownClass (%s) %r>' % (self.known_class, self.op)
         assert self.level == LEVEL_CONSTANT
-        return '<OptConst %r>' % self.box
+        return '<OptConst %r>' % self.op
 
 class ConstantValue(OptValue):
     def __init__(self, box):
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
@@ -1,5 +1,5 @@
 from pypy.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED
-from pypy.jit.metainterp.resoperation import rop, create_resop_2
+from pypy.jit.metainterp.resoperation import rop, create_resop_2, create_resop_1
 from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method,\
      ArgsSet
 
@@ -93,8 +93,11 @@
     def setup(self):
         self.optimizer.optpure = self
 
-    def pure(self, opnum, result, arg0, arg1):
-        op = create_resop_2(opnum, result, arg0, arg1)
+    def pure(self, opnum, result, arg0, arg1=None):
+        if arg1 is None:
+            op = create_resop_1(opnum, result, arg0)
+        else:
+            op = create_resop_2(opnum, result, arg0, arg1)
         self.pure_operations.add(op)
 
     def has_pure_result(self, op_key):
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
@@ -184,7 +184,7 @@
                     ))
                     return
         self.emit_operation(op)
-        self.pure(rop.FLOAT_MUL, [arg2, arg1], op)
+        self.pure(rop.FLOAT_MUL, op.getfloat(), arg2, arg1)
 
     def optimize_FLOAT_NEG(self, op):
         v1 = op.getarg(0)
@@ -309,29 +309,30 @@
                               'fail')
         self.optimize_GUARD_CLASS(op)
 
-    def optimize_CALL_LOOPINVARIANT_i(self, op):
-        arg = op.getarg(0)
-        # 'arg' must be a Const, because residual_call in codewriter
-        # expects a compile-time constant
-        assert isinstance(arg, Const)
-        key = make_hashable_int(arg.getint())
+    def _new_optimize_call_loopinvariant(opnum):
+        def optimize_CALL_LOOPINVARIANT(self, op):
+            arg = op.getarg(0)
+            # 'arg' must be a Const, because residual_call in codewriter
+            # expects a compile-time constant
+            assert isinstance(arg, Const)
+            key = make_hashable_int(arg.getint())
 
-        resvalue = self.loop_invariant_results.get(key, None)
-        if resvalue is not None:
-            self.make_equal_to(op, resvalue)
-            self.last_emitted_operation = REMOVED
-            return
-        # 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)
-        self.loop_invariant_results[key] = resvalue
-    optimize_CALL_LOOPINVARIANT_p = optimize_CALL_LOOPINVARIANT_i
-    optimize_CALL_LOOPINVARIANT_f = optimize_CALL_LOOPINVARIANT_i
-    optimize_CALL_LOOPINVARIANT_N = optimize_CALL_LOOPINVARIANT_i
+            resop = self.loop_invariant_results.get(key, None)
+            if resop is not None:
+                self.replace(op, resop)
+                self.last_emitted_operation = REMOVED
+                return
+            # 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
+            op = self.optimizer.copy_and_change(op, opnum)
+            self.emit_operation(op)
+            self.loop_invariant_results[key] = op
+        return optimize_CALL_LOOPINVARIANT
+    optimize_CALL_LOOPINVARIANT_i = _new_optimize_call_loopinvariant(rop.CALL_i)
+    optimize_CALL_LOOPINVARIANT_p = _new_optimize_call_loopinvariant(rop.CALL_p)
+    optimize_CALL_LOOPINVARIANT_f = _new_optimize_call_loopinvariant(rop.CALL_f)
+    optimize_CALL_LOOPINVARIANT_N = _new_optimize_call_loopinvariant(rop.CALL_N)
 
     def _optimize_nullness(self, op, box, expect_nonnull):
         value = self.getvalue(box)
@@ -447,6 +448,11 @@
         return False
 
     def optimize_CALL_PURE_i(self, op):
+        # Note that we can safely read the contents of boxes here, because
+        # we compare the value of unoptimized op (which is correct) with
+        # proven constants. In the rare case where proven constants are
+        # different, we just emit it (to be precise we emit CALL_x, but
+        # it's being done by someone else)
         for i in range(op.numargs()):
             arg = op.getarg(i)
             const = self.get_constant_box(arg)
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -905,7 +905,7 @@
         [i]
         p1 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p1, i, descr=valuedescr)
-        i0 = getfield_gc(p1, descr=valuedescr)
+        i0 = getfield_gc_i(p1, descr=valuedescr)
         i1 = int_add(i0, 1)
         jump(i1)
         """
@@ -970,7 +970,7 @@
         [i0]
         p0 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p0, NULL, descr=nextdescr)
-        p2 = getfield_gc(p0, descr=nextdescr)
+        p2 = getfield_gc_p(p0, descr=nextdescr)
         i1 = ptr_eq(p2, NULL)
         jump(i1)
         """
@@ -985,7 +985,7 @@
         [i0]
         p0 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p0, ConstPtr(myptr), descr=nextdescr)
-        p2 = getfield_gc(p0, descr=nextdescr)
+        p2 = getfield_gc_p(p0, descr=nextdescr)
         i1 = ptr_eq(p2, NULL)
         jump(i1)
         """
@@ -1003,11 +1003,11 @@
         setinteriorfield_gc(p0, 0, f1, descr=compleximagdescr)
         setinteriorfield_gc(p0, 1, f2, descr=complexrealdescr)
         setinteriorfield_gc(p0, 1, f3, descr=compleximagdescr)
-        f4 = getinteriorfield_gc(p0, 0, descr=complexrealdescr)
-        f5 = getinteriorfield_gc(p0, 1, descr=complexrealdescr)
+        f4 = getinteriorfield_gc_f(p0, 0, descr=complexrealdescr)
+        f5 = getinteriorfield_gc_f(p0, 1, descr=complexrealdescr)
         f6 = float_mul(f4, f5)
-        f7 = getinteriorfield_gc(p0, 0, descr=compleximagdescr)
-        f8 = getinteriorfield_gc(p0, 1, descr=compleximagdescr)
+        f7 = getinteriorfield_gc_f(p0, 0, descr=compleximagdescr)
+        f8 = getinteriorfield_gc_f(p0, 1, descr=compleximagdescr)
         f9 = float_mul(f7, f8)
         f10 = float_add(f6, f9)
         finish(f10)
@@ -1027,11 +1027,11 @@
         p0 = new_array(1, descr=complexarraydescr)
         setinteriorfield_gc(p0, 0, f0, descr=complexrealdescr)
         setinteriorfield_gc(p0, 0, f1, descr=compleximagdescr)
-        f2 = getinteriorfield_gc(p0, 0, descr=complexrealdescr)
-        f3 = getinteriorfield_gc(p0, 0, descr=compleximagdescr)
+        f2 = getinteriorfield_gc_f(p0, 0, descr=complexrealdescr)
+        f3 = getinteriorfield_gc_f(p0, 0, descr=compleximagdescr)
         f4 = float_mul(f2, f3)
-        i0 = escape(f4, p0)
-        finish(i0)
+        escape(f4, p0)
+        finish()
         """
         expected = """
         [f0, f1]
@@ -1039,8 +1039,8 @@
         p0 = new_array(1, descr=complexarraydescr)
         setinteriorfield_gc(p0, 0, f0, descr=complexrealdescr)
         setinteriorfield_gc(p0, 0, f1, descr=compleximagdescr)
-        i0 = escape(f2, p0)
-        finish(i0)
+        escape(f2, p0)
+        finish()
         """
         self.optimize_loop(ops, expected)
 
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -4,7 +4,7 @@
 from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
     descrlist_dict, sort_descrs)
 from pypy.jit.metainterp.resoperation import rop, Const, ConstInt, BoxInt,\
-     create_resop_2
+     create_resop_2, create_resop_3
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.jit.metainterp.optimizeopt.optimizer import OptValue
 
@@ -144,8 +144,8 @@
                         ofs, box, subbox)
             # keep self._fields, because it's all immutable anyway
         else:
+            self.forced = True
             optforce.emit_operation(op)
-            self.forced = True
             #
             iteritems = self._fields.iteritems()
             if not we_are_translated(): #random order is fine, except for tests
@@ -260,20 +260,19 @@
         return self
 
     def _really_force(self, optforce):
-        assert self.source_op is not None
         if not we_are_translated():
-            self.source_op.name = 'FORCE ' + self.source_op.name
-        optforce.emit_operation(self.source_op)
-        self.box = box = self.source_op.result
+            self.op.name = 'FORCE ' + self.source_op.name
+        self.forced = True
+        optforce.emit_operation(self.op)
         for index in range(len(self._items)):
             subvalue = self._items[index]
             if subvalue is not self.constvalue:
                 if subvalue.is_null():
                     continue
                 subbox = subvalue.force_box(optforce)
-                op = ResOperation(rop.SETARRAYITEM_GC,
-                                  [box, ConstInt(index), subbox], None,
-                                  descr=self.arraydescr)
+                op = create_resop_3(rop.SETARRAYITEM_GC, None,
+                                    self.op, ConstInt(index), subbox,
+                                    descr=self.arraydescr)
                 optforce.emit_operation(op)
 
     def get_args_for_fail(self, modifier):
@@ -307,11 +306,10 @@
         self._items[index][ofs] = itemvalue
 
     def _really_force(self, optforce):
-        assert self.source_op is not None
         if not we_are_translated():
-            self.source_op.name = 'FORCE ' + self.source_op.name
-        optforce.emit_operation(self.source_op)
-        self.box = box = self.source_op.result
+            self.op.name = 'FORCE ' + self.op.name
+        self.forced = True
+        optforce.emit_operation(self.op)
         for index in range(len(self._items)):
             iteritems = self._items[index].iteritems()
             # random order is fine, except for tests
@@ -320,9 +318,9 @@
                 iteritems.sort(key = lambda (x, y): x.sort_key())
             for descr, value in iteritems:
                 subbox = value.force_box(optforce)
-                op = ResOperation(rop.SETINTERIORFIELD_GC,
-                    [box, ConstInt(index), subbox], None, descr=descr
-                )
+                op = create_resop_3(rop.SETINTERIORFIELD_GC, None,
+                                    self.op, ConstInt(index), subbox,
+                                    descr=descr)
                 optforce.emit_operation(op)
 
     def _get_list_of_descrs(self):
@@ -369,13 +367,13 @@
         self.setvalue(op, vvalue)
         return vvalue
 
-    def make_varray(self, arraydescr, size, box, source_op=None):
+    def make_varray(self, arraydescr, size, op):
         if arraydescr.is_array_of_structs():
-            vvalue = VArrayStructValue(arraydescr, size, box, source_op)
+            vvalue = VArrayStructValue(arraydescr, size, op)
         else:
             constvalue = self.new_const_item(arraydescr)
-            vvalue = VArrayValue(arraydescr, constvalue, size, box, source_op)
-        self.make_equal_to(box, vvalue)
+            vvalue = VArrayValue(arraydescr, constvalue, size, op)
+        self.setvalue(op, vvalue)
         return vvalue
 
     def make_vstruct(self, structdescr, box, source_op=None):
@@ -484,11 +482,10 @@
             # if the original 'op' did not have a ConstInt as argument,
             # build a new one with the ConstInt argument
             if not isinstance(op.getarg(0), ConstInt):
-                op = ResOperation(rop.NEW_ARRAY, [sizebox], op.result,
-                                  descr=op.getdescr())
-            self.make_varray(op.getdescr(), sizebox.getint(), op.result, op)
+                op = self.optimizer.copy_and_change(op, newargs=[sizebox])
+            self.make_varray(op.getdescr(), sizebox.getint(), op)
         else:
-            self.getvalue(op.result).ensure_nonnull()
+            self.getvalue(op).ensure_nonnull()
             self.emit_operation(op)
 
     def optimize_ARRAYLEN_GC(self, op):
@@ -540,7 +537,7 @@
                 )
                 if fieldvalue is None:
                     fieldvalue = self.new_const(descr)
-                self.make_equal_to(op.result, fieldvalue)
+                self.replace(op, fieldvalue.op)
                 return
         value.ensure_nonnull()
         self.emit_operation(op)


More information about the pypy-commit mailing list