1. Pypy
  2. Untitled project
  3. pypy

Commits

Daniel Roberts  committed 4a04352

Added support for folding int_sub(ConstInt(*), i*)

  • Participants
  • Parent commits 386510d
  • Branches fold_intadd

Comments (0)

Files changed (2)

File pypy/jit/metainterp/optimizeopt/addition.py

View file
  • Ignore whitespace
 from pypy.jit.metainterp.optimizeopt.optimizer import *
-from pypy.jit.metainterp.resoperation import opboolinvers, opboolreflex
 from pypy.jit.metainterp.history import ConstInt
 from pypy.jit.metainterp.optimizeutil import _findall
 from pypy.jit.metainterp.resoperation import rop, ResOperation
-from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.jit.metainterp.optimizeopt.intutils import IntBound
-from pypy.rlib.rarithmetic import highest_bit
 
 class OptAddition(Optimization):
     def __init__(self):
-        self.args = {}
+        self.loperands = {}
+        self.roperands = {} # roperands is only for int_sub(ConstInt(*), i*)
+                            # and cases deriving from that
 
     def reconstruct_for_next_iteration(self, optimizer, valuemap):
         return OptAddition()
             constant = ConstInt(constant)
             return ResOperation(rop.INT_ADD, [variable, constant], result)
 
-    def _process_add(self, variable, constant, result):
+    def _process_add(self, constant, variable, result):
+        # int_add(ConstInt(*), int_sub(ConstInt(*), i*))
         try:
-            root, stored_constant = self.args[variable]
+            stored_constant, root = self.roperands[variable]
+            constant = constant + stored_constant
+
+            self.roperands[result] = constant, root
+
+            boxed_constant = ConstInt(constant)
+            new_op = ResOperation(rop.INT_SUB, [boxed_constant, variable], result)
+            self.emit_operation(new_op)
+            return
+        except KeyError:
+            pass
+
+        # int_add(ConstInt(*), int_add(ConstInt(*), i*))
+        try:
+            root, stored_constant = self.loperands[variable]
             constant = constant + stored_constant
         except KeyError:
             root = variable
 
-        self.args[result] = root, constant
+        self.loperands[result] = root, constant
 
         new_op = self._int_operation(root, constant, result)
         self.emit_operation(new_op)
 
+    def _process_sub(self, constant, variable, result):
+        # int_sub(ConstInt(*), int_sub(ConstInt(*), i*))
+        try:
+            stored_constant, root = self.roperands[variable]
+            constant = constant - stored_constant
+
+            self.loperands[result] = root, constant
+
+            new_op = self._int_operation(root, constant, result)
+            self.emit_operation(new_op)
+            return
+        except KeyError:
+            pass
+
+        # int_sub(ConstInt(*), int_add(ConstInt(*), i*))
+        try:
+            root, stored_constant = self.loperands[variable]
+            constant = constant - stored_constant
+        except KeyError:
+            root = variable
+
+        self.roperands[result] = constant, root
+
+        constant = ConstInt(constant)
+        new_op = ResOperation(rop.INT_SUB, [constant, root], result)
+        self.emit_operation(new_op)
+
     def optimize_INT_ADD(self, op):
         lv = self.getvalue(op.getarg(0))
         rv = self.getvalue(op.getarg(1))
             self.emit_operation(op) # XXX: there's support for optimizing this elsewhere, right?
         elif lv.is_constant():
             constant = lv.box.getint()
-            self._process_add(op.getarg(1), constant, result)
+            self._process_add(constant, op.getarg(1), result)
         elif rv.is_constant():
             constant = rv.box.getint()
-            self._process_add(op.getarg(0), constant, result)
+            self._process_add(constant, op.getarg(0), result)
         else:
             self.emit_operation(op)
 
         if lv.is_constant() and rv.is_constant():
             self.emit_operation(op) # XXX: there's support for optimizing this elsewhere, right?
         elif lv.is_constant():
-            # TODO: implement?
-            self.emit_operation(op)
+            constant = lv.box.getint()
+            self._process_sub(constant, op.getarg(1), result)
+            #self.emit_operation(op)
         elif rv.is_constant():
             constant = rv.box.getint()
-            self._process_add(op.getarg(0), -constant, result)
+            self._process_add(-constant, op.getarg(0), result)
         else:
             self.emit_operation(op)
 

File pypy/jit/metainterp/test/test_optimizeopt.py

View file
  • Ignore whitespace
         """
         self.optimize_loop(ops, expected)
 
+    def test_fold_backwards_sub(self):
+        ops = """
+        [i0]
+        i1 = int_add(i0, 3)
+        i2 = int_sub(4, i1)
+        i3 = int_sub(i2, 14)
+        i4 = int_add(6, i2)
+        jump(i3)
+        """
+
+        expected = """
+        [i0]
+        i1 = int_add(i0, 3)
+        i2 = int_sub(1, i0)
+        i3 = int_sub(i0, 13)
+        i4 = int_sub(7, i0)
+        jump(i3)
+        """
 
 ##class TestOOtype(OptimizeOptTest, OOtypeMixin):