[pypy-commit] pypy default: Try to slim optvalues by splitting them into IntOptValue and PtrOptValue

fijal noreply at buildbot.pypy.org
Sun Dec 21 11:34:18 CET 2014


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r75045:e0c704d662ec
Date: 2014-12-21 12:34 +0200
http://bitbucket.org/pypy/pypy/changeset/e0c704d662ec/

Log:	Try to slim optvalues by splitting them into IntOptValue and
	PtrOptValue

diff --git a/rpython/jit/metainterp/optimizeopt/generalize.py b/rpython/jit/metainterp/optimizeopt/generalize.py
--- a/rpython/jit/metainterp/optimizeopt/generalize.py
+++ b/rpython/jit/metainterp/optimizeopt/generalize.py
@@ -1,4 +1,5 @@
-from rpython.jit.metainterp.optimizeopt.optimizer import MININT, MAXINT
+from rpython.jit.metainterp.optimizeopt.optimizer import MININT, MAXINT,\
+     IntOptValue
 
 
 class GeneralizationStrategy(object):
@@ -14,7 +15,8 @@
         for v in self.optimizer.values.values():
             if v.is_constant():
                 continue
-            if v.intbound.lower < MININT / 2:
-                v.intbound.lower = MININT
-            if v.intbound.upper > MAXINT / 2:
-                v.intbound.upper = MAXINT
+            if isinstance(v, IntOptValue):
+                if v.intbound.lower < MININT / 2:
+                    v.intbound.lower = MININT
+                if v.intbound.upper > MAXINT / 2:
+                    v.intbound.upper = MAXINT
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -383,7 +383,7 @@
         except KeyError:
             return
         for idx, cf in submap.iteritems():
-            if indexvalue is None or indexvalue.intbound.contains(idx):
+            if indexvalue is None or indexvalue.getintbound().contains(idx):
                 cf.force_lazy_setfield(self, can_cache)
 
     def _assert_valid_cf(self, cf):
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
@@ -4,7 +4,7 @@
 from rpython.jit.metainterp.optimizeopt.intutils import (IntBound, IntLowerBound,
     IntUpperBound)
 from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, CONST_1,
-    CONST_0, MODE_ARRAY, MODE_STR, MODE_UNICODE)
+    CONST_0, MODE_ARRAY, MODE_STR, MODE_UNICODE, IntOptValue)
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.backend.llsupport import symbolic
@@ -54,7 +54,9 @@
         #        but the bounds produced by all instructions where box is
         #        an argument might also be tighten
         v = self.getvalue(box)
-        b = v.intbound
+        b = v.getintbound()
+        if b is None:
+            return # pointer
         if b.has_lower and b.has_upper and b.lower == b.upper:
             v.make_constant(ConstInt(b.lower))
 
@@ -81,11 +83,13 @@
                 self.make_constant_int(op.result, 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)
-            mostsignificant = v1.intbound.upper | v2.intbound.upper
-            r.intbound.intersect(IntBound(0, next_pow2_m1(mostsignificant)))
+        bound1 = v1.getintbound()
+        bound2 = v2.getintbound()
+        if bound1.known_ge(IntBound(0, 0)) and \
+           bound2.known_ge(IntBound(0, 0)):
+            r = self.getvalue(op.result).getintbound()
+            mostsignificant = bound1.upper | bound2.upper
+            r.intersect(IntBound(0, next_pow2_m1(mostsignificant)))
 
     optimize_INT_OR = optimize_INT_OR_or_XOR
     optimize_INT_XOR = optimize_INT_OR_or_XOR
@@ -99,55 +103,55 @@
         if v2.is_constant():
             val = v2.box.getint()
             if val >= 0:
-                r.intbound.intersect(IntBound(0, val))
+                r.getintbound().intersect(IntBound(0, val))
         elif v1.is_constant():
             val = v1.box.getint()
             if val >= 0:
-                r.intbound.intersect(IntBound(0, val))
-        elif v1.intbound.known_ge(IntBound(0, 0)) and \
-          v2.intbound.known_ge(IntBound(0, 0)):
-            lesser = min(v1.intbound.upper, v2.intbound.upper)
-            r.intbound.intersect(IntBound(0, next_pow2_m1(lesser)))
+                r.getintbound().intersect(IntBound(0, val))
+        elif v1.getintbound().known_ge(IntBound(0, 0)) and \
+          v2.getintbound().known_ge(IntBound(0, 0)):
+            lesser = min(v1.getintbound().upper, v2.getintbound().upper)
+            r.getintbound().intersect(IntBound(0, next_pow2_m1(lesser)))
 
     def optimize_INT_SUB(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
         r = self.getvalue(op.result)
-        b = v1.intbound.sub_bound(v2.intbound)
+        b = v1.getintbound().sub_bound(v2.getintbound())
         if b.bounded():
-            r.intbound.intersect(b)
+            r.getintbound().intersect(b)
 
     def optimize_INT_ADD(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
         r = self.getvalue(op.result)
-        b = v1.intbound.add_bound(v2.intbound)
+        b = v1.getintbound().add_bound(v2.getintbound())
         if b.bounded():
-            r.intbound.intersect(b)
+            r.getintbound().intersect(b)
 
     def optimize_INT_MUL(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
         r = self.getvalue(op.result)
-        b = v1.intbound.mul_bound(v2.intbound)
+        b = v1.getintbound().mul_bound(v2.getintbound())
         if b.bounded():
-            r.intbound.intersect(b)
+            r.getintbound().intersect(b)
 
     def optimize_INT_FLOORDIV(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
         r = self.getvalue(op.result)
-        r.intbound.intersect(v1.intbound.div_bound(v2.intbound))
+        r.getintbound().intersect(v1.getintbound().div_bound(v2.getintbound()))
 
     def optimize_INT_MOD(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        known_nonneg = (v1.intbound.known_ge(IntBound(0, 0)) and
-                        v2.intbound.known_ge(IntBound(0, 0)))
+        known_nonneg = (v1.getintbound().known_ge(IntBound(0, 0)) and
+                        v2.getintbound().known_ge(IntBound(0, 0)))
         if known_nonneg and v2.is_constant():
             val = v2.box.getint()
             if (val & (val-1)) == 0:
@@ -164,18 +168,18 @@
                     return     # give up
                 val = -val
             if known_nonneg:
-                r.intbound.make_ge(IntBound(0, 0))
+                r.getintbound().make_ge(IntBound(0, 0))
             else:
-                r.intbound.make_gt(IntBound(-val, -val))
-            r.intbound.make_lt(IntBound(val, val))
+                r.getintbound().make_gt(IntBound(-val, -val))
+            r.getintbound().make_lt(IntBound(val, val))
 
     def optimize_INT_LSHIFT(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         self.emit_operation(op)
         r = self.getvalue(op.result)
-        b = v1.intbound.lshift_bound(v2.intbound)
-        r.intbound.intersect(b)
+        b = v1.getintbound().lshift_bound(v2.getintbound())
+        r.getintbound().intersect(b)
         # intbound.lshift_bound checks for an overflow and if the
         # lshift can be proven not to overflow sets b.has_upper and
         # b.has_lower
@@ -186,14 +190,14 @@
     def optimize_INT_RSHIFT(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        b = v1.intbound.rshift_bound(v2.intbound)
+        b = v1.getintbound().rshift_bound(v2.getintbound())
         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)
         else:
             self.emit_operation(op)
             r = self.getvalue(op.result)
-            r.intbound.intersect(b)
+            r.getintbound().intersect(b)
 
     def optimize_GUARD_NO_OVERFLOW(self, op):
         lastop = self.last_emitted_operation
@@ -238,7 +242,7 @@
     def optimize_INT_ADD_OVF(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        resbound = v1.intbound.add_bound(v2.intbound)
+        resbound = v1.getintbound().add_bound(v2.getintbound())
         if resbound.bounded():
             # Transform into INT_ADD.  The following guard will be killed
             # by optimize_GUARD_NO_OVERFLOW; if we see instead an
@@ -246,7 +250,7 @@
             op = op.copy_and_change(rop.INT_ADD)
         self.emit_operation(op) # emit the op
         r = self.getvalue(op.result)
-        r.intbound.intersect(resbound)
+        r.getintbound().intersect(resbound)
 
     def optimize_INT_SUB_OVF(self, op):
         v1 = self.getvalue(op.getarg(0))
@@ -254,29 +258,29 @@
         if v1 is v2:
             self.make_constant_int(op.result, 0)
             return
-        resbound = v1.intbound.sub_bound(v2.intbound)
+        resbound = v1.getintbound().sub_bound(v2.getintbound())
         if resbound.bounded():
             op = op.copy_and_change(rop.INT_SUB)
         self.emit_operation(op) # emit the op
         r = self.getvalue(op.result)
-        r.intbound.intersect(resbound)
+        r.getintbound().intersect(resbound)
 
     def optimize_INT_MUL_OVF(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        resbound = v1.intbound.mul_bound(v2.intbound)
+        resbound = v1.getintbound().mul_bound(v2.getintbound())
         if resbound.bounded():
             op = op.copy_and_change(rop.INT_MUL)
         self.emit_operation(op)
         r = self.getvalue(op.result)
-        r.intbound.intersect(resbound)
+        r.getintbound().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):
+        if v1.getintbound().known_lt(v2.getintbound()):
             self.make_constant_int(op.result, 1)
-        elif v1.intbound.known_ge(v2.intbound) or v1 is v2:
+        elif v1.getintbound().known_ge(v2.getintbound()) or v1 is v2:
             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
@@ -284,9 +288,9 @@
     def optimize_INT_GT(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        if v1.intbound.known_gt(v2.intbound):
+        if v1.getintbound().known_gt(v2.getintbound()):
             self.make_constant_int(op.result, 1)
-        elif v1.intbound.known_le(v2.intbound) or v1 is v2:
+        elif v1.getintbound().known_le(v2.getintbound()) or v1 is v2:
             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
@@ -294,9 +298,9 @@
     def optimize_INT_LE(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        if v1.intbound.known_le(v2.intbound) or v1 is v2:
+        if v1.getintbound().known_le(v2.getintbound()) or v1 is v2:
             self.make_constant_int(op.result, 1)
-        elif v1.intbound.known_gt(v2.intbound):
+        elif v1.getintbound().known_gt(v2.getintbound()):
             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
@@ -304,9 +308,9 @@
     def optimize_INT_GE(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        if v1.intbound.known_ge(v2.intbound) or v1 is v2:
+        if v1.getintbound().known_ge(v2.getintbound()) or v1 is v2:
             self.make_constant_int(op.result, 1)
-        elif v1.intbound.known_lt(v2.intbound):
+        elif v1.getintbound().known_lt(v2.getintbound()):
             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
@@ -314,9 +318,9 @@
     def optimize_INT_EQ(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        if v1.intbound.known_gt(v2.intbound):
+        if v1.getintbound().known_gt(v2.getintbound()):
             self.make_constant_int(op.result, 0)
-        elif v1.intbound.known_lt(v2.intbound):
+        elif v1.getintbound().known_lt(v2.getintbound()):
             self.make_constant_int(op.result, 0)
         elif v1 is v2:
             self.make_constant_int(op.result, 1)
@@ -326,9 +330,9 @@
     def optimize_INT_NE(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
-        if v1.intbound.known_gt(v2.intbound):
+        if v1.getintbound().known_gt(v2.getintbound()):
             self.make_constant_int(op.result, 1)
-        elif v1.intbound.known_lt(v2.intbound):
+        elif v1.getintbound().known_lt(v2.getintbound()):
             self.make_constant_int(op.result, 1)
         elif v1 is v2:
             self.make_constant_int(op.result, 0)
@@ -337,7 +341,7 @@
 
     def optimize_INT_FORCE_GE_ZERO(self, op):
         value = self.getvalue(op.getarg(0))
-        if value.intbound.known_ge(IntBound(0, 0)):
+        if value.getintbound().known_ge(IntBound(0, 0)):
             self.make_equal_to(op.result, value)
         else:
             self.emit_operation(op)
@@ -348,50 +352,53 @@
         start = -(1 << (numbits - 1))
         stop = 1 << (numbits - 1)
         bounds = IntBound(start, stop - 1)
-        if bounds.contains_bound(value.intbound):
+        if bounds.contains_bound(value.getintbound()):
             self.make_equal_to(op.result, value)
         else:
             self.emit_operation(op)
             vres = self.getvalue(op.result)
-            vres.intbound.intersect(bounds)
+            vres.getintbound().intersect(bounds)
 
     def optimize_ARRAYLEN_GC(self, op):
         self.emit_operation(op)
         array = self.getvalue(op.getarg(0))
         result = self.getvalue(op.result)
         array.make_len_gt(MODE_ARRAY, op.getdescr(), -1)
-        array.lenbound.bound.intersect(result.intbound)
-        result.intbound = array.lenbound.bound
+        array.getlenbound().bound.intersect(result.getintbound())
+        assert isinstance(result, IntOptValue)
+        result.intbound = array.getlenbound().bound
 
     def optimize_STRLEN(self, op):
         self.emit_operation(op)
         array = self.getvalue(op.getarg(0))
         result = self.getvalue(op.result)
         array.make_len_gt(MODE_STR, op.getdescr(), -1)
-        array.lenbound.bound.intersect(result.intbound)
-        result.intbound = array.lenbound.bound
+        array.getlenbound().bound.intersect(result.getintbound())
+        assert isinstance(result, IntOptValue)
+        result.intbound = array.getlenbound().bound
 
     def optimize_UNICODELEN(self, op):
         self.emit_operation(op)
         array = self.getvalue(op.getarg(0))
         result = self.getvalue(op.result)
         array.make_len_gt(MODE_UNICODE, op.getdescr(), -1)
-        array.lenbound.bound.intersect(result.intbound)
-        result.intbound = array.lenbound.bound
+        array.getlenbound().bound.intersect(result.getintbound())
+        assert isinstance(result, IntOptValue)        
+        result.intbound = array.getlenbound().bound
 
     def optimize_STRGETITEM(self, op):
         self.emit_operation(op)
         v1 = self.getvalue(op.result)
-        v1.intbound.make_ge(IntLowerBound(0))
-        v1.intbound.make_lt(IntUpperBound(256))
+        v1.getintbound().make_ge(IntLowerBound(0))
+        v1.getintbound().make_lt(IntUpperBound(256))
 
     def optimize_GETFIELD_RAW(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_le(IntUpperBound(descr.get_integer_max()))
+            v1.getintbound().make_ge(IntLowerBound(descr.get_integer_min()))
+            v1.getintbound().make_le(IntUpperBound(descr.get_integer_max()))
 
     optimize_GETFIELD_GC = optimize_GETFIELD_RAW
 
@@ -402,30 +409,30 @@
         descr = op.getdescr()
         if descr and descr.is_item_integer_bounded():
             v1 = self.getvalue(op.result)
-            v1.intbound.make_ge(IntLowerBound(descr.get_item_integer_min()))
-            v1.intbound.make_le(IntUpperBound(descr.get_item_integer_max()))
+            v1.getintbound().make_ge(IntLowerBound(descr.get_item_integer_min()))
+            v1.getintbound().make_le(IntUpperBound(descr.get_item_integer_max()))
 
     optimize_GETARRAYITEM_GC = optimize_GETARRAYITEM_RAW
 
     def optimize_UNICODEGETITEM(self, op):
         self.emit_operation(op)
         v1 = self.getvalue(op.result)
-        v1.intbound.make_ge(IntLowerBound(0))
+        v1.getintbound().make_ge(IntLowerBound(0))
 
     def make_int_lt(self, box1, box2):
         v1 = self.getvalue(box1)
         v2 = self.getvalue(box2)
-        if v1.intbound.make_lt(v2.intbound):
+        if v1.getintbound().make_lt(v2.getintbound()):
             self.propagate_bounds_backward(box1)
-        if v2.intbound.make_gt(v1.intbound):
+        if v2.getintbound().make_gt(v1.getintbound()):
             self.propagate_bounds_backward(box2)
 
     def make_int_le(self, box1, box2):
         v1 = self.getvalue(box1)
         v2 = self.getvalue(box2)
-        if v1.intbound.make_le(v2.intbound):
+        if v1.getintbound().make_le(v2.getintbound()):
             self.propagate_bounds_backward(box1)
-        if v2.intbound.make_ge(v1.intbound):
+        if v2.getintbound().make_ge(v1.getintbound()):
             self.propagate_bounds_backward(box2)
 
     def make_int_gt(self, box1, box2):
@@ -472,9 +479,9 @@
             if r.box.same_constant(CONST_1):
                 v1 = self.getvalue(op.getarg(0))
                 v2 = self.getvalue(op.getarg(1))
-                if v1.intbound.intersect(v2.intbound):
+                if v1.getintbound().intersect(v2.getintbound()):
                     self.propagate_bounds_backward(op.getarg(0))
-                if v2.intbound.intersect(v1.intbound):
+                if v2.getintbound().intersect(v1.getintbound()):
                     self.propagate_bounds_backward(op.getarg(1))
 
     def propagate_bounds_INT_NE(self, op):
@@ -483,9 +490,9 @@
             if r.box.same_constant(CONST_0):
                 v1 = self.getvalue(op.getarg(0))
                 v2 = self.getvalue(op.getarg(1))
-                if v1.intbound.intersect(v2.intbound):
+                if v1.getintbound().intersect(v2.getintbound()):
                     self.propagate_bounds_backward(op.getarg(0))
-                if v2.intbound.intersect(v1.intbound):
+                if v2.getintbound().intersect(v1.getintbound()):
                     self.propagate_bounds_backward(op.getarg(1))
 
     def propagate_bounds_INT_IS_TRUE(self, op):
@@ -493,8 +500,8 @@
         if r.is_constant():
             if r.box.same_constant(CONST_1):
                 v1 = self.getvalue(op.getarg(0))
-                if v1.intbound.known_ge(IntBound(0, 0)):
-                    v1.intbound.make_gt(IntBound(0, 0))
+                if v1.getintbound().known_ge(IntBound(0, 0)):
+                    v1.getintbound().make_gt(IntBound(0, 0))
                     self.propagate_bounds_backward(op.getarg(0))
 
     def propagate_bounds_INT_IS_ZERO(self, op):
@@ -505,49 +512,49 @@
                 # Clever hack, we can't use self.make_constant_int yet because
                 # the args aren't in the values dictionary yet so it runs into
                 # an assert, this is a clever way of expressing the same thing.
-                v1.intbound.make_ge(IntBound(0, 0))
-                v1.intbound.make_lt(IntBound(1, 1))
+                v1.getintbound().make_ge(IntBound(0, 0))
+                v1.getintbound().make_lt(IntBound(1, 1))
                 self.propagate_bounds_backward(op.getarg(0))
 
     def propagate_bounds_INT_ADD(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         r = self.getvalue(op.result)
-        b = r.intbound.sub_bound(v2.intbound)
-        if v1.intbound.intersect(b):
+        b = r.getintbound().sub_bound(v2.getintbound())
+        if v1.getintbound().intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
-        b = r.intbound.sub_bound(v1.intbound)
-        if v2.intbound.intersect(b):
+        b = r.getintbound().sub_bound(v1.getintbound())
+        if v2.getintbound().intersect(b):
             self.propagate_bounds_backward(op.getarg(1))
 
     def propagate_bounds_INT_SUB(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         r = self.getvalue(op.result)
-        b = r.intbound.add_bound(v2.intbound)
-        if v1.intbound.intersect(b):
+        b = r.getintbound().add_bound(v2.getintbound())
+        if v1.getintbound().intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
-        b = r.intbound.sub_bound(v1.intbound).mul(-1)
-        if v2.intbound.intersect(b):
+        b = r.getintbound().sub_bound(v1.getintbound()).mul(-1)
+        if v2.getintbound().intersect(b):
             self.propagate_bounds_backward(op.getarg(1))
 
     def propagate_bounds_INT_MUL(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         r = self.getvalue(op.result)
-        b = r.intbound.div_bound(v2.intbound)
-        if v1.intbound.intersect(b):
+        b = r.getintbound().div_bound(v2.getintbound())
+        if v1.getintbound().intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
-        b = r.intbound.div_bound(v1.intbound)
-        if v2.intbound.intersect(b):
+        b = r.getintbound().div_bound(v1.getintbound())
+        if v2.getintbound().intersect(b):
             self.propagate_bounds_backward(op.getarg(1))
 
     def propagate_bounds_INT_LSHIFT(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         r = self.getvalue(op.result)
-        b = r.intbound.rshift_bound(v2.intbound)
-        if v1.intbound.intersect(b):
+        b = r.getintbound().rshift_bound(v2.getintbound())
+        if v1.getintbound().intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
 
     propagate_bounds_INT_ADD_OVF = propagate_bounds_INT_ADD
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -1,9 +1,11 @@
 from rpython.jit.metainterp import jitprof, resume, compile
 from rpython.jit.metainterp.executor import execute_nonspec
-from rpython.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt, REF
-from rpython.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded, \
+from rpython.jit.metainterp.history import BoxInt, BoxFloat, Const, ConstInt,\
+     REF, BoxPtr, ConstPtr, ConstFloat
+from rpython.jit.metainterp.optimizeopt.intutils import IntBound, IntUnbounded,\
                                                      ImmutableIntUnbounded, \
-                                                     IntLowerBound, MININT, MAXINT
+                                                     IntLowerBound, MININT,\
+                                                     MAXINT
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop, ResOperation, AbstractResOp
 from rpython.jit.metainterp.typesystem import llhelper
@@ -39,69 +41,19 @@
 
 class OptValue(object):
     __metaclass__ = extendabletype
-    _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound', 'lenbound')
-    last_guard = None
+    _attrs_ = ('box', 'level')
 
     level = LEVEL_UNKNOWN
-    known_class = None
-    intbound = ImmutableIntUnbounded()
-    lenbound = None
 
     def __init__(self, box, level=None, known_class=None, intbound=None):
         self.box = box
         if level is not None:
             self.level = level
-        self.known_class = known_class
-        if intbound:
-            self.intbound = intbound
-        else:
-            if isinstance(box, BoxInt):
-                self.intbound = IntBound(MININT, MAXINT)
-            else:
-                self.intbound = IntUnbounded()
 
         if isinstance(box, Const):
             self.make_constant(box)
         # invariant: box is a Const if and only if level == LEVEL_CONSTANT
 
-    def make_len_gt(self, mode, descr, val):
-        if self.lenbound:
-            assert self.lenbound.mode == mode
-            assert self.lenbound.descr == descr
-            self.lenbound.bound.make_gt(IntBound(val, val))
-        else:
-            self.lenbound = LenBound(mode, descr, IntLowerBound(val + 1))
-
-    def make_guards(self, box):
-        guards = []
-        if self.level == LEVEL_CONSTANT:
-            op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
-            guards.append(op)
-        elif self.level == LEVEL_KNOWNCLASS:
-            op = ResOperation(rop.GUARD_NONNULL, [box], None)
-            guards.append(op)
-            op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
-            guards.append(op)
-        else:
-            if self.level == LEVEL_NONNULL:
-                op = ResOperation(rop.GUARD_NONNULL, [box], None)
-                guards.append(op)
-            self.intbound.make_guards(box, guards)
-            if self.lenbound:
-                lenbox = BoxInt()
-                if self.lenbound.mode == MODE_ARRAY:
-                    op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox, self.lenbound.descr)
-                elif self.lenbound.mode == MODE_STR:
-                    op = ResOperation(rop.STRLEN, [box], lenbox, self.lenbound.descr)
-                elif self.lenbound.mode == MODE_UNICODE:
-                    op = ResOperation(rop.UNICODELEN, [box], lenbox, self.lenbound.descr)
-                else:
-                    debug_print("Unknown lenbound mode")
-                    assert False
-                guards.append(op)
-                self.lenbound.bound.make_guards(lenbox, guards)
-        return guards
-
     def import_from(self, other, optimizer):
         if self.level == LEVEL_CONSTANT:
             assert other.level == LEVEL_CONSTANT
@@ -112,19 +64,16 @@
             self.make_constant(other.get_key_box())
             optimizer.turned_constant(self)
         elif other.level == LEVEL_KNOWNCLASS:
-            self.make_constant_class(other.known_class, None)
+            self.make_constant_class(other.get_known_class(), None)
         else:
             if other.level == LEVEL_NONNULL:
                 self.ensure_nonnull()
-            self.intbound.intersect(other.intbound)
-            if other.lenbound:
-                if self.lenbound:
-                    assert other.lenbound.mode == self.lenbound.mode
-                    assert other.lenbound.descr == self.lenbound.descr
-                    self.lenbound.bound.intersect(other.lenbound.bound)
-                else:
-                    self.lenbound = other.lenbound.clone()
 
+    def make_guards(self, box):
+        if self.level == LEVEL_CONSTANT:
+            op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
+            return [op]
+        return []
 
     def force_box(self, optforce):
         return self.box
@@ -168,38 +117,6 @@
             return self.box.same_constant(other.box)
         return self is other
 
-    def make_constant(self, constbox):
-        """Replace 'self.box' with a Const box."""
-        assert isinstance(constbox, Const)
-        self.box = constbox
-        self.level = LEVEL_CONSTANT
-
-        if isinstance(constbox, ConstInt):
-            val = constbox.getint()
-            self.intbound = IntBound(val, val)
-        else:
-            self.intbound = IntUnbounded()
-
-    def get_constant_class(self, cpu):
-        level = self.level
-        if level == LEVEL_KNOWNCLASS:
-            return self.known_class
-        elif level == LEVEL_CONSTANT:
-            return cpu.ts.cls_of_box(self.box)
-        else:
-            return None
-
-    def make_constant_class(self, classbox, guardop):
-        assert self.level < LEVEL_KNOWNCLASS
-        self.known_class = classbox
-        self.level = LEVEL_KNOWNCLASS
-        self.last_guard = guardop
-
-    def make_nonnull(self, guardop):
-        assert self.level < LEVEL_NONNULL
-        self.level = LEVEL_NONNULL
-        self.last_guard = guardop
-
     def is_nonnull(self):
         level = self.level
         if level == LEVEL_NONNULL or level == LEVEL_KNOWNCLASS:
@@ -208,12 +125,6 @@
             box = self.box
             assert isinstance(box, Const)
             return box.nonnull()
-        elif self.intbound:
-            if self.intbound.known_gt(IntBound(0, 0)) or \
-               self.intbound.known_lt(IntBound(0, 0)):
-                return True
-            else:
-                return False
         else:
             return False
 
@@ -260,8 +171,202 @@
     def get_missing_null_value(self):
         raise NotImplementedError    # only for VArrayValue
 
+    def make_constant(self, constbox):
+        """Replace 'self.box' with a Const box."""
+        assert isinstance(constbox, Const)
+        self.box = constbox
+        self.level = LEVEL_CONSTANT
 
-class ConstantValue(OptValue):
+    def get_last_guard(self):
+        return None
+
+    def get_known_class(self):
+        return None
+
+    def getlenbound(self):
+        return None
+
+    def getintbound(self):
+        return None
+
+    def get_constant_class(self, cpu):
+        return None
+
+class PtrOptValue(OptValue):
+    _attrs_ = ('known_class', 'last_guard', 'lenbound')
+
+    known_class = None
+    last_guard = None
+    lenbound = None
+
+    def __init__(self, box, level=None, known_class=None, intbound=None):
+        OptValue.__init__(self, box, level, None, intbound)
+        if not isinstance(box, Const):
+            self.known_class = known_class
+
+    def make_len_gt(self, mode, descr, val):
+        if self.lenbound:
+            assert self.lenbound.mode == mode
+            assert self.lenbound.descr == descr
+            self.lenbound.bound.make_gt(IntBound(val, val))
+        else:
+            self.lenbound = LenBound(mode, descr, IntLowerBound(val + 1))
+
+    def make_nonnull(self, guardop):
+        assert self.level < LEVEL_NONNULL
+        self.level = LEVEL_NONNULL
+        self.last_guard = guardop
+
+    def make_constant_class(self, classbox, guardop):
+        assert self.level < LEVEL_KNOWNCLASS
+        self.known_class = classbox
+        self.level = LEVEL_KNOWNCLASS
+        self.last_guard = guardop
+
+    def import_from(self, other, optimizer):
+        OptValue.import_from(self, other, optimizer)
+        if self.level != LEVEL_CONSTANT:
+            if other.getlenbound():
+                if self.lenbound:
+                    assert other.getlenbound().mode == self.lenbound.mode
+                    assert other.getlenbound().descr == self.lenbound.descr
+                    self.lenbound.bound.intersect(other.getlenbound().bound)
+                else:
+                    self.lenbound = other.getlenbound().clone()
+
+    def make_guards(self, box):
+        guards = []
+        if self.level == LEVEL_CONSTANT:
+            op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
+            guards.append(op)
+        elif self.level == LEVEL_KNOWNCLASS:
+            op = ResOperation(rop.GUARD_NONNULL, [box], None)
+            guards.append(op)
+            op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
+            guards.append(op)
+        else:
+            if self.level == LEVEL_NONNULL:
+                op = ResOperation(rop.GUARD_NONNULL, [box], None)
+                guards.append(op)
+            if self.lenbound:
+                lenbox = BoxInt()
+                if self.lenbound.mode == MODE_ARRAY:
+                    op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox, self.lenbound.descr)
+                elif self.lenbound.mode == MODE_STR:
+                    op = ResOperation(rop.STRLEN, [box], lenbox, self.lenbound.descr)
+                elif self.lenbound.mode == MODE_UNICODE:
+                    op = ResOperation(rop.UNICODELEN, [box], lenbox, self.lenbound.descr)
+                else:
+                    debug_print("Unknown lenbound mode")
+                    assert False
+                guards.append(op)
+                self.lenbound.bound.make_guards(lenbox, guards)
+        return guards
+
+    def get_constant_class(self, cpu):
+        level = self.level
+        if level == LEVEL_KNOWNCLASS:
+            return self.known_class
+        elif level == LEVEL_CONSTANT:
+            return cpu.ts.cls_of_box(self.box)
+        else:
+            return None
+
+    def getlenbound(self):
+        return self.lenbound
+
+    def get_last_guard(self):
+        return self.last_guard
+
+    def get_known_class(self):
+        return self.known_class
+
+class IntOptValue(OptValue):
+    _attrs_ = ('intbound',)
+
+    intbound = ImmutableIntUnbounded()
+
+    def __init__(self, box, level=None, known_class=None, intbound=None):
+        OptValue.__init__(self, box, level, None, None)
+        if isinstance(box, Const):
+            return
+        if intbound:
+            self.intbound = intbound
+        else:
+            if isinstance(box, BoxInt):
+                self.intbound = IntBound(MININT, MAXINT)
+            else:
+                self.intbound = IntUnbounded()
+
+    def make_constant(self, constbox):
+        """Replace 'self.box' with a Const box."""
+        assert isinstance(constbox, ConstInt)
+        self.box = constbox
+        self.level = LEVEL_CONSTANT
+        val = constbox.getint()
+        self.intbound = IntBound(val, val)
+
+    def is_nonnull(self):
+        if OptValue.is_nonnull(self):
+            return True
+        if self.intbound:
+            if self.intbound.known_gt(IntBound(0, 0)) or \
+               self.intbound.known_lt(IntBound(0, 0)):
+                return True
+        return False
+
+    def make_nonnull(self, guardop):
+        assert self.level < LEVEL_NONNULL
+        self.level = LEVEL_NONNULL
+
+    def import_from(self, other, optimizer):
+        OptValue.import_from(self, other, optimizer)
+        if self.level != LEVEL_CONSTANT:
+            if other.getintbound() is not None: # VRawBufferValue
+                self.intbound.intersect(other.getintbound())
+
+    def make_guards(self, box):
+        guards = []
+        if self.level == LEVEL_CONSTANT:
+            op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
+            guards.append(op)
+        elif self.level == LEVEL_KNOWNCLASS:
+            op = ResOperation(rop.GUARD_NONNULL, [box], None)
+            guards.append(op)
+        else:
+            if self.level == LEVEL_NONNULL:
+                op = ResOperation(rop.GUARD_NONNULL, [box], None)
+                guards.append(op)
+            self.intbound.make_guards(box, guards)
+        return guards
+
+    def getintbound(self):
+        return self.intbound
+
+    def get_last_guard(self):
+        return None
+
+    def get_known_class(self):
+        return None
+
+    def getlenbound(self):
+        return None
+
+class ConstantFloatValue(OptValue):
+    def __init__(self, box):
+        self.make_constant(box)
+
+    def __repr__(self):
+        return 'Constant(%r)' % (self.box,)
+
+class ConstantIntValue(IntOptValue):
+    def __init__(self, box):
+        self.make_constant(box)
+
+    def __repr__(self):
+        return 'Constant(%r)' % (self.box,)
+
+class ConstantPtrValue(PtrOptValue):
     def __init__(self, box):
         self.make_constant(box)
 
@@ -270,9 +375,9 @@
 
 CONST_0      = ConstInt(0)
 CONST_1      = ConstInt(1)
-CVAL_ZERO    = ConstantValue(CONST_0)
-CVAL_ZERO_FLOAT = ConstantValue(Const._new(0.0))
-llhelper.CVAL_NULLREF = ConstantValue(llhelper.CONST_NULL)
+CVAL_ZERO    = ConstantIntValue(CONST_0)
+CVAL_ZERO_FLOAT = ConstantFloatValue(Const._new(0.0))
+llhelper.CVAL_NULLREF = ConstantPtrValue(llhelper.CONST_NULL)
 REMOVED = AbstractResOp(None)
 
 
@@ -451,7 +556,12 @@
         try:
             value = self.values[box]
         except KeyError:
-            value = self.values[box] = OptValue(box)
+            if isinstance(box, BoxPtr) or isinstance(box, ConstPtr):
+                value = self.values[box] = PtrOptValue(box)
+            elif isinstance(box, BoxInt) or isinstance(box, ConstInt):
+                value = self.values[box] = IntOptValue(box)
+            else:
+                value = self.values[box] = OptValue(box)
         self.ensure_imported(value)
         return value
 
@@ -487,7 +597,14 @@
         self.values[box] = value
 
     def make_constant(self, box, constbox):
-        self.make_equal_to(box, ConstantValue(constbox))
+        if isinstance(constbox, ConstInt):
+            self.make_equal_to(box, ConstantIntValue(constbox))
+        elif isinstance(constbox, ConstPtr):
+            self.make_equal_to(box, ConstantPtrValue(constbox))
+        elif isinstance(constbox, ConstFloat):
+            self.make_equal_to(box, ConstantFloatValue(constbox))
+        else:
+            assert False
 
     def make_constant_int(self, box, intvalue):
         self.make_constant(box, ConstInt(intvalue))
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -6,7 +6,7 @@
 from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.optimizeopt.intutils import IntBound
 from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED,
-    CONST_0, CONST_1)
+    CONST_0, CONST_1, PtrOptValue)
 from rpython.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop, ResOperation, opclasses
 from rpython.rlib.rarithmetic import highest_bit
@@ -82,14 +82,14 @@
             return
         elif v2.is_constant():
             val = v2.box.getint()
-            if val == -1 or v1.intbound.lower >= 0 \
-                and v1.intbound.upper <= val & ~(val + 1):
+            if val == -1 or v1.getintbound().lower >= 0 \
+                and v1.getintbound().upper <= val & ~(val + 1):
                 self.make_equal_to(op.result, v1)
                 return
         elif v1.is_constant():
             val = v1.box.getint()
-            if val == -1 or v2.intbound.lower >= 0 \
-                and v2.intbound.upper <= val & ~(val + 1):
+            if val == -1 or v2.getintbound().lower >= 0 \
+                and v2.getintbound().upper <= val & ~(val + 1):
                 self.make_equal_to(op.result, v2)
                 return
 
@@ -295,11 +295,11 @@
             else:
                 name = "<unknown>"
             raise InvalidLoop('A promote of a virtual %s (a recently allocated object) never makes sense!' % name)
-        if value.last_guard:
+        if value.get_last_guard():
             # there already has been a guard_nonnull or guard_class or
             # guard_nonnull_class on this value, which is rather silly.
             # replace the original guard with a guard_value
-            old_guard_op = value.last_guard
+            old_guard_op = value.get_last_guard()
             if old_guard_op.getopnum() != rop.GUARD_NONNULL:
                 # This is only safe if the class of the guard_value matches the
                 # class of the guard_*_class, otherwise the intermediate ops might
@@ -322,7 +322,8 @@
             descr.guard_opnum = rop.GUARD_VALUE
             descr.make_a_counter_per_value(op)
             # to be safe
-            value.last_guard = None
+            if isinstance(value, PtrOptValue):
+                value.last_guard = None
         constbox = op.getarg(1)
         assert isinstance(constbox, Const)
         self.optimize_guard(op, constbox)
@@ -354,6 +355,7 @@
             r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
             raise InvalidLoop('A GUARD_CLASS (%s) was proven to always fail'
                               % r)
+        assert isinstance(value, PtrOptValue)
         if value.last_guard:
             # there already has been a guard_nonnull or guard_class or
             # guard_nonnull_class on this value.
@@ -563,7 +565,7 @@
         elif v1.is_constant() and v1.box.getint() == 0:
             self.make_constant_int(op.result, 0)
             return
-        if v1.intbound.known_ge(IntBound(0, 0)) and v2.is_constant():
+        if v1.getintbound().known_ge(IntBound(0, 0)) and v2.is_constant():
             val = v2.box.getint()
             if val & (val - 1) == 0 and val > 0: # val == 2**shift
                 op = op.copy_and_change(rop.INT_RSHIFT,
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
@@ -3,7 +3,8 @@
 from rpython.jit.metainterp.optimizeopt.virtualstate import VirtualStateInfo, VStructStateInfo, \
      VArrayStateInfo, NotVirtualStateInfo, VirtualState, ShortBoxes, GenerateGuardState, \
      VirtualStatesCantMatch, VArrayStructStateInfo
-from rpython.jit.metainterp.optimizeopt.optimizer import OptValue
+from rpython.jit.metainterp.optimizeopt.optimizer import OptValue, PtrOptValue,\
+      IntOptValue
 from rpython.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr, ConstInt, ConstPtr
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin, BaseTest, \
@@ -121,13 +122,13 @@
         assert isgeneral(OptValue(BoxInt()), OptValue(ConstInt(7)))
         assert not isgeneral(OptValue(ConstInt(7)), OptValue(BoxInt()))
 
-        ptr = OptValue(BoxPtr())
-        nonnull = OptValue(BoxPtr())
+        ptr = PtrOptValue(BoxPtr())
+        nonnull = PtrOptValue(BoxPtr())
         nonnull.make_nonnull(0)
-        knownclass = OptValue(BoxPtr())
+        knownclass = PtrOptValue(BoxPtr())
         clsbox = self.cpu.ts.cls_of_box(BoxPtr(self.myptr))
         knownclass.make_constant_class(clsbox, 0)
-        const = OptValue(BoxPtr)
+        const = PtrOptValue(BoxPtr)
         const.make_constant_class(clsbox, 0)
         const.make_constant(ConstPtr(self.myptr))
         inorder = [ptr, nonnull, knownclass, const]
@@ -137,8 +138,8 @@
                 if i != j:
                     assert not isgeneral(inorder[j], inorder[i])
 
-        value1 = OptValue(BoxInt())
-        value2 = OptValue(BoxInt())
+        value1 = IntOptValue(BoxInt())
+        value2 = IntOptValue(BoxInt())
         value2.intbound.make_lt(IntBound(10, 10))
         assert isgeneral(value1, value2)
         assert not isgeneral(value2, value1)
@@ -150,9 +151,9 @@
         assert isgeneral(OptValue(ConstPtr(fooref)),
                          OptValue(ConstPtr(fooref)))
 
-        value1 = OptValue(BoxPtr())
+        value1 = PtrOptValue(BoxPtr())
         value1.make_nonnull(None)
-        value2 = OptValue(ConstPtr(self.nullptr))
+        value2 = PtrOptValue(ConstPtr(self.nullptr))
         assert not isgeneral(value1, value2)
 
     def test_field_matching_generalization(self):
@@ -178,18 +179,18 @@
         fldtst(VArrayStructStateInfo(fakedescr, [[fielddescr]]), VArrayStructStateInfo(fakedescr, [[fielddescr]]))
 
     def test_known_class_generalization(self):
-        knownclass1 = OptValue(BoxPtr())
+        knownclass1 = PtrOptValue(BoxPtr())
         knownclass1.make_constant_class(ConstPtr(self.myptr), 0)
         info1 = NotVirtualStateInfo(knownclass1)
         info1.position = 0
-        knownclass2 = OptValue(BoxPtr())
+        knownclass2 = PtrOptValue(BoxPtr())
         knownclass2.make_constant_class(ConstPtr(self.myptr), 0)
         info2 = NotVirtualStateInfo(knownclass2)
         info2.position = 0
         self.check_no_guards(info1, info2)
         self.check_no_guards(info2, info1)
 
-        knownclass3 = OptValue(BoxPtr())
+        knownclass3 = PtrOptValue(BoxPtr())
         knownclass3.make_constant_class(ConstPtr(self.myptr2), 0)
         info3 = NotVirtualStateInfo(knownclass3)
         info3.position = 0
@@ -209,33 +210,33 @@
 
     def test_generate_guards_nonvirtual_all_combinations(self):
         # set up infos
-        unknown_val = OptValue(self.nodebox)
-        unknownnull_val = OptValue(BoxPtr(self.nullptr))
+        unknown_val = PtrOptValue(self.nodebox)
+        unknownnull_val = PtrOptValue(BoxPtr(self.nullptr))
         unknown_info = NotVirtualStateInfo(unknown_val)
 
-        nonnull_val = OptValue(self.nodebox)
+        nonnull_val = PtrOptValue(self.nodebox)
         nonnull_val.make_nonnull(None)
         nonnull_info = NotVirtualStateInfo(nonnull_val)
 
-        knownclass_val = OptValue(self.nodebox)
+        knownclass_val = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         knownclass_val.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(knownclass_val)
-        knownclass2_val = OptValue(self.nodebox2)
+        knownclass2_val = PtrOptValue(self.nodebox2)
         classbox = self.cpu.ts.cls_of_box(self.nodebox2)
         knownclass2_val.make_constant_class(classbox, -1)
         knownclass2_info = NotVirtualStateInfo(knownclass2_val)
 
-        constant_val = OptValue(BoxInt())
+        constant_val = IntOptValue(BoxInt())
         constant_val.make_constant(ConstInt(1))
         constant_info = NotVirtualStateInfo(constant_val)
-        constclass_val = OptValue(self.nodebox)
+        constclass_val = PtrOptValue(self.nodebox)
         constclass_val.make_constant(self.nodebox.constbox())
         constclass_info = NotVirtualStateInfo(constclass_val)
-        constclass2_val = OptValue(self.nodebox)
+        constclass2_val = PtrOptValue(self.nodebox)
         constclass2_val.make_constant(self.nodebox2.constbox())
         constclass2_info = NotVirtualStateInfo(constclass2_val)
-        constantnull_val = OptValue(ConstPtr(self.nullptr))
+        constantnull_val = PtrOptValue(ConstPtr(self.nullptr))
         constantnull_info = NotVirtualStateInfo(constantnull_val)
 
         # unknown unknown
@@ -354,11 +355,11 @@
 
 
     def test_intbounds(self):
-        value1 = OptValue(BoxInt(15))
+        value1 = IntOptValue(BoxInt(15))
         value1.intbound.make_ge(IntBound(0, 10))
         value1.intbound.make_le(IntBound(20, 30))
         info1 = NotVirtualStateInfo(value1)
-        info2 = NotVirtualStateInfo(OptValue(BoxInt()))
+        info2 = NotVirtualStateInfo(IntOptValue(BoxInt()))
         expected = """
         [i0]
         i1 = int_ge(i0, 0)
@@ -370,22 +371,22 @@
         self.check_invalid(info1, info2, BoxInt(50))
 
     def test_intbounds_constant(self):
-        value1 = OptValue(BoxInt(15))
+        value1 = IntOptValue(BoxInt(15))
         value1.intbound.make_ge(IntBound(0, 10))
         value1.intbound.make_le(IntBound(20, 30))
         info1 = NotVirtualStateInfo(value1)
-        info2 = NotVirtualStateInfo(OptValue(ConstInt(10000)))
+        info2 = NotVirtualStateInfo(IntOptValue(ConstInt(10000)))
         self.check_invalid(info1, info2)
         info1 = NotVirtualStateInfo(value1)
-        info2 = NotVirtualStateInfo(OptValue(ConstInt(11)))
+        info2 = NotVirtualStateInfo(IntOptValue(ConstInt(11)))
         self.check_no_guards(info1, info2)
 
     def test_known_class(self):
-        value1 = OptValue(self.nodebox)
+        value1 = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value1.make_constant_class(classbox, -1)
         info1 = NotVirtualStateInfo(value1)
-        info2 = NotVirtualStateInfo(OptValue(self.nodebox))
+        info2 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
         expected = """
         [p0]
         guard_nonnull(p0) []        
@@ -395,7 +396,7 @@
         self.check_invalid(info1, info2, BoxPtr())
 
     def test_known_class_value(self):
-        value1 = OptValue(self.nodebox)
+        value1 = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value1.make_constant_class(classbox, -1)
         box = self.nodebox
@@ -408,7 +409,7 @@
         self.compare(guards, expected, [box])
 
     def test_known_value(self):
-        value1 = OptValue(self.nodebox)
+        value1 = PtrOptValue(self.nodebox)
         value1.make_constant(ConstInt(1))
         box = self.nodebox
         guards = value1.make_guards(box)
@@ -419,21 +420,21 @@
         self.compare(guards, expected, [box])
 
     def test_equal_inputargs(self):
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
         vstate1 = VirtualState([knownclass_info, knownclass_info])
         assert vstate1.generalization_of(vstate1)
 
-        unknown_info1 = NotVirtualStateInfo(OptValue(self.nodebox))
+        unknown_info1 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
         vstate2 = VirtualState([unknown_info1, unknown_info1])
         assert vstate2.generalization_of(vstate2)
         assert not vstate1.generalization_of(vstate2)
         assert vstate2.generalization_of(vstate1)
 
-        unknown_info1 = NotVirtualStateInfo(OptValue(self.nodebox))
-        unknown_info2 = NotVirtualStateInfo(OptValue(self.nodebox))
+        unknown_info1 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
+        unknown_info2 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
         vstate3 = VirtualState([unknown_info1, unknown_info2])
         assert vstate3.generalization_of(vstate2)
         assert vstate3.generalization_of(vstate1)
@@ -457,12 +458,12 @@
 
 
     def test_generate_guards_on_virtual_fields_matches_array(self):
-        innervalue1 = OptValue(self.nodebox)
+        innervalue1 = PtrOptValue(self.nodebox)
         constclassbox = self.cpu.ts.cls_of_box(self.nodebox)
         innervalue1.make_constant_class(constclassbox, -1)
         innerinfo1 = NotVirtualStateInfo(innervalue1)
         innerinfo1.position = 1
-        innerinfo2 = NotVirtualStateInfo(OptValue(self.nodebox))
+        innerinfo2 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
         innerinfo2.position = 1
 
         descr = object()
@@ -474,7 +475,7 @@
         info2.fieldstate = [innerinfo2]
 
         value1 = VArrayValue(descr, None, 1, self.nodebox)
-        value1._items[0] = OptValue(self.nodebox)
+        value1._items[0] = PtrOptValue(self.nodebox)
 
         expected = """
         [p0]
@@ -484,12 +485,12 @@
         self.guards(info1, info2, value1, expected, [self.nodebox])
 
     def test_generate_guards_on_virtual_fields_matches_instance(self):
-        innervalue1 = OptValue(self.nodebox)
+        innervalue1 = PtrOptValue(self.nodebox)
         constclassbox = self.cpu.ts.cls_of_box(self.nodebox)
         innervalue1.make_constant_class(constclassbox, -1)
         innerinfo1 = NotVirtualStateInfo(innervalue1)
         innerinfo1.position = 1
-        innerinfo2 = NotVirtualStateInfo(OptValue(self.nodebox))
+        innerinfo2 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
         innerinfo2.position = 1
 
         info1 = VirtualStateInfo(ConstInt(42), [1])
@@ -499,7 +500,7 @@
         info2.fieldstate = [innerinfo2]
 
         value1 = VirtualValue(self.cpu, constclassbox, self.nodebox)
-        value1._fields = {1: OptValue(self.nodebox)}
+        value1._fields = {1: PtrOptValue(self.nodebox)}
 
         expected = """
         [p0]
@@ -509,12 +510,12 @@
         self.guards(info1, info2, value1, expected, [self.nodebox])
 
     def test_generate_guards_on_virtual_fields_matches_struct(self):
-        innervalue1 = OptValue(self.nodebox)
+        innervalue1 = PtrOptValue(self.nodebox)
         constclassbox = self.cpu.ts.cls_of_box(self.nodebox)
         innervalue1.make_constant_class(constclassbox, -1)
         innerinfo1 = NotVirtualStateInfo(innervalue1)
         innerinfo1.position = 1
-        innerinfo2 = NotVirtualStateInfo(OptValue(self.nodebox))
+        innerinfo2 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
         innerinfo2.position = 1
 
         structdescr = object()
@@ -526,7 +527,7 @@
         info2.fieldstate = [innerinfo2]
 
         value1 = VStructValue(self.cpu, structdescr, self.nodebox)
-        value1._fields = {1: OptValue(self.nodebox)}
+        value1._fields = {1: PtrOptValue(self.nodebox)}
 
         expected = """
         [p0]
@@ -536,12 +537,12 @@
         self.guards(info1, info2, value1, expected, [self.nodebox])
 
     def test_generate_guards_on_virtual_fields_matches_arraystruct(self):
-        innervalue1 = OptValue(self.nodebox)
+        innervalue1 = PtrOptValue(self.nodebox)
         constclassbox = self.cpu.ts.cls_of_box(self.nodebox)
         innervalue1.make_constant_class(constclassbox, -1)
         innerinfo1 = NotVirtualStateInfo(innervalue1)
         innerinfo1.position = 1
-        innerinfo2 = NotVirtualStateInfo(OptValue(self.nodebox))
+        innerinfo2 = NotVirtualStateInfo(PtrOptValue(self.nodebox))
         innerinfo2.position = 1
 
         arraydescr = object()
@@ -554,7 +555,7 @@
         info2.fieldstate = [innerinfo2]
 
         value1 = VArrayStructValue(arraydescr, 1, self.nodebox)
-        value1._items[0][fielddescr] = OptValue(self.nodebox)
+        value1._items[0][fielddescr] = PtrOptValue(self.nodebox)
 
         expected = """
         [p0]
@@ -568,7 +569,7 @@
 
     def test_virtuals_with_equal_fields(self):
         info1 = VirtualStateInfo(ConstInt(42), [1, 2])
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -596,7 +597,7 @@
 
     def test_virtuals_with_nonmatching_fields(self):
         info1 = VirtualStateInfo(ConstInt(42), [1, 2])
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -605,7 +606,7 @@
         assert vstate1.generalization_of(vstate1)
 
         info2 = VirtualStateInfo(ConstInt(42), [1, 2])
-        value = OptValue(self.nodebox2)
+        value = PtrOptValue(self.nodebox2)
         classbox = self.cpu.ts.cls_of_box(self.nodebox2)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -618,7 +619,7 @@
 
     def test_virtuals_with_nonmatching_descrs(self):
         info1 = VirtualStateInfo(ConstInt(42), [10, 20])
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -627,7 +628,7 @@
         assert vstate1.generalization_of(vstate1)
 
         info2 = VirtualStateInfo(ConstInt(42), [1, 2])
-        value = OptValue(self.nodebox2)
+        value = PtrOptValue(self.nodebox2)
         classbox = self.cpu.ts.cls_of_box(self.nodebox2)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -640,7 +641,7 @@
         
     def test_virtuals_with_nonmatching_classes(self):
         info1 = VirtualStateInfo(ConstInt(42), [1, 2])
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -649,7 +650,7 @@
         assert vstate1.generalization_of(vstate1)
 
         info2 = VirtualStateInfo(ConstInt(7), [1, 2])
-        value = OptValue(self.nodebox2)
+        value = PtrOptValue(self.nodebox2)
         classbox = self.cpu.ts.cls_of_box(self.nodebox2)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -662,7 +663,7 @@
         
     def test_nonvirtual_is_not_virtual(self):
         info1 = VirtualStateInfo(ConstInt(42), [1, 2])
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -679,7 +680,7 @@
 
     def test_arrays_with_nonmatching_fields(self):
         info1 = VArrayStateInfo(42)
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -688,7 +689,7 @@
         assert vstate1.generalization_of(vstate1)
 
         info2 = VArrayStateInfo(42)
-        value = OptValue(self.nodebox2)
+        value = PtrOptValue(self.nodebox2)
         classbox = self.cpu.ts.cls_of_box(self.nodebox2)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -701,7 +702,7 @@
 
     def test_arrays_of_different_sizes(self):
         info1 = VArrayStateInfo(42)
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -710,7 +711,7 @@
         assert vstate1.generalization_of(vstate1)
 
         info2 = VArrayStateInfo(42)
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -723,7 +724,7 @@
 
     def test_arrays_with_nonmatching_types(self):
         info1 = VArrayStateInfo(42)
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -732,7 +733,7 @@
         assert vstate1.generalization_of(vstate1)
 
         info2 = VArrayStateInfo(7)
-        value = OptValue(self.nodebox2)
+        value = PtrOptValue(self.nodebox2)
         classbox = self.cpu.ts.cls_of_box(self.nodebox2)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -745,7 +746,7 @@
         
     def test_nonvirtual_is_not_array(self):
         info1 = VArrayStateInfo(42)
-        value = OptValue(self.nodebox)
+        value = PtrOptValue(self.nodebox)
         classbox = self.cpu.ts.cls_of_box(self.nodebox)
         value.make_constant_class(classbox, -1)
         knownclass_info = NotVirtualStateInfo(value)
@@ -762,7 +763,7 @@
         
 
     def test_crash_varay_clear(self):
-        innervalue1 = OptValue(self.nodebox)
+        innervalue1 = PtrOptValue(self.nodebox)
         constclassbox = self.cpu.ts.cls_of_box(self.nodebox)
         innervalue1.make_constant_class(constclassbox, -1)
         innerinfo1 = NotVirtualStateInfo(innervalue1)
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -11,9 +11,9 @@
 from rpython.jit.metainterp.optimizeopt.rawbuffer import RawBuffer, InvalidRawOperation
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.rlib.objectmodel import we_are_translated, specialize
+from rpython.jit.metainterp.optimizeopt.intutils import IntUnbounded
 
-
-class AbstractVirtualValue(optimizer.OptValue):
+class AbstractVirtualValue(optimizer.PtrOptValue):
     _attrs_ = ('keybox', 'source_op', '_cached_vinfo')
     box = None
     level = optimizer.LEVEL_NONNULL
@@ -433,6 +433,9 @@
         self.size = size
         self.buffer = RawBuffer(cpu, logops)
 
+    def getintbound(self):
+        return IntUnbounded()
+
     def getlength(self):
         return len(self.buffer.values)
 
@@ -492,6 +495,9 @@
         self.rawbuffer_value = rawbuffer_value
         self.offset = offset
 
+    def getintbound(self):
+        return IntUnbounded()
+
     def _really_force(self, optforce):
         op = self.source_op
         assert op is not None
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -280,18 +280,18 @@
 class NotVirtualStateInfo(AbstractVirtualStateInfo):
     def __init__(self, value, is_opaque=False):
         self.is_opaque = is_opaque
-        self.known_class = value.known_class
+        self.known_class = value.get_known_class()
         self.level = value.level
-        if value.intbound is None:
+        if value.getintbound() is None:
             self.intbound = IntUnbounded()
         else:
-            self.intbound = value.intbound.clone()
+            self.intbound = value.getintbound().clone()
         if value.is_constant():
             self.constbox = value.box
         else:
             self.constbox = None
         self.position_in_notvirtuals = -1
-        self.lenbound = value.lenbound
+        self.lenbound = value.getlenbound()
 
 
     def _generate_guards(self, other, value, state):
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -472,7 +472,7 @@
                 if index < len1:
                     return self.strgetitem(value.left, vindex, mode)
                 else:
-                    vindex = optimizer.ConstantValue(ConstInt(index - len1))
+                    vindex = optimizer.ConstantIntValue(ConstInt(index - len1))
                     return self.strgetitem(value.right, vindex, mode)
         #
         resbox = _strgetitem(self, value.force_box(self), vindex.force_box(self), mode, resbox)
@@ -521,7 +521,7 @@
             dst_start = dststart.force_box(self).getint()
             actual_length = length.force_box(self).getint()
             for index in range(actual_length):
-                vresult = self.strgetitem(src, optimizer.ConstantValue(ConstInt(index + src_start)), mode)
+                vresult = self.strgetitem(src, optimizer.ConstantIntValue(ConstInt(index + src_start)), mode)
                 if dst_virtual:
                     dst.setitem(index + dst_start, vresult)
                 else:


More information about the pypy-commit mailing list