[pypy-commit] pypy result-in-resops: implement copy and change, more cleanups

fijal noreply at buildbot.pypy.org
Wed Jul 25 16:39:07 CEST 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: result-in-resops
Changeset: r56449:d50041b95100
Date: 2012-07-25 16:38 +0200
http://bitbucket.org/pypy/pypy/changeset/d50041b95100/

Log:	implement copy and change, more cleanups

diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -1,7 +1,5 @@
 import weakref
 from pypy.rpython.lltypesystem import lltype
-from pypy.rpython.ootypesystem import ootype
-from pypy.objspace.flow.model import Constant, Variable
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.debug import debug_start, debug_stop, debug_print
 from pypy.rlib import rstack
@@ -9,12 +7,11 @@
 from pypy.conftest import option
 from pypy.tool.sourcetools import func_with_new_name
 
-from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.metainterp.history import TreeLoop, Box, History, JitCellToken, TargetToken
+from pypy.jit.metainterp.resoperation import rop, create_resop
+from pypy.jit.metainterp.history import TreeLoop, Box, JitCellToken, TargetToken
 from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt
-from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const, ConstInt
+from pypy.jit.metainterp.history import BoxPtr, BoxFloat, ConstInt
 from pypy.jit.metainterp import history
-from pypy.jit.metainterp.typesystem import llhelper, oohelper
 from pypy.jit.metainterp.optimize import InvalidLoop
 from pypy.jit.metainterp.inliner import Inliner
 from pypy.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP
@@ -114,16 +111,16 @@
 
     metainterp_sd = metainterp.staticdata
     jitdriver_sd = metainterp.jitdriver_sd
-    history = metainterp.history
 
     jitcell_token = make_jitcell_token(jitdriver_sd)
     part = create_empty_loop(metainterp)
     part.inputargs = inputargs[:]
-    h_ops = history.operations
+    h_ops = metainterp.history.operations
     part.resume_at_jump_descr = resume_at_jump_descr
-    part.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(jitcell_token))] + \
-                      [h_ops[i].clone() for i in range(start, len(h_ops))] + \
-                      [ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token)]
+    part.operations = ([create_resop(rop.LABEL, None, inputargs,
+                                     descr=TargetToken(jitcell_token))] +
+                       h_ops[start:] + [create_resop(rop.LABEL, None, jumpargs,
+                                                     descr=jitcell_token)])
 
     try:
         optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts)
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -736,10 +736,10 @@
                 if hasattr(op.getdescr(), '_debug_suboperations'):
                     ops = op.getdescr()._debug_suboperations
                     TreeLoop.check_consistency_of_branch(ops, seen.copy())
-                for box in op.getfailargs() or []:
-                    if box is not None:
-                        assert isinstance(box, Box)
-                        assert box in seen
+                for failarg in op.getfailargs() or []:
+                    if failarg is not None:
+                        assert not failarg.is_constant()
+                        assert failarg in seen
             else:
                 assert op.getfailargs() is None
             seen[op] = True
diff --git a/pypy/jit/metainterp/optimizeopt/__init__.py b/pypy/jit/metainterp/optimizeopt/__init__.py
--- a/pypy/jit/metainterp/optimizeopt/__init__.py
+++ b/pypy/jit/metainterp/optimizeopt/__init__.py
@@ -36,6 +36,7 @@
 def build_opt_chain(metainterp_sd, enable_opts):
     config = metainterp_sd.config
     optimizations = []
+    enable_opts = {}
     unroll = 'unroll' in enable_opts    # 'enable_opts' is normally a dict
     for name, opt in unroll_all_opts:
         if name in enable_opts:
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
@@ -51,12 +51,12 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1 is v2:
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
             return
         self.emit_operation(op)
         if v1.intbound.known_ge(IntBound(0, 0)) and \
            v2.intbound.known_ge(IntBound(0, 0)):
-            r = self.getvalue(op.result)
+            r = self.getvalue(op)
             r.intbound.make_ge(IntLowerBound(0))
 
     def optimize_INT_AND(self, op):
@@ -64,7 +64,7 @@
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
 
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if v2.is_constant():
             val = v2.box.getint()
             if val >= 0:
@@ -78,7 +78,7 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         b = v1.intbound.sub_bound(v2.intbound)
         if b.bounded():
             r.intbound.intersect(b)
@@ -96,7 +96,7 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         b = v1.intbound.mul_bound(v2.intbound)
         if b.bounded():
             r.intbound.intersect(b)
@@ -105,7 +105,7 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         r.intbound.intersect(v1.intbound.div_bound(v2.intbound))
 
     def optimize_INT_MOD(self, op):
@@ -123,7 +123,7 @@
         self.emit_operation(op)
         if v2.is_constant():
             val = v2.box.getint()
-            r = self.getvalue(op.result)
+            r = self.getvalue(op)
             if val < 0:
                 if val == -sys.maxint-1:
                     return     # give up
@@ -138,7 +138,7 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         b = v1.intbound.lshift_bound(v2.intbound)
         r.intbound.intersect(b)
         # intbound.lshift_bound checks for an overflow and if the
@@ -146,7 +146,7 @@
         # b.has_lower
         if b.has_lower and b.has_upper:
             # Synthesize the reverse op for optimize_default to reuse
-            self.pure(rop.INT_RSHIFT, [op.result, op.getarg(1)], op.getarg(0))
+            self.pure(rop.INT_RSHIFT, [op, op.getarg(1)], op.getarg(0))
 
     def optimize_INT_RSHIFT(self, op):
         v1 = self.getvalue(op.getarg(0))
@@ -154,10 +154,10 @@
         b = v1.intbound.rshift_bound(v2.intbound)
         if b.has_lower and b.has_upper and b.lower == b.upper:
             # constant result (likely 0, for rshifts that kill all bits)
-            self.make_constant_int(op.result, b.lower)
+            self.make_constant_int(op, b.lower)
         else:
             self.emit_operation(op)
-            r = self.getvalue(op.result)
+            r = self.getvalue(op)
             r.intbound.intersect(b)
 
     def optimize_GUARD_NO_OVERFLOW(self, op):
@@ -165,7 +165,7 @@
         if lastop is not None:
             opnum = lastop.getopnum()
             args = lastop.getarglist()
-            result = lastop.result
+            result = lastop
             # If the INT_xxx_OVF was replaced with INT_xxx, then we can kill
             # the GUARD_NO_OVERFLOW.
             if (opnum == rop.INT_ADD or
@@ -210,7 +210,7 @@
             # optimize_GUARD_OVERFLOW, then InvalidLoop.
             op = op.copy_and_change(rop.INT_ADD)
         self.emit_operation(op) # emit the op
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         r.intbound.intersect(resbound)
 
     def optimize_INT_SUB_OVF(self, op):
@@ -220,7 +220,7 @@
         if resbound.bounded():
             op = op.copy_and_change(rop.INT_SUB)
         self.emit_operation(op) # emit the op
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         r.intbound.intersect(resbound)
 
     def optimize_INT_MUL_OVF(self, op):
@@ -230,16 +230,16 @@
         if resbound.bounded():
             op = op.copy_and_change(rop.INT_MUL)
         self.emit_operation(op)
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         r.intbound.intersect(resbound)
 
     def optimize_INT_LT(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.intbound.known_lt(v2.intbound):
-            self.make_constant_int(op.result, 1)
+            self.make_constant_int(op, 1)
         elif v1.intbound.known_ge(v2.intbound) or v1 is v2:
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         else:
             self.emit_operation(op)
 
@@ -247,9 +247,9 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.intbound.known_gt(v2.intbound):
-            self.make_constant_int(op.result, 1)
+            self.make_constant_int(op, 1)
         elif v1.intbound.known_le(v2.intbound) or v1 is v2:
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         else:
             self.emit_operation(op)
 
@@ -257,9 +257,9 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.intbound.known_le(v2.intbound) or v1 is v2:
-            self.make_constant_int(op.result, 1)
+            self.make_constant_int(op, 1)
         elif v1.intbound.known_gt(v2.intbound):
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         else:
             self.emit_operation(op)
 
@@ -267,9 +267,9 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.intbound.known_ge(v2.intbound) or v1 is v2:
-            self.make_constant_int(op.result, 1)
+            self.make_constant_int(op, 1)
         elif v1.intbound.known_lt(v2.intbound):
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         else:
             self.emit_operation(op)
 
@@ -277,11 +277,11 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.intbound.known_gt(v2.intbound):
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         elif v1.intbound.known_lt(v2.intbound):
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         elif v1 is v2:
-            self.make_constant_int(op.result, 1)
+            self.make_constant_int(op, 1)
         else:
             self.emit_operation(op)
 
@@ -289,18 +289,18 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.intbound.known_gt(v2.intbound):
-            self.make_constant_int(op.result, 1)
+            self.make_constant_int(op, 1)
         elif v1.intbound.known_lt(v2.intbound):
-            self.make_constant_int(op.result, 1)
+            self.make_constant_int(op, 1)
         elif v1 is v2:
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         else:
             self.emit_operation(op)
 
     def optimize_ARRAYLEN_GC(self, op):
         self.emit_operation(op)
         array  = self.getvalue(op.getarg(0))
-        result = self.getvalue(op.result)
+        result = self.getvalue(op)
         array.make_len_gt(MODE_ARRAY, op.getdescr(), -1)
         array.lenbound.bound.intersect(result.intbound)
         result.intbound = array.lenbound.bound
@@ -308,7 +308,7 @@
     def optimize_STRLEN(self, op):
         self.emit_operation(op)
         array  = self.getvalue(op.getarg(0))
-        result = self.getvalue(op.result)
+        result = self.getvalue(op)
         array.make_len_gt(MODE_STR, op.getdescr(), -1)
         array.lenbound.bound.intersect(result.intbound)
         result.intbound = array.lenbound.bound
@@ -316,20 +316,20 @@
     def optimize_UNICODELEN(self, op):
         self.emit_operation(op)
         array  = self.getvalue(op.getarg(0))
-        result = self.getvalue(op.result)
+        result = self.getvalue(op)
         array.make_len_gt(MODE_UNICODE, op.getdescr(), -1)
         array.lenbound.bound.intersect(result.intbound)
         result.intbound = array.lenbound.bound
 
     def optimize_STRGETITEM(self, op):
         self.emit_operation(op)
-        v1 = self.getvalue(op.result)
+        v1 = self.getvalue(op)
         v1.intbound.make_ge(IntLowerBound(0))
         v1.intbound.make_lt(IntUpperBound(256))
 
     def optimize_UNICODEGETITEM(self, op):
         self.emit_operation(op)
-        v1 = self.getvalue(op.result)
+        v1 = self.getvalue(op)
         v1.intbound.make_ge(IntLowerBound(0))
 
     def make_int_lt(self, box1, box2):
@@ -355,7 +355,7 @@
         self.make_int_le(box2, box1)
 
     def propagate_bounds_INT_LT(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 self.make_int_lt(op.getarg(0), op.getarg(1))
@@ -363,7 +363,7 @@
                 self.make_int_ge(op.getarg(0), op.getarg(1))
 
     def propagate_bounds_INT_GT(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 self.make_int_gt(op.getarg(0), op.getarg(1))
@@ -371,7 +371,7 @@
                 self.make_int_le(op.getarg(0), op.getarg(1))
 
     def propagate_bounds_INT_LE(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 self.make_int_le(op.getarg(0), op.getarg(1))
@@ -379,7 +379,7 @@
                 self.make_int_gt(op.getarg(0), op.getarg(1))
 
     def propagate_bounds_INT_GE(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 self.make_int_ge(op.getarg(0), op.getarg(1))
@@ -387,7 +387,7 @@
                 self.make_int_lt(op.getarg(0), op.getarg(1))
 
     def propagate_bounds_INT_EQ(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 v1 = self.getvalue(op.getarg(0))
@@ -398,7 +398,7 @@
                     self.propagate_bounds_backward(op.getarg(1))
 
     def propagate_bounds_INT_NE(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_0):
                 v1 = self.getvalue(op.getarg(0))
@@ -409,7 +409,7 @@
                     self.propagate_bounds_backward(op.getarg(1))
 
     def propagate_bounds_INT_IS_TRUE(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 v1 = self.getvalue(op.getarg(0))
@@ -418,7 +418,7 @@
                     self.propagate_bounds_backward(op.getarg(0))
 
     def propagate_bounds_INT_IS_ZERO(self, op):
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 v1 = self.getvalue(op.getarg(0))
@@ -432,7 +432,7 @@
     def propagate_bounds_INT_ADD(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         b = r.intbound.sub_bound(v2.intbound)
         if v1.intbound.intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
@@ -443,7 +443,7 @@
     def propagate_bounds_INT_SUB(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         b = r.intbound.add_bound(v2.intbound)
         if v1.intbound.intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
@@ -454,7 +454,7 @@
     def propagate_bounds_INT_MUL(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         b = r.intbound.div_bound(v2.intbound)
         if v1.intbound.intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
@@ -465,7 +465,7 @@
     def propagate_bounds_INT_LSHIFT(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        r = self.getvalue(op.result)
+        r = self.getvalue(op)
         b = r.intbound.rshift_bound(v2.intbound)
         if v1.intbound.intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
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
@@ -293,9 +293,9 @@
     def new_const_item(self, arraydescr):
         return self.optimizer.new_const_item(arraydescr)
 
-    def pure(self, opnum, args, result):
+    def pure(self, opnum, result, arg0, arg1):
         if self.optimizer.optpure:
-            self.optimizer.optpure.pure(opnum, args, result)
+            self.optimizer.optpure.pure(opnum, result, arg0, arg1)
 
     def has_pure_result(self, opnum, args, descr):
         if self.optimizer.optpure:
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
+from pypy.jit.metainterp.resoperation import rop, create_resop_2
 from pypy.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
     args_dict)
 
@@ -52,7 +52,7 @@
         # otherwise, the operation remains
         self.emit_operation(op)
         if op.returns_bool_result():
-            self.optimizer.bool_boxes[self.getvalue(op.result)] = None        
+            self.optimizer.bool_boxes[self.getvalue(op)] = None        
         if nextop:
             self.emit_operation(nextop)
 
@@ -95,8 +95,8 @@
     def setup(self):
         self.optimizer.optpure = self
 
-    def pure(self, opnum, arg0, arg1, result):
-        op = create_resopt_2(opnum, args, result)
+    def pure(self, opnum, result, arg0, arg1):
+        op = create_resop_2(opnum, result, arg0, arg1)
         key = self.optimizer.make_args_key(op)
         if key not in self.pure_operations:
             self.pure_operations[key] = op
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
@@ -33,19 +33,22 @@
     def try_boolinvers(self, op, targs):
         oldop = self.get_pure_result(targs)
         if oldop is not None and oldop.getdescr() is op.getdescr():
-            value = self.getvalue(oldop.result)
+            value = self.getvalue(oldop)
             if value.is_constant():
                 if value.box.same_constant(CONST_1):
-                    self.make_constant(op.result, CONST_0)
+                    self.make_constant(op, CONST_0)
                     return True
                 elif value.box.same_constant(CONST_0):
-                    self.make_constant(op.result, CONST_1)
+                    self.make_constant(op, CONST_1)
                     return True
 
         return False
 
 
     def find_rewritable_bool(self, op, args):
+        # XXXX
+        return False
+        
         try:
             oldopnum = opboolinvers[op.getopnum()]
         except KeyError:
@@ -65,7 +68,7 @@
                                                               None))
             oldop = self.get_pure_result(targs)
             if oldop is not None and oldop.getdescr() is op.getdescr():
-                self.make_equal_to(op.result, self.getvalue(oldop.result))
+                self.make_equal_to(op, self.getvalue(oldop))
                 return True
 
         try:
@@ -84,7 +87,7 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.is_null() or v2.is_null():
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         else:
             self.emit_operation(op)
 
@@ -92,9 +95,9 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v1.is_null():
-            self.make_equal_to(op.result, v2)
+            self.make_equal_to(op, v2)
         elif v2.is_null():
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
         else:
             self.emit_operation(op)
 
@@ -102,12 +105,12 @@
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         if v2.is_constant() and v2.box.getint() == 0:
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
         else:
             self.emit_operation(op)
             # Synthesize the reverse ops for optimize_default to reuse
-            self.pure(rop.INT_ADD, [op.result, op.getarg(1)], op.getarg(0))
-            self.pure(rop.INT_SUB, [op.getarg(0), op.result], op.getarg(1))
+            self.pure(rop.INT_ADD, op.getarg(0), op, op.getarg(1))
+            self.pure(rop.INT_SUB, op.getarg(1), op.getarg(0), op)
 
     def optimize_INT_ADD(self, op):
         v1 = self.getvalue(op.getarg(0))
@@ -115,9 +118,9 @@
 
         # If one side of the op is 0 the result is the other side.
         if v1.is_constant() and v1.box.getint() == 0:
-            self.make_equal_to(op.result, v2)
+            self.make_equal_to(op, v2)
         elif v2.is_constant() and v2.box.getint() == 0:
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
         else:
             self.emit_operation(op)
             # Synthesize the reverse op for optimize_default to reuse
@@ -131,12 +134,12 @@
 
         # If one side of the op is 1 the result is the other side.
         if v1.is_constant() and v1.box.getint() == 1:
-            self.make_equal_to(op.result, v2)
+            self.make_equal_to(op, v2)
         elif v2.is_constant() and v2.box.getint() == 1:
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
         elif (v1.is_constant() and v1.box.getint() == 0) or \
              (v2.is_constant() and v2.box.getint() == 0):
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
         else:
             for lhs, rhs in [(v1, v2), (v2, v1)]:
                 if lhs.is_constant():
@@ -153,7 +156,7 @@
         v2 = self.getvalue(op.getarg(1))
 
         if v2.is_constant() and v2.box.getint() == 1:
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
         else:
             self.emit_operation(op)
 
@@ -162,7 +165,7 @@
         v2 = self.getvalue(op.getarg(1))
 
         if v2.is_constant() and v2.box.getint() == 0:
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
         else:
             self.emit_operation(op)
 
@@ -171,7 +174,7 @@
         v2 = self.getvalue(op.getarg(1))
 
         if v2.is_constant() and v2.box.getint() == 0:
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
         else:
             self.emit_operation(op)
 
@@ -187,20 +190,20 @@
 
             if v1.is_constant():
                 if v1.box.getfloat() == 1.0:
-                    self.make_equal_to(op.result, v2)
+                    self.make_equal_to(op, v2)
                     return
                 elif v1.box.getfloat() == -1.0:
                     self.emit_operation(ResOperation(
-                        rop.FLOAT_NEG, [rhs], op.result
+                        rop.FLOAT_NEG, [rhs], op
                     ))
                     return
         self.emit_operation(op)
-        self.pure(rop.FLOAT_MUL, [arg2, arg1], op.result)
+        self.pure(rop.FLOAT_MUL, [arg2, arg1], op)
 
     def optimize_FLOAT_NEG(self, op):
         v1 = op.getarg(0)
         self.emit_operation(op)
-        self.pure(rop.FLOAT_NEG, [op.result], v1)
+        self.pure(rop.FLOAT_NEG, [op], v1)
 
     def optimize_guard(self, op, constbox, emit_operation=True):
         value = self.getvalue(op.getarg(0))
@@ -327,7 +330,7 @@
 
         resvalue = self.loop_invariant_results.get(key, None)
         if resvalue is not None:
-            self.make_equal_to(op.result, resvalue)
+            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
@@ -335,7 +338,7 @@
         self.loop_invariant_producer[key] = op
         op = op.copy_and_change(rop.CALL)
         self.emit_operation(op)
-        resvalue = self.getvalue(op.result)
+        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
@@ -344,15 +347,15 @@
     def _optimize_nullness(self, op, box, expect_nonnull):
         value = self.getvalue(box)
         if value.is_nonnull():
-            self.make_constant_int(op.result, expect_nonnull)
+            self.make_constant_int(op, expect_nonnull)
         elif value.is_null():
-            self.make_constant_int(op.result, not expect_nonnull)
+            self.make_constant_int(op, not expect_nonnull)
         else:
             self.emit_operation(op)
 
     def optimize_INT_IS_TRUE(self, op):
         if self.getvalue(op.getarg(0)) in self.optimizer.bool_boxes:
-            self.make_equal_to(op.result, self.getvalue(op.getarg(0)))
+            self.make_equal_to(op, self.getvalue(op.getarg(0)))
             return
         self._optimize_nullness(op, op.getarg(0), True)
 
@@ -365,17 +368,17 @@
         if value0.is_virtual():
             if value1.is_virtual():
                 intres = (value0 is value1) ^ expect_isnot
-                self.make_constant_int(op.result, intres)
+                self.make_constant_int(op, intres)
             else:
-                self.make_constant_int(op.result, expect_isnot)
+                self.make_constant_int(op, expect_isnot)
         elif value1.is_virtual():
-            self.make_constant_int(op.result, expect_isnot)
+            self.make_constant_int(op, expect_isnot)
         elif value1.is_null():
             self._optimize_nullness(op, op.getarg(0), expect_isnot)
         elif value0.is_null():
             self._optimize_nullness(op, op.getarg(1), expect_isnot)
         elif value0 is value1:
-            self.make_constant_int(op.result, not expect_isnot)
+            self.make_constant_int(op, not expect_isnot)
         else:
             if instance:
                 cls0 = value0.get_constant_class(self.optimizer.cpu)
@@ -384,7 +387,7 @@
                     if cls1 is not None and not cls0.same_constant(cls1):
                         # cannot be the same object, as we know that their
                         # class is different
-                        self.make_constant_int(op.result, expect_isnot)
+                        self.make_constant_int(op, expect_isnot)
                         return
             self.emit_operation(op)
 
@@ -408,7 +411,7 @@
 ##            result = self.optimizer.cpu.ts.subclassOf(self.optimizer.cpu,
 ##                                                      realclassbox,
 ##                                                      checkclassbox)
-##            self.make_constant_int(op.result, result)
+##            self.make_constant_int(op, result)
 ##            return
 ##        self.emit_operation(op)
 
@@ -470,7 +473,7 @@
                 pass
             else:
                 # this removes a CALL_PURE with all constant arguments.
-                self.make_constant(op.result, result)
+                self.make_constant(op, result)
                 self.last_emitted_operation = REMOVED
                 return
         self.emit_operation(op)
@@ -490,10 +493,10 @@
         v2 = self.getvalue(op.getarg(1))
 
         if v2.is_constant() and v2.box.getint() == 1:
-            self.make_equal_to(op.result, v1)
+            self.make_equal_to(op, v1)
             return
         elif v1.is_constant() and v1.box.getint() == 0:
-            self.make_constant_int(op.result, 0)
+            self.make_constant_int(op, 0)
             return
         if v1.intbound.known_ge(IntBound(0, 0)) and v2.is_constant():
             val = v2.box.getint()
@@ -503,15 +506,15 @@
         self.emit_operation(op)
 
     def optimize_CAST_PTR_TO_INT(self, op):
-        self.pure(rop.CAST_INT_TO_PTR, [op.result], op.getarg(0))
+        self.pure(rop.CAST_INT_TO_PTR, [op], op.getarg(0))
         self.emit_operation(op)
 
     def optimize_CAST_INT_TO_PTR(self, op):
-        self.pure(rop.CAST_PTR_TO_INT, [op.result], op.getarg(0))
+        self.pure(rop.CAST_PTR_TO_INT, [op], op.getarg(0))
         self.emit_operation(op)
 
     def optimize_SAME_AS_i(self, op):
-        self.make_equal_to(op.result, self.getvalue(op.getarg(0)))
+        self.make_equal_to(op, self.getvalue(op.getarg(0)))
     optimize_SAME_AS_p = optimize_SAME_AS_i
     optimize_SAME_AS_f = optimize_SAME_AS_i
 
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -32,7 +32,7 @@
 
     def emit_operation(self, op):
         if op.returns_bool_result():
-            self.bool_boxes[self.getvalue(op.result)] = None
+            self.bool_boxes[self.getvalue(op)] = None
         if self.emitting_dissabled:
             return
         if op.is_guard():
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1050,7 +1050,8 @@
         loc = jitdriver_sd.warmstate.get_location_str(greenkey)
         debug_print(loc)
         args = [ConstInt(jd_index), ConstInt(portal_call_depth), ConstInt(current_call_id)] + greenkey
-        self.metainterp.history.record(rop.DEBUG_MERGE_POINT, args, None)
+        dmp = create_resop(rop.DEBUG_MERGE_POINT, None, args)
+        self.metainterp.history.record(dmp)
 
     @arguments("box", "label")
     def opimpl_goto_if_exception_mismatch(self, vtablebox, next_exc_target):
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
@@ -112,17 +112,6 @@
         op.setdescr(descr)
     return op
 
-def copy_and_change(self, opnum, args=None, result=None, descr=None):
-    "shallow copy: the returned operation is meant to be used in place of self"
-    if args is None:
-        args = self.getarglist()
-    if result is None:
-        result = self.result
-    if descr is None:
-        descr = self.getdescr()
-    newop = ResOperation(opnum, args, result, descr)
-    return newop
-
 class AbstractValue(object):
     __slots__ = ()
 
@@ -336,6 +325,10 @@
             return False     # for tests
         return opboolresult[opnum]
 
+# ===========
+# type mixins
+# ===========
+
 class ResOpNone(object):
     _mixin_ = True
     type = VOID
@@ -491,6 +484,14 @@
             r.setfailargs(self.getfailargs())
         return r
 
+    @specialize.arg(1)
+    def copy_and_change(self, newopnum):
+        r = create_resop_0(newopnum, self.getresult(), self.getdescrclone())
+        if r.is_guard():
+            r.setfailargs(self.getfailargs())
+            assert self.is_guard()
+        return r
+
     def copy_if_modified_by_optimization(self, opt):
         return self
 
@@ -534,6 +535,15 @@
         return create_resop_1(self.opnum, self.getresult(), new_arg,
                               self.getdescrclone())
 
+    @specialize.arg(1)
+    def copy_and_change(self, newopnum, arg0=None):
+        r = create_resop_1(newopnum, self.getresult(), arg0 or self._arg0,
+                           self.getdescrclone())
+        if r.is_guard():
+            r.setfailargs(self.getfailargs())
+            assert self.is_guard()
+        return r
+
 class BinaryOp(object):
     _mixin_ = True
     _arg0 = None
@@ -581,6 +591,15 @@
                               new_arg1 or self._arg1,
                               self.getdescrclone())
 
+    @specialize.arg(1)
+    def copy_and_change(self, newopnum, arg0=None, arg1=None):
+        r = create_resop_2(newopnum, self.getresult(), arg0 or self._arg0,
+                           arg1 or self._arg1,
+                           self.getdescrclone())
+        if r.is_guard():
+            r.setfailargs(self.getfailargs())
+            assert self.is_guard()
+        return r
 
 class TernaryOp(object):
     _mixin_ = True
@@ -622,6 +641,7 @@
                               self._arg1, self._arg2, self.getdescrclone())
 
     def copy_if_modified_by_optimization(self, opt):
+        assert not self.is_guard()
         new_arg0 = opt.get_value_replacement(self._arg0)
         new_arg1 = opt.get_value_replacement(self._arg1)
         new_arg2 = opt.get_value_replacement(self._arg2)
@@ -633,6 +653,13 @@
                               new_arg2 or self._arg2,
                               self.getdescrclone())
 
+    @specialize.arg(1)
+    def copy_and_change(self, newopnum, arg0=None, arg1=None, arg2=None):
+        r = create_resop_3(newopnum, self.getresult(), arg0 or self._arg0,
+                           arg1 or self._arg1, arg2 or self._arg2,
+                           self.getdescrclone())
+        assert not r.is_guard()
+        return r
 
 class N_aryOp(object):
     _mixin_ = True
@@ -680,6 +707,13 @@
         return create_resop(self.opnum, self.getresult(),
                             newargs, self.getdescrclone())
 
+    @specialize.arg(1)
+    def copy_and_change(self, newopnum, newargs=None):
+        r = create_resop(newopnum, self.getresult(),
+                         newargs or self.getarglist(), self.getdescrclone())
+        assert not r.is_guard()
+        return r
+
 # ____________________________________________________________
 
 _oplist = [
diff --git a/pypy/jit/metainterp/test/test_resoperation.py b/pypy/jit/metainterp/test/test_resoperation.py
--- a/pypy/jit/metainterp/test/test_resoperation.py
+++ b/pypy/jit/metainterp/test/test_resoperation.py
@@ -7,6 +7,8 @@
         self.v = v
 
     def __eq__(self, other):
+        if isinstance(other, str):
+            return self.v == other
         return self.v == other.v
 
     def __ne__(self, other):
@@ -184,3 +186,32 @@
     assert op2 is not op
     assert op2.getarglist() == [FakeBox("a"), FakeBox("rrr"), FakeBox("c")]
     assert op2.getdescr() == mydescr
+
+def test_copy_and_change():    
+    op = rop.create_resop_1(rop.rop.INT_IS_ZERO, 1, FakeBox('a'))
+    op2 = op.copy_and_change(rop.rop.INT_IS_TRUE)
+    assert op2.opnum == rop.rop.INT_IS_TRUE
+    assert op2.getarg(0) == FakeBox('a')
+    op2 = op.copy_and_change(rop.rop.INT_IS_TRUE, FakeBox('b'))
+    assert op2.opnum == rop.rop.INT_IS_TRUE
+    assert op2.getarg(0) == FakeBox('b')
+    assert op2 is not op
+    op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b"))
+    op2 = op.copy_and_change(rop.rop.INT_SUB)
+    assert op2.opnum == rop.rop.INT_SUB
+    assert op2.getarglist() == [FakeBox("a"), FakeBox("b")]
+    op2 = op.copy_and_change(rop.rop.INT_SUB, None, FakeBox("c"))
+    assert op2.opnum == rop.rop.INT_SUB
+    assert op2.getarglist() == [FakeBox("a"), FakeBox("c")]
+    op = rop.create_resop_3(rop.rop.STRSETITEM, None, FakeBox('a'),
+                            FakeBox('b'), FakeBox('c'))
+    op2 = op.copy_and_change(rop.rop.UNICODESETITEM, None, FakeBox("c"))
+    assert op2.opnum == rop.rop.UNICODESETITEM
+    assert op2.getarglist() == [FakeBox("a"), FakeBox("c"), FakeBox("c")]    
+    mydescr = FakeDescr()
+    op = rop.create_resop(rop.rop.CALL_PURE_i, 13, [FakeBox('a'), FakeBox('b'),
+                            FakeBox('c')], descr=mydescr)
+    op2 = op.copy_and_change(rop.rop.CALL_i)
+    assert op2.getarglist() == ['a', 'b', 'c']
+    op2 = op.copy_and_change(rop.rop.CALL_i, [FakeBox('a')])
+    assert op2.getarglist() == ['a']


More information about the pypy-commit mailing list