Author: Armin Rigo <ar...@tunes.org> Branch: all_ordered_dicts Changeset: r75062:6b50206e647d Date: 2014-12-22 17:18 +0100 http://bitbucket.org/pypy/pypy/changeset/6b50206e647d/
Log: hg merge default diff too long, truncating to 2000 out of 2244 lines diff --git a/lib_pypy/readline.py b/lib_pypy/readline.py --- a/lib_pypy/readline.py +++ b/lib_pypy/readline.py @@ -6,4 +6,11 @@ are only stubs at the moment. """ -from pyrepl.readline import * +try: + from pyrepl.readline import * +except ImportError: + import sys + if sys.platform == 'win32': + raise ImportError("the 'readline' module is not available on Windows" + " (on either PyPy or CPython)") + raise diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -397,7 +397,7 @@ def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) - py.test.raises(TypeError, "p[0]") + py.test.raises(TypeError, "x[0]") def test_default_str(): BChar = new_primitive_type("char") diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py --- a/pypy/objspace/std/listobject.py +++ b/pypy/objspace/std/listobject.py @@ -618,8 +618,8 @@ try: i = self.find(w_value, 0, sys.maxint) except ValueError: - raise OperationError(space.w_ValueError, - space.wrap("list.remove(x): x not in list")) + raise oefmt(space.w_ValueError, + "list.remove(): %R is not in list", w_value) if i < self.length(): # otherwise list was mutated self.pop(i) @@ -633,8 +633,7 @@ try: i = self.find(w_value, i, stop) except ValueError: - raise OperationError(space.w_ValueError, - space.wrap("list.index(x): x not in list")) + raise oefmt(space.w_ValueError, "%R is not in list", w_value) return space.wrap(i) @unwrap_spec(reverse=bool) diff --git a/pypy/objspace/std/test/test_dictproxy.py b/pypy/objspace/std/test/test_dictproxy.py --- a/pypy/objspace/std/test/test_dictproxy.py +++ b/pypy/objspace/std/test/test_dictproxy.py @@ -15,14 +15,15 @@ assert NotEmpty.__dict__.get("b") is None raises(TypeError, 'NotEmpty.__dict__[15] = "y"') raises(KeyError, 'del NotEmpty.__dict__[15]') + + key, value = NotEmpty.__dict__.popitem() + assert (key == 'a' and value == 1) or (key == 'b' and value == 4) + assert NotEmpty.__dict__.setdefault("string", 1) == 1 assert NotEmpty.__dict__.setdefault("string", 2) == 1 assert NotEmpty.string == 1 raises(TypeError, 'NotEmpty.__dict__.setdefault(15, 1)') - key, value = NotEmpty.__dict__.popitem() - assert (key == 'a' and value == 1) or (key == 'b' and value == 4) - def test_dictproxy_getitem(self): class NotEmpty(object): a = 1 diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -976,7 +976,10 @@ c = [0.0, 2.2, 4.4] assert c.index(0) == 0.0 - raises(ValueError, c.index, 3) + e = raises(ValueError, c.index, 3) + import sys + if sys.version_info[:2] == (2, 7): # CPython 2.7, PyPy + assert str(e.value) == '3 is not in list' def test_index_cpython_bug(self): if self.on_cpython: @@ -1228,7 +1231,9 @@ assert l == [0.0, 1.1, 3.3, 4.4] l = [0.0, 3.3, 5.5] raises(ValueError, c.remove, 2) - raises(ValueError, c.remove, 2.2) + e = raises(ValueError, c.remove, 2.2) + if not self.on_cpython: + assert str(e.value) == 'list.remove(): 2.2 is not in list' def test_reverse(self): c = list('hello world') diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -389,7 +389,7 @@ assert isinstance(dct2, SomeOrderedDict), "OrderedDict.update(dict) not allowed" dct1.dictdef.union(dct2.dictdef) -SomeDict=SomeOrderedDict +SomeDict = SomeOrderedDict # all dicts are ordered! class SomeIterator(SomeObject): diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -128,7 +128,8 @@ [ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token)] try: - start_state = optimize_trace(metainterp_sd, part, enable_opts) + start_state = optimize_trace(metainterp_sd, part, enable_opts, + export_state=True) except InvalidLoop: return None target_token = part.operations[0].getdescr() @@ -156,7 +157,7 @@ try: optimize_trace(metainterp_sd, part, enable_opts, - start_state=start_state) + start_state=start_state, export_state=False) except InvalidLoop: return None @@ -209,7 +210,7 @@ assert label.getopnum() == rop.LABEL try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts, - start_state=start_state) + start_state=start_state, export_state=False) except InvalidLoop: # Fall back on jumping to preamble target_token = label.getdescr() @@ -220,7 +221,8 @@ try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts, - inline_short_preamble=False, start_state=start_state) + inline_short_preamble=False, start_state=start_state, + export_state=False) except InvalidLoop: return None assert part.operations[-1].getopnum() != rop.LABEL @@ -789,7 +791,8 @@ else: inline_short_preamble = True try: - state = optimize_trace(metainterp_sd, new_trace, state.enable_opts, inline_short_preamble) + state = optimize_trace(metainterp_sd, new_trace, state.enable_opts, + inline_short_preamble, export_state=True) except InvalidLoop: debug_print("compile_new_bridge: got an InvalidLoop") # XXX I am fairly convinced that optimize_bridge cannot actually raise diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py --- a/rpython/jit/metainterp/optimizeopt/__init__.py +++ b/rpython/jit/metainterp/optimizeopt/__init__.py @@ -48,7 +48,8 @@ return optimizations, unroll def optimize_trace(metainterp_sd, loop, enable_opts, - inline_short_preamble=True, start_state=None): + inline_short_preamble=True, start_state=None, + export_state=True): """Optimize loop.operations to remove internal overheadish operations. """ @@ -59,7 +60,8 @@ optimizations, unroll = build_opt_chain(metainterp_sd, enable_opts) if unroll: return optimize_unroll(metainterp_sd, loop, optimizations, - inline_short_preamble, start_state) + inline_short_preamble, start_state, + export_state) else: optimizer = Optimizer(metainterp_sd, loop, optimizations) optimizer.propagate_all_forward() 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 @@ -4,7 +4,7 @@ from rpython.jit.metainterp.optimizeopt.util import args_dict from rpython.jit.metainterp.history import Const, ConstInt from rpython.jit.metainterp.jitexc import JitException -from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, MODE_ARRAY, LEVEL_KNOWNCLASS, REMOVED +from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, MODE_ARRAY, LEVEL_KNOWNCLASS, REMOVED, LEVEL_CONSTANT from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method from rpython.jit.metainterp.optimizeopt.intutils import IntBound from rpython.jit.metainterp.optimize import InvalidLoop @@ -64,6 +64,17 @@ # cancelling its previous effects with no side effect. self._lazy_setfield = None + def value_updated(self, oldvalue, newvalue): + try: + fieldvalue = self._cached_fields[oldvalue] + except KeyError: + pass + else: + self._cached_fields[newvalue] = fieldvalue + op = self._cached_fields_getfield_op[oldvalue].clone() + op.setarg(0, newvalue.box) + self._cached_fields_getfield_op[newvalue] = op + def possible_aliasing(self, optheap, structvalue): # If lazy_setfield is set and contains a setfield on a different # structvalue, then we are annoyed, because it may point to either @@ -118,18 +129,6 @@ self._cached_fields.clear() self._cached_fields_getfield_op.clear() - def turned_constant(self, newvalue, value): - if newvalue not in self._cached_fields and value in self._cached_fields: - self._cached_fields[newvalue] = self._cached_fields[value] - op = self._cached_fields_getfield_op[value].clone() - constbox = value.box - assert isinstance(constbox, Const) - op.setarg(0, constbox) - self._cached_fields_getfield_op[newvalue] = op - for structvalue in self._cached_fields.keys(): - if self._cached_fields[structvalue] is value: - self._cached_fields[structvalue] = newvalue - def produce_potential_short_preamble_ops(self, optimizer, shortboxes, descr): if self._lazy_setfield is not None: return @@ -187,6 +186,17 @@ self._seen_guard_not_invalidated = False self.postponed_op = None + def setup(self): + self.optimizer.optheap = self + + def value_updated(self, oldvalue, newvalue): + # XXXX very unhappy about that + for cf in self.cached_fields.itervalues(): + cf.value_updated(oldvalue, newvalue) + for submap in self.cached_arrayitems.itervalues(): + for cf in submap.itervalues(): + cf.value_updated(oldvalue, newvalue) + def force_at_end_of_preamble(self): self.cached_dict_reads.clear() self.corresponding_array_descrs.clear() @@ -391,16 +401,6 @@ # ^^^ we only need to force this field; the other fields # of virtualref_info and virtualizable_info are not gcptrs. - def turned_constant(self, value): - assert value.is_constant() - newvalue = self.getvalue(value.box) - if value is not newvalue: - for cf in self.cached_fields.itervalues(): - cf.turned_constant(newvalue, value) - for submap in self.cached_arrayitems.itervalues(): - for cf in submap.itervalues(): - cf.turned_constant(newvalue, value) - def force_lazy_setfield(self, descr, can_cache=True): try: cf = self.cached_fields[descr] @@ -414,7 +414,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 @@ -110,21 +62,22 @@ assert self.level <= LEVEL_NONNULL if other.level == LEVEL_CONSTANT: 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 copy_from(self, other_value): + assert isinstance(other_value, OptValue) + self.box = other_value.box + self.level = other_value.level def force_box(self, optforce): return self.box @@ -168,38 +121,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 +129,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 @@ -266,8 +181,216 @@ 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 copy_from(self, other_value): + assert isinstance(other_value, PtrOptValue) + self.box = other_value.box + self.known_class = other_value.known_class + self.level = other_value.level + self.last_guard = other_value.last_guard + self.lenbound = other_value.lenbound + + 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 copy_from(self, other_value): + assert isinstance(other_value, IntOptValue) + self.box = other_value.box + self.intbound = other_value.intbound + self.level = other_value.level + + 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) @@ -276,9 +399,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) @@ -305,8 +428,8 @@ def make_constant_int(self, box, intconst): return self.optimizer.make_constant_int(box, intconst) - def make_equal_to(self, box, value): - return self.optimizer.make_equal_to(box, value) + def make_equal_to(self, box, value, replace=False): + return self.optimizer.make_equal_to(box, value, replace=replace) def get_constant_box(self, box): return self.optimizer.get_constant_box(box) @@ -340,9 +463,6 @@ def setup(self): pass - def turned_constant(self, value): - pass - def force_at_end_of_preamble(self): pass @@ -390,9 +510,9 @@ self.opaque_pointers = {} self.replaces_guard = {} self._newoperations = [] - self.seen_results = {} self.optimizer = self self.optpure = None + self.optheap = None self.optearlyforce = None if loop is not None: self.call_pure_results = loop.call_pure_results @@ -428,10 +548,6 @@ for opt in self.optimizations: opt.produce_potential_short_preamble_ops(sb) - def turned_constant(self, value): - for o in self.optimizations: - o.turned_constant(value) - def forget_numberings(self, virtualbox): self.metainterp_sd.profiler.count(jitprof.Counters.OPT_FORCINGS) self.resumedata_memo.forget_numberings(virtualbox) @@ -457,7 +573,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 @@ -485,15 +606,31 @@ def clear_newoperations(self): self._newoperations = [] - self.seen_results = {} def make_equal_to(self, box, value, replace=False): assert isinstance(value, OptValue) - assert replace or box not in self.values + if replace: + try: + cur_value = self.values[box] + except KeyError: + pass + else: + assert value.level != LEVEL_CONSTANT + assert cur_value.level != LEVEL_CONSTANT + # replacing with a different box + cur_value.copy_from(value) + return 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)) @@ -547,7 +684,8 @@ self.first_optimization.propagate_forward(op) def propagate_forward(self, op): - self.producer[op.result] = op + if op.result is not None: + self.producer[op.result] = op dispatch_opt(self, op) def emit_operation(self, op): @@ -580,10 +718,6 @@ op = self.store_final_boxes_in_guard(op, pendingfields) elif op.can_raise(): self.exception_might_have_happened = True - if op.result: - if op.result in self.seen_results: - raise ValueError, "invalid optimization" - self.seen_results[op.result] = None self._newoperations.append(op) def replace_op(self, old_op, new_op): diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py --- a/rpython/jit/metainterp/optimizeopt/pure.py +++ b/rpython/jit/metainterp/optimizeopt/pure.py @@ -25,6 +25,7 @@ else: nextop = None + args = None if canfold: for i in range(op.numargs()): if self.get_constant_box(op.getarg(i)) is None: @@ -39,15 +40,11 @@ # did we do the exact same operation already? args = self.optimizer.make_args_key(op) - oldop = self.pure_operations.get(args, None) - if oldop is not None and oldop.getdescr() is op.getdescr(): - assert oldop.getopnum() == op.getopnum() - self.optimizer.make_equal_to(op.result, - self.getvalue(oldop.result), - True) + oldvalue = self.pure_operations.get(args, None) + if oldvalue is not None: + self.optimizer.make_equal_to(op.result, oldvalue, True) return else: - self.pure_operations[args] = op self.remember_emitting_pure(op) # otherwise, the operation remains @@ -56,6 +53,8 @@ self.optimizer.bool_boxes[self.getvalue(op.result)] = None if nextop: self.emit_operation(nextop) + if args is not None: + self.pure_operations[args] = self.getvalue(op.result) def optimize_CALL_PURE(self, op): # Step 1: check if all arguments are constant @@ -69,16 +68,15 @@ # Step 2: check if all arguments are the same as a previous # CALL_PURE. args = self.optimizer.make_args_key(op) - oldop = self.pure_operations.get(args, None) - if oldop is not None and oldop.getdescr() is op.getdescr(): - assert oldop.getopnum() == op.getopnum() + oldvalue = self.pure_operations.get(args, None) + if oldvalue is not None: # this removes a CALL_PURE that has the same (non-constant) # arguments as a previous CALL_PURE. - self.make_equal_to(op.result, self.getvalue(oldop.result)) + self.make_equal_to(op.result, oldvalue) self.last_emitted_operation = REMOVED return else: - self.pure_operations[args] = op + self.pure_operations[args] = self.getvalue(op.result) self.remember_emitting_pure(op) # replace CALL_PURE with just CALL @@ -103,15 +101,12 @@ op = ResOperation(opnum, args, result) key = self.optimizer.make_args_key(op) if key not in self.pure_operations: - self.pure_operations[key] = op + self.pure_operations[key] = self.getvalue(result) def has_pure_result(self, opnum, args, descr): op = ResOperation(opnum, args, None, descr) key = self.optimizer.make_args_key(op) - op = self.pure_operations.get(key, None) - if op is None: - return False - return op.getdescr() is descr + return self.pure_operations.get(key, None) is not None def get_pure_result(self, key): return self.pure_operations.get(key, None) 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 @@ -33,9 +33,8 @@ dispatch_opt(self, op) 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.get_pure_result(targs) + if value is not None: if value.is_constant(): if value.box.same_constant(CONST_1): self.make_constant(op.result, CONST_0) @@ -59,9 +58,9 @@ if oldopnum != -1: targs = self.optimizer.make_args_key(ResOperation(oldopnum, [args[1], args[0]], 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)) + value = self.get_pure_result(targs) + if value is not None: + self.optimizer.make_equal_to(op.result, value, True) return True if op.boolreflex == -1: @@ -83,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 @@ -262,7 +261,8 @@ if emit_operation: self.emit_operation(op) value.make_constant(constbox) - self.optimizer.turned_constant(value) + if self.optimizer.optheap: + self.optimizer.optheap.value_updated(value, self.getvalue(constbox)) def optimize_GUARD_ISNULL(self, op): value = self.getvalue(op.getarg(0)) @@ -296,11 +296,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 @@ -323,7 +323,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) @@ -355,6 +356,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. @@ -564,7 +566,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_multilabel.py b/rpython/jit/metainterp/optimizeopt/test/test_multilabel.py --- a/rpython/jit/metainterp/optimizeopt/test/test_multilabel.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_multilabel.py @@ -45,7 +45,8 @@ part.operations = operations self.add_guard_future_condition(part) - state = self._do_optimize_loop(part, None, state) + state = self._do_optimize_loop(part, None, state, + export_state=True) if part.operations[-1].getopnum() == rop.LABEL: last_label = [part.operations.pop()] else: @@ -497,7 +498,8 @@ class BaseTestOptimizerRenamingBoxes(BaseTestMultiLabel): - def _do_optimize_loop(self, loop, call_pure_results, state): + def _do_optimize_loop(self, loop, call_pure_results, state, + export_state=False): from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll from rpython.jit.metainterp.optimizeopt.util import args_dict from rpython.jit.metainterp.optimizeopt.pure import OptPure @@ -505,7 +507,7 @@ self.loop = loop loop.call_pure_results = args_dict() metainterp_sd = FakeMetaInterpStaticData(self.cpu) - return optimize_unroll(metainterp_sd, loop, [OptRewrite(), OptRenameStrlen(), OptHeap(), OptPure()], True, state) + return optimize_unroll(metainterp_sd, loop, [OptRewrite(), OptRenameStrlen(), OptHeap(), OptPure()], True, state, export_state) def test_optimizer_renaming_boxes1(self): ops = """ @@ -543,8 +545,8 @@ self.optimize_loop(ops, expected) -class TestLLtype(OptimizeoptTestMultiLabel, LLtypeMixin): +class XxxTestLLtype(OptimizeoptTestMultiLabel, LLtypeMixin): pass -class TestOptimizerRenamingBoxesLLtype(BaseTestOptimizerRenamingBoxes, LLtypeMixin): +class XxxTestOptimizerRenamingBoxesLLtype(BaseTestOptimizerRenamingBoxes, LLtypeMixin): pass 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 @@ -104,7 +104,7 @@ if loop.operations[-1].getopnum() == rop.JUMP: loop.operations[-1].setdescr(token) expected = convert_old_style_to_targets(self.parse(optops), jump=True) - self._do_optimize_loop(loop, call_pure_results) + self._do_optimize_loop(loop, call_pure_results, export_state=False) print '\n'.join([str(o) for o in loop.operations]) self.assert_equal(loop, expected) @@ -999,6 +999,40 @@ """ self.optimize_loop(ops, expected) + def test_virtual_array_of_struct_arraycopy(self): + ops = """ + [f0, f1] + p0 = new_array_clear(3, descr=complexarraydescr) + setinteriorfield_gc(p0, 0, f0, descr=compleximagdescr) + setinteriorfield_gc(p0, 0, f1, descr=complexrealdescr) + call(0, p0, p0, 0, 2, 1, descr=complexarraycopydescr) + f2 = getinteriorfield_gc(p0, 2, descr=complexrealdescr) + f3 = getinteriorfield_gc(p0, 2, descr=compleximagdescr) + escape(f2) + escape(f3) + finish(1) + """ + expected = """ + [f0, f1] + escape(f1) + escape(f0) + finish(1) + """ + self.optimize_loop(ops, ops) + py.test.skip("XXX missing optimization: ll_arraycopy(array-of-structs)") + + def test_nonvirtual_array_of_struct_arraycopy(self): + ops = """ + [p0] + call(0, p0, p0, 0, 2, 1, descr=complexarraycopydescr) + f2 = getinteriorfield_gc(p0, 2, descr=compleximagdescr) + f3 = getinteriorfield_gc(p0, 2, descr=complexrealdescr) + escape(f2) + escape(f3) + finish(1) + """ + self.optimize_loop(ops, ops) + def test_nonvirtual_1(self): ops = """ [i] diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py --- a/rpython/jit/metainterp/optimizeopt/test/test_util.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py @@ -223,6 +223,10 @@ complexarraydescr = cpu.arraydescrof(complexarray) complexrealdescr = cpu.interiorfielddescrof(complexarray, "real") compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag") + complexarraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([], [complexarraydescr], [], [], [complexarraydescr], [], + EffectInfo.EF_CANNOT_RAISE, + oopspecindex=EffectInfo.OS_ARRAYCOPY)) rawarraydescr = cpu.arraydescrof(lltype.Array(lltype.Signed, hints={'nolength': True})) @@ -390,7 +394,8 @@ assert equaloplists(optimized.operations, expected.operations, False, remap, text_right) - def _do_optimize_loop(self, loop, call_pure_results, start_state=None): + def _do_optimize_loop(self, loop, call_pure_results, start_state=None, + export_state=False): from rpython.jit.metainterp.optimizeopt import optimize_trace from rpython.jit.metainterp.optimizeopt.util import args_dict @@ -406,7 +411,8 @@ metainterp_sd.callinfocollection = self.callinfocollection # return optimize_trace(metainterp_sd, loop, self.enable_opts, - start_state=start_state) + start_state=start_state, + export_state=export_state) def unroll_and_optimize(self, loop, call_pure_results=None): self.add_guard_future_condition(loop) @@ -426,7 +432,8 @@ preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] - start_state = self._do_optimize_loop(preamble, call_pure_results) + start_state = self._do_optimize_loop(preamble, call_pure_results, + export_state=True) assert preamble.operations[-1].getopnum() == rop.LABEL @@ -440,7 +447,8 @@ assert loop.operations[0].getopnum() == rop.LABEL loop.inputargs = loop.operations[0].getarglist() - self._do_optimize_loop(loop, call_pure_results, start_state) + self._do_optimize_loop(loop, call_pure_results, start_state, + export_state=False) extra_same_as = [] while loop.operations[0].getopnum() != rop.LABEL: extra_same_as.append(loop.operations[0]) 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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit