Commits

Carl Friedrich Bolz committed 1bab583

when the optimizer sees an int_tag operation, it can later remove the
int_and(x, 1) operation because it knows the int is tagged.

Comments (0)

Files changed (3)

pypy/jit/metainterp/optimizeopt/intbounds.py

     def optimize_INT_AND(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
+        if (self.optimizer.metainterp_sd.config.translation.taggedpointers and
+                v2.is_constant() and v2.box.getint() == 1):
+            if self.has_pure_result(rop.INT_UNTAG, [v1.box], None):
+                # the result of untagging the int is known, so the box must be
+                # tagged, so int_and(x, 1) == 1
+                value = self.getvalue(ConstInt(1))
+                self.optimizer.make_equal_to(op.result, value)
+                return
         self.emit_operation(op)
 
         r = self.getvalue(op.result)

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

         """
         self.optimize_loop(ops, expected)
 
+    def test_int_tag_removes_int_and(self):
+        ops = """
+        [i0]
+        i1 = int_tag_ovf(i0)
+        guard_no_overflow() []
+        i2 = int_and(i1, 1)
+        i3 = int_is_true(i2)
+        guard_true(i3) []
+        i4 = int_untag(i1)
+        i5 = int_add(i4, 1)
+        jump(i5)
+        """
+        expected = """
+        [i0]
+        i1 = int_tag_ovf(i0)
+        guard_no_overflow() []
+        i2 = int_add(i0, 1)
+        jump(i2)
+        """
+        self.optimize_loop(ops, expected)
+
+
     def test_mul_ovf(self):
         ops = """
         [i0, i1]

pypy/jit/metainterp/optimizeopt/test/test_util.py

         self.globaldata = Fake()
         self.config = get_pypy_config(translating=True)
         self.config.translation.jit_ffi = True
+        self.config.translation.taggedpointers = True
 
     class warmrunnerdesc:
         class memory_manager: