[pypy-commit] pypy array-propagate-len: add optimization, move stuff around

squeaky noreply at buildbot.pypy.org
Sat Feb 15 18:21:17 CET 2014


Author: Squeaky <squeaky_pl at gmx.com>
Branch: array-propagate-len
Changeset: r69154:17003c30fe47
Date: 2014-02-14 19:23 +0100
http://bitbucket.org/pypy/pypy/changeset/17003c30fe47/

Log:	add optimization, move stuff around

diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -1,10 +1,12 @@
 import py, weakref
 from rpython.jit.backend import model
 from rpython.jit.backend.llgraph import support
+from rpython.jit.backend.llsupport import symbolic
 from rpython.jit.metainterp.history import AbstractDescr
 from rpython.jit.metainterp.history import Const, getkind
 from rpython.jit.metainterp.history import INT, REF, FLOAT, VOID
 from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.metainterp.optimizeopt import intbounds
 from rpython.jit.codewriter import longlong, heaptracker
 from rpython.jit.codewriter.effectinfo import EffectInfo
 
@@ -119,6 +121,24 @@
     def is_field_signed(self):
         return _is_signed_kind(self.FIELD)
 
+    def is_integer_bounded(self):
+        return getkind(self.FIELD) == 'int' \
+            and rffi.sizeof(self.FIELD) < symbolic.WORD
+
+    def get_integer_min(self):
+        if getkind(self.FIELD) != 'int':
+            assert False
+
+        return intbounds.get_integer_min(
+            not _is_signed_kind(self.FIELD), rffi.sizeof(self.FIELD))
+
+    def get_integer_max(self):
+        if getkind(self.FIELD) != 'int':
+            assert False
+
+        return intbounds.get_integer_max(
+            not _is_signed_kind(self.FIELD), rffi.sizeof(self.FIELD))
+
 def _is_signed_kind(TYPE):
     return (TYPE is not lltype.Bool and isinstance(TYPE, lltype.Number) and
             rffi.cast(TYPE, -1) == -1)
diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py
--- a/rpython/jit/backend/llsupport/descr.py
+++ b/rpython/jit/backend/llsupport/descr.py
@@ -6,6 +6,7 @@
 from rpython.jit.metainterp import history
 from rpython.jit.codewriter import heaptracker, longlong
 from rpython.jit.codewriter.longlong import is_longlong
+from rpython.jit.metainterp.optimizeopt import intbounds
 
 
 class GcCache(object):
@@ -109,17 +110,17 @@
 
     def get_integer_min(self):
         if self.flag == FLAG_UNSIGNED:
-            return 0
+            return intbounds.get_integer_min(True, self.field_size)
         elif self.flag == FLAG_SIGNED:
-            return -(1 << ((self.field_size << 3) - 1))
+            return intbounds.get_integer_min(False, self.field_size)
 
         assert False
 
     def get_integer_max(self):
         if self.flag == FLAG_UNSIGNED:
-            return (1 << (self.field_size << 3)) - 1
+            return intbounds.get_integer_max(True, self.field_size)
         elif self.flag == FLAG_SIGNED:
-            return (1 << ((self.field_size << 3) - 1)) - 1
+            return intbounds.get_integer_max(False, self.field_size)
 
         assert False
 
diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -9,6 +9,20 @@
 from rpython.jit.metainterp.resoperation import rop
 
 
+def get_integer_min(is_unsigned, byte_size):
+    if is_unsigned:
+        return 0
+    else:
+        return -(1 << ((byte_size << 3) - 1))
+
+
+def get_integer_max(is_unsigned, byte_size):
+    if is_unsigned:
+        return (1 << (byte_size << 3)) - 1
+    else:
+        return (1 << ((byte_size << 3) - 1)) - 1
+
+
 class OptIntBounds(Optimization):
     """Keeps track of the bounds placed on integers by guards and remove
        redundant guards"""
@@ -322,6 +336,14 @@
         v1.intbound.make_ge(IntLowerBound(0))
         v1.intbound.make_lt(IntUpperBound(256))
 
+    def optimize_GETFIELD_GC(self, op):
+        self.emit_operation(op)
+        descr = op.getdescr()
+        if descr.is_integer_bounded():
+            v1 = self.getvalue(op.result)
+            v1.intbound.make_ge(IntLowerBound(descr.get_integer_min()))
+            v1.intbound.make_lt(IntUpperBound(descr.get_integer_max() + 1))
+
     def optimize_UNICODEGETITEM(self, op):
         self.emit_operation(op)
         v1 = self.getvalue(op.result)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -5200,7 +5200,7 @@
         """
         self.optimize_loop(ops, ops)
 
-    def test_cmp_outside_intbounds(self):
+    def test_getfield_cmp_outside_intbounds(self):
         ops = """
         [p0]
         i0 = getfield_gc(p0, descr=chardescr)


More information about the pypy-commit mailing list