Author: Spenser Bauman <[email protected]>
Branch: remove-getfield-pure
Changeset: r80278:92efa3b835f1
Date: 2015-10-16 10:52 -0400
http://bitbucket.org/pypy/pypy/changeset/92efa3b835f1/
Log: Remove GETFIELD_PURE_* operations from the JIT
- That information is now entirely encoded in the field descriptor
diff --git a/rpython/jit/backend/arm/opassembler.py
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -675,9 +675,6 @@
emit_op_getfield_gc_i = _genop_getfield
emit_op_getfield_gc_r = _genop_getfield
emit_op_getfield_gc_f = _genop_getfield
- emit_op_getfield_gc_pure_i = _genop_getfield
- emit_op_getfield_gc_pure_r = _genop_getfield
- emit_op_getfield_gc_pure_f = _genop_getfield
emit_op_getfield_raw_i = _genop_getfield
emit_op_getfield_raw_f = _genop_getfield
emit_op_getfield_raw_pure_i = _genop_getfield
diff --git a/rpython/jit/backend/arm/regalloc.py
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -853,9 +853,6 @@
prepare_op_getfield_raw_f = _prepare_op_getfield
prepare_op_getfield_raw_pure_i = _prepare_op_getfield
prepare_op_getfield_raw_pure_f = _prepare_op_getfield
- prepare_op_getfield_gc_pure_i = _prepare_op_getfield
- prepare_op_getfield_gc_pure_r = _prepare_op_getfield
- prepare_op_getfield_gc_pure_f = _prepare_op_getfield
def prepare_op_increment_debug_counter(self, op, fcond):
boxes = op.getarglist()
diff --git a/rpython/jit/backend/llgraph/runner.py
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -578,9 +578,6 @@
p = support.cast_arg(lltype.Ptr(descr.S), p)
return support.cast_result(descr.FIELD, getattr(p, descr.fieldname))
- bh_getfield_gc_pure_i = bh_getfield_gc
- bh_getfield_gc_pure_r = bh_getfield_gc
- bh_getfield_gc_pure_f = bh_getfield_gc
bh_getfield_gc_i = bh_getfield_gc
bh_getfield_gc_r = bh_getfield_gc
bh_getfield_gc_f = bh_getfield_gc
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1378,9 +1378,6 @@
genop_getfield_raw_f = _genop_getfield
genop_getfield_raw_pure_i = _genop_getfield
genop_getfield_raw_pure_f = _genop_getfield
- genop_getfield_gc_pure_i = _genop_getfield
- genop_getfield_gc_pure_r = _genop_getfield
- genop_getfield_gc_pure_f = _genop_getfield
def _genop_getarrayitem(self, op, arglocs, resloc):
base_loc, ofs_loc, size_loc, ofs, sign_loc = arglocs
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -1096,9 +1096,6 @@
consider_getfield_raw_f = _consider_getfield
consider_getfield_raw_pure_i = _consider_getfield
consider_getfield_raw_pure_f = _consider_getfield
- consider_getfield_gc_pure_i = _consider_getfield
- consider_getfield_gc_pure_r = _consider_getfield
- consider_getfield_gc_pure_f = _consider_getfield
def consider_increment_debug_counter(self, op):
base_loc = self.loc(op.getarg(0))
diff --git a/rpython/jit/metainterp/heapcache.py
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -168,9 +168,6 @@
elif (opnum != rop.GETFIELD_GC_R and
opnum != rop.GETFIELD_GC_I and
opnum != rop.GETFIELD_GC_F and
- opnum != rop.GETFIELD_GC_PURE_R and
- opnum != rop.GETFIELD_GC_PURE_I and
- opnum != rop.GETFIELD_GC_PURE_F and
opnum != rop.PTR_EQ and
opnum != rop.PTR_NE and
opnum != rop.INSTANCE_PTR_EQ and
diff --git a/rpython/jit/metainterp/history.py
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -789,9 +789,6 @@
if 'getfield_gc' in check:
assert check.pop('getfield_gc') == 0
check['getfield_gc_i'] = check['getfield_gc_r'] =
check['getfield_gc_f'] = 0
- if 'getfield_gc_pure' in check:
- assert check.pop('getfield_gc_pure') == 0
- check['getfield_gc_pure_i'] = check['getfield_gc_pure_r'] =
check['getfield_gc_pure_f'] = 0
if 'getarrayitem_gc_pure' in check:
assert check.pop('getarrayitem_gc_pure') == 0
check['getarrayitem_gc_pure_i'] = check['getarrayitem_gc_pure_r']
= check['getarrayitem_gc_pure_f'] = 0
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
@@ -507,19 +507,6 @@
optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I
- def optimize_GETFIELD_GC_PURE_I(self, op):
- structinfo = self.ensure_ptr_info_arg0(op)
- cf = self.field_cache(op.getdescr())
- field = cf.getfield_from_cache(self, structinfo, op.getdescr())
- if field is not None:
- self.make_equal_to(op, field)
- return
- # default case: produce the operation
- self.make_nonnull(op.getarg(0))
- self.emit_operation(op)
- optimize_GETFIELD_GC_PURE_R = optimize_GETFIELD_GC_PURE_I
- optimize_GETFIELD_GC_PURE_F = optimize_GETFIELD_GC_PURE_I
-
def optimize_SETFIELD_GC(self, op):
self.setfield(op)
#opnum = OpHelpers.getfield_pure_for_descr(op.getdescr())
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
@@ -1,4 +1,3 @@
-from rpython.rtyper.rclass import IR_QUASIIMMUTABLE
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED
from rpython.jit.metainterp.resoperation import rop, OpHelpers, AbstractResOp,\
ResOperation
@@ -66,7 +65,7 @@
class OptPure(Optimization):
def __init__(self):
self.postponed_op = None
- self._pure_operations = [None] * (rop._ALWAYS_PURE_LAST -
+ self._pure_operations = [None] * (rop._NOSIDEEFFECT_LAST -
rop._ALWAYS_PURE_FIRST)
self.call_pure_positions = []
self.extra_call_pure = []
@@ -193,22 +192,6 @@
return
self.emit_operation(op)
- def optimize_GETFIELD_GC_PURE_I(self, op):
- from rpython.rlib.objectmodel import we_are_translated
- # check that the descr is pure
- # XXX quasi immutable descrs, are they pure or not?
- if not we_are_translated():
- descr = op.getdescr()
- # Kind of weird that this returns a boolean or one of the IR_*
- # family
- assert descr.is_always_pure() in (True, IR_QUASIIMMUTABLE)
- return self.optimize_default(op)
- optimize_GETFIELD_GC_PURE_R = optimize_GETFIELD_GC_PURE_I
- optimize_GETFIELD_GC_PURE_F = optimize_GETFIELD_GC_PURE_I
- optimize_GETARRAYITEM_GC_PURE_I = optimize_GETFIELD_GC_PURE_I
- optimize_GETARRAYITEM_GC_PURE_R = optimize_GETFIELD_GC_PURE_I
- optimize_GETARRAYITEM_GC_PURE_F = optimize_GETFIELD_GC_PURE_I
-
def flush(self):
assert self.postponed_op is None
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
@@ -1086,12 +1086,12 @@
"""
self.optimize_loop(ops, expected)
- def test_getfield_gc_pure_1(self):
+ def test_getfield_gc_1(self):
ops = """
[i]
p1 = new_with_vtable(descr=nodesize3)
setfield_gc(p1, i, descr=valuedescr3)
- i1 = getfield_gc_pure_i(p1, descr=valuedescr3)
+ i1 = getfield_gc_i(p1, descr=valuedescr3)
jump(i1)
"""
expected = """
@@ -1100,10 +1100,10 @@
"""
self.optimize_loop(ops, expected)
- def test_getfield_gc_pure_2(self):
+ def test_getfield_gc_2(self):
ops = """
[i]
- i1 = getfield_gc_pure_i(ConstPtr(myptr3), descr=valuedescr3)
+ i1 = getfield_gc_i(ConstPtr(myptr3), descr=valuedescr3)
jump(i1)
"""
expected = """
@@ -1785,7 +1785,7 @@
ops = """
[p1, p2]
p3 = getarrayitem_gc_r(p1, 0, descr=arraydescr2)
- i4 = getfield_gc_pure_i(ConstPtr(myptr3), descr=valuedescr3)
+ i4 = getfield_gc_i(ConstPtr(myptr3), descr=valuedescr3)
p5 = getarrayitem_gc_r(p1, 0, descr=arraydescr2)
escape_n(p3)
escape_n(i4)
@@ -5482,7 +5482,7 @@
[]
quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
guard_not_invalidated() []
- i0 = getfield_gc_pure_i(ConstPtr(quasiptr), descr=quasifielddescr)
+ i0 = getfield_gc_i(ConstPtr(quasiptr), descr=quasifielddescr)
i1 = call_pure_i(123, i0, descr=nonwritedescr)
finish(i1)
"""
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -1411,7 +1411,7 @@
[i]
p1 = new_with_vtable(descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
- i1 = getfield_gc_pure_i(p1, descr=valuedescr)
+ i1 = getfield_gc_i(p1, descr=valuedescr)
jump(i1)
"""
expected = """
@@ -1423,7 +1423,7 @@
def test_getfield_gc_pure_2(self):
ops = """
[i]
- i1 = getfield_gc_pure_i(ConstPtr(myptr3), descr=valuedescr3)
+ i1 = getfield_gc_i(ConstPtr(myptr3), descr=valuedescr3)
jump(i1)
"""
expected = """
@@ -1437,16 +1437,16 @@
ops = """
[]
p1 = escape_r()
- p2 = getfield_gc_pure_r(p1, descr=nextdescr3)
+ p2 = getfield_gc_r(p1, descr=nextdescr3)
escape_n(p2)
- p3 = getfield_gc_pure_r(p1, descr=nextdescr3)
+ p3 = getfield_gc_r(p1, descr=nextdescr3)
escape_n(p3)
jump()
"""
expected = """
[]
p1 = escape_r()
- p2 = getfield_gc_pure_r(p1, descr=nextdescr3)
+ p2 = getfield_gc_r(p1, descr=nextdescr3)
escape_n(p2)
escape_n(p2)
jump()
@@ -2667,7 +2667,7 @@
ops = """
[p1, p2]
p3 = getarrayitem_gc_r(p1, 0, descr=arraydescr2)
- i4 = getfield_gc_pure_i(ConstPtr(myptr3), descr=valuedescr3)
+ i4 = getfield_gc_i(ConstPtr(myptr3), descr=valuedescr3)
p5 = getarrayitem_gc_r(p1, 0, descr=arraydescr2)
escape_n(p3)
escape_n(i4)
@@ -3331,8 +3331,8 @@
setfield_gc(p26, i24, descr=adescr)
i28 = int_add(i17, 1)
setfield_gc(p8, i28, descr=valuedescr)
- i34 = getfield_gc_pure_i(p11, descr=valuedescr3)
- i35 = getfield_gc_pure_i(p26, descr=adescr)
+ i34 = getfield_gc_i(p11, descr=valuedescr3)
+ i35 = getfield_gc_i(p26, descr=adescr)
guard_nonnull(p12) []
i36 = int_add_ovf(i34, i35)
guard_no_overflow() []
@@ -3523,14 +3523,14 @@
def test_residual_call_does_not_invalidate_immutable_caches(self):
ops = """
[p1]
- i1 = getfield_gc_pure_i(p1, descr=valuedescr3)
+ i1 = getfield_gc_i(p1, descr=valuedescr3)
i2 = call_i(i1, descr=writevalue3descr)
- i3 = getfield_gc_pure_i(p1, descr=valuedescr3)
+ i3 = getfield_gc_i(p1, descr=valuedescr3)
jump(p1)
"""
expected_preamble = """
[p1]
- i1 = getfield_gc_pure_i(p1, descr=valuedescr3)
+ i1 = getfield_gc_i(p1, descr=valuedescr3)
i2 = call_i(i1, descr=writevalue3descr)
jump(p1, i1)
"""
@@ -4974,17 +4974,15 @@
ops = """
[p42]
p53 = getfield_gc_r(ConstPtr(myptr3), descr=nextdescr3)
- p59 = getfield_gc_pure_r(p53, descr=valuedescr3)
+ p59 = getfield_gc_r(p53, descr=valuedescr3)
i61 = call_i(1, p59, descr=nonwritedescr)
jump(p42)
"""
expected = """
- [p42, p59]
- i61 = call_i(1, p59, descr=nonwritedescr)
- jump(p42, p59)
-
- """
- self.node.value = 5
+ [p42]
+ i61 = call_i(1, 7, descr=nonwritedescr)
+ jump(p42)
+ """
self.optimize_loop(ops, expected)
def test_complains_getfieldpure_setfield(self):
@@ -4993,7 +4991,7 @@
ops = """
[p3]
p1 = escape_r()
- p2 = getfield_gc_pure_r(p1, descr=nextdescr)
+ p2 = getfield_gc_r(p1, descr=nextdescr)
setfield_gc(p1, p3, descr=nextdescr)
jump(p3)
"""
@@ -5003,7 +5001,7 @@
ops = """
[p3]
p1 = escape_r()
- p2 = getfield_gc_pure_r(p1, descr=nextdescr3)
+ p2 = getfield_gc_r(p1, descr=nextdescr3)
setfield_gc(p1, p3, descr=otherdescr)
escape_n(p2)
jump(p3)
@@ -5011,7 +5009,7 @@
expected = """
[p3]
p1 = escape_r()
- p2 = getfield_gc_pure_r(p1, descr=nextdescr3)
+ p2 = getfield_gc_r(p1, descr=nextdescr3)
setfield_gc(p1, p3, descr=otherdescr)
escape_n(p2)
jump(p3)
@@ -6168,14 +6166,14 @@
def test_bug_unroll_with_immutables(self):
ops = """
[p0]
- i2 = getfield_gc_pure_i(p0, descr=immut_intval)
+ i2 = getfield_gc_i(p0, descr=immut_intval)
p1 = new_with_vtable(descr=immut_descr)
setfield_gc(p1, 1242, descr=immut_intval)
jump(p1)
"""
preamble = """
[p0]
- i2 = getfield_gc_pure_i(p0, descr=immut_intval)
+ i2 = getfield_gc_i(p0, descr=immut_intval)
jump()
"""
expected = """
@@ -7157,13 +7155,13 @@
[p0, p1, i0]
quasiimmut_field(p0, descr=quasiimmutdescr)
guard_not_invalidated() []
- i1 = getfield_gc_pure_i(p0, descr=quasifielddescr)
+ i1 = getfield_gc_i(p0, descr=quasifielddescr)
escape_n(i1)
jump(p1, p0, i1)
"""
expected = """
[p0, p1, i0]
- i1 = getfield_gc_pure_i(p0, descr=quasifielddescr)
+ i1 = getfield_gc_i(p0, descr=quasifielddescr)
escape_n(i1)
jump(p1, p0, i1)
"""
@@ -7174,7 +7172,7 @@
[]
quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
guard_not_invalidated() []
- i1 = getfield_gc_pure_i(ConstPtr(quasiptr), descr=quasifielddescr)
+ i1 = getfield_gc_i(ConstPtr(quasiptr), descr=quasifielddescr)
escape_n(i1)
jump()
"""
@@ -7226,11 +7224,11 @@
[i0a, i0b]
quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
guard_not_invalidated() []
- i1 = getfield_gc_pure_i(ConstPtr(quasiptr), descr=quasifielddescr)
+ i1 = getfield_gc_i(ConstPtr(quasiptr), descr=quasifielddescr)
call_may_force_n(i0b, descr=mayforcevirtdescr)
quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr)
guard_not_invalidated() []
- i2 = getfield_gc_pure_i(ConstPtr(quasiptr), descr=quasifielddescr)
+ i2 = getfield_gc_i(ConstPtr(quasiptr), descr=quasifielddescr)
i3 = escape_i(i1)
i4 = escape_i(i2)
jump(i3, i4)
@@ -7253,11 +7251,11 @@
setfield_gc(p, 421, descr=quasifielddescr)
quasiimmut_field(p, descr=quasiimmutdescr)
guard_not_invalidated() []
- i1 = getfield_gc_pure_i(p, descr=quasifielddescr)
+ i1 = getfield_gc_i(p, descr=quasifielddescr)
call_may_force_n(i0b, descr=mayforcevirtdescr)
quasiimmut_field(p, descr=quasiimmutdescr)
guard_not_invalidated() []
- i2 = getfield_gc_pure_i(p, descr=quasifielddescr)
+ i2 = getfield_gc_i(p, descr=quasifielddescr)
i3 = escape_i(i1)
i4 = escape_i(i2)
jump(i3, i4)
@@ -7496,7 +7494,7 @@
def test_forced_virtual_pure_getfield(self):
ops = """
[p0]
- p1 = getfield_gc_pure_r(p0, descr=valuedescr3)
+ p1 = getfield_gc_r(p0, descr=valuedescr3)
jump(p1)
"""
self.optimize_loop(ops, ops)
@@ -7506,7 +7504,7 @@
p1 = new_with_vtable(descr=nodesize3)
setfield_gc(p1, p0, descr=valuedescr3)
escape_n(p1)
- p2 = getfield_gc_pure_r(p1, descr=valuedescr3)
+ p2 = getfield_gc_r(p1, descr=valuedescr3)
escape_n(p2)
jump(p0)
"""
@@ -7993,7 +7991,7 @@
def test_dont_mixup_equal_boxes(self):
ops = """
[p8]
- i9 = getfield_gc_pure_i(p8, descr=valuedescr3)
+ i9 = getfield_gc_i(p8, descr=valuedescr3)
i10 = int_gt(i9, 0)
guard_true(i10) []
i29 = int_lshift(i9, 1)
@@ -8088,9 +8086,9 @@
py.test.skip("would be fixed by make heap optimizer aware of virtual
setfields")
ops = """
[p5, p8]
- i9 = getfield_gc_pure_i(p5, descr=valuedescr)
+ i9 = getfield_gc_i(p5, descr=valuedescr)
call_n(i9, descr=nonwritedescr)
- i11 = getfield_gc_pure_i(p8, descr=valuedescr)
+ i11 = getfield_gc_i(p8, descr=valuedescr)
i13 = int_add_ovf(i11, 1)
guard_no_overflow() []
p22 = new_with_vtable(descr=nodesize)
@@ -8556,7 +8554,7 @@
quasiimmut_field(p69, descr=quasiimmutdescr)
guard_not_invalidated() []
- p71 = getfield_gc_pure_r(p69, descr=quasifielddescr) # inst_code
+ p71 = getfield_gc_r(p69, descr=quasifielddescr) # inst_code
guard_value(p71, -4247) []
p106 = new_with_vtable(descr=nodesize)
@@ -8578,7 +8576,7 @@
[p69]
quasiimmut_field(p69, descr=quasiimmutdescr)
guard_not_invalidated() []
- p71 = getfield_gc_pure_r(p69, descr=quasifielddescr) # inst_code
+ p71 = getfield_gc_r(p69, descr=quasifielddescr) # inst_code
guard_value(p71, -4247) []
jump(ConstPtr(myptr))
"""
@@ -8780,7 +8778,7 @@
def test_virtual_back_and_forth(self):
ops = """
[p0]
- p1 = getfield_gc_pure_r(p0, descr=valuedescr3)
+ p1 = getfield_gc_r(p0, descr=valuedescr3)
ptemp = new_with_vtable(descr=nodesize)
setfield_gc(ptemp, p1, descr=nextdescr)
p2 = getfield_gc_r(ptemp, descr=nextdescr)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_unroll.py
@@ -220,16 +220,16 @@
def test_double_getfield_plus_pure(self):
loop = """
[p0]
- pc = getfield_gc_pure_r(p0, descr=nextdescr3)
+ pc = getfield_gc_r(p0, descr=nextdescr3)
escape_n(p0) # that should flush the caches
p1 = getfield_gc_r(pc, descr=nextdescr3)
i0 = getfield_gc_i(p1, descr=valuedescr3)
jump(p0)
"""
es, loop, preamble = self.optimize(loop)
- assert len(es.short_boxes) == 4
+ assert len(es.short_boxes) == 7
# both getfields are available as
- # well as getfield_gc_pure
+ # well as getfield_gc
def test_p123_anti_nested(self):
loop = """
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
@@ -182,12 +182,6 @@
optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I
- # note: the following line does not mean that the two operations are
- # completely equivalent, because GETFIELD_GC_PURE is_always_pure().
- optimize_GETFIELD_GC_PURE_I = optimize_GETFIELD_GC_I
- optimize_GETFIELD_GC_PURE_R = optimize_GETFIELD_GC_I
- optimize_GETFIELD_GC_PURE_F = optimize_GETFIELD_GC_I
-
def optimize_SETFIELD_GC(self, op):
struct = op.getarg(0)
opinfo = self.getptrinfo(struct)
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -12,7 +12,7 @@
from rpython.jit.metainterp.jitprof import EmptyProfiler
from rpython.jit.metainterp.logger import Logger
from rpython.jit.metainterp.optimizeopt.util import args_dict
-from rpython.jit.metainterp.resoperation import rop, OpHelpers, GuardResOp
+from rpython.jit.metainterp.resoperation import rop, OpHelpers, GuardResOp,
is_pure_getfield
from rpython.rlib import nonconst, rstack
from rpython.rlib.debug import debug_start, debug_stop, debug_print
from rpython.rlib.debug import have_debug_prints, make_sure_not_resized
@@ -661,48 +661,52 @@
rop.INT_ADD, None, indexbox, lenbox)
return indexbox
+ # @arguments("box", "descr")
+ # def opimpl_getfield_gc_i(self, box, fielddescr):
+ # return self._opimpl_getfield_gc_any_pureornot(
+ # rop.GETFIELD_GC_I, box, fielddescr, 'i')
+ # @arguments("box", "descr")
+ # def opimpl_getfield_gc_r(self, box, fielddescr):
+ # return self._opimpl_getfield_gc_any_pureornot(
+ # rop.GETFIELD_GC_R, box, fielddescr, 'r')
+ # @arguments("box", "descr")
+ # def opimpl_getfield_gc_f(self, box, fielddescr):
+ # return self._opimpl_getfield_gc_any_pureornot(
+ # rop.GETFIELD_GC_F, box, fielddescr, 'f')
+
@arguments("box", "descr")
def opimpl_getfield_gc_i(self, box, fielddescr):
+ if fielddescr.is_always_pure() and isinstance(box, ConstPtr):
+ # if 'box' is directly a ConstPtr, bypass the heapcache completely
+ resbox = executor.execute(self.metainterp.cpu, self.metainterp,
+ rop.GETFIELD_GC_I, fielddescr, box)
+ return ConstInt(resbox)
return self._opimpl_getfield_gc_any_pureornot(
rop.GETFIELD_GC_I, box, fielddescr, 'i')
+
+ @arguments("box", "descr")
+ def opimpl_getfield_gc_f(self, box, fielddescr):
+ if fielddescr.is_always_pure() and isinstance(box, ConstPtr):
+ # if 'box' is directly a ConstPtr, bypass the heapcache completely
+ resvalue = executor.execute(self.metainterp.cpu, self.metainterp,
+ rop.GETFIELD_GC_F, fielddescr, box)
+ return ConstFloat(resvalue)
+ return self._opimpl_getfield_gc_any_pureornot(
+ rop.GETFIELD_GC_F, box, fielddescr, 'f')
+
@arguments("box", "descr")
def opimpl_getfield_gc_r(self, box, fielddescr):
+ if fielddescr.is_always_pure() and isinstance(box, ConstPtr):
+ # if 'box' is directly a ConstPtr, bypass the heapcache completely
+ val = executor.execute(self.metainterp.cpu, self.metainterp,
+ rop.GETFIELD_GC_R, fielddescr, box)
+ return ConstPtr(val)
return self._opimpl_getfield_gc_any_pureornot(
rop.GETFIELD_GC_R, box, fielddescr, 'r')
- @arguments("box", "descr")
- def opimpl_getfield_gc_f(self, box, fielddescr):
- return self._opimpl_getfield_gc_any_pureornot(
- rop.GETFIELD_GC_F, box, fielddescr, 'f')
-
- @arguments("box", "descr")
- def opimpl_getfield_gc_i_pure(self, box, fielddescr):
- if isinstance(box, ConstPtr):
- # if 'box' is directly a ConstPtr, bypass the heapcache completely
- resbox = executor.execute(self.metainterp.cpu, self.metainterp,
- rop.GETFIELD_GC_PURE_I, fielddescr, box)
- return ConstInt(resbox)
- return self._opimpl_getfield_gc_any_pureornot(
- rop.GETFIELD_GC_PURE_I, box, fielddescr, 'i')
-
- @arguments("box", "descr")
- def opimpl_getfield_gc_f_pure(self, box, fielddescr):
- if isinstance(box, ConstPtr):
- # if 'box' is directly a ConstPtr, bypass the heapcache completely
- resvalue = executor.execute(self.metainterp.cpu, self.metainterp,
- rop.GETFIELD_GC_PURE_F, fielddescr, box)
- return ConstFloat(resvalue)
- return self._opimpl_getfield_gc_any_pureornot(
- rop.GETFIELD_GC_PURE_F, box, fielddescr, 'f')
-
- @arguments("box", "descr")
- def opimpl_getfield_gc_r_pure(self, box, fielddescr):
- if isinstance(box, ConstPtr):
- # if 'box' is directly a ConstPtr, bypass the heapcache completely
- val = executor.execute(self.metainterp.cpu, self.metainterp,
- rop.GETFIELD_GC_PURE_R, fielddescr, box)
- return ConstPtr(val)
- return self._opimpl_getfield_gc_any_pureornot(
- rop.GETFIELD_GC_PURE_R, box, fielddescr, 'r')
+
+ opimpl_getfield_gc_i_pure = opimpl_getfield_gc_i
+ opimpl_getfield_gc_r_pure = opimpl_getfield_gc_r
+ opimpl_getfield_gc_f_pure = opimpl_getfield_gc_f
@arguments("box", "box", "descr")
def opimpl_getinteriorfield_gc_i(self, array, index, descr):
@@ -743,7 +747,7 @@
@arguments("box", "descr", "orgpc")
def _opimpl_getfield_gc_greenfield_any(self, box, fielddescr, pc):
ginfo = self.metainterp.jitdriver_sd.greenfield_info
- opnum = OpHelpers.getfield_pure_for_descr(fielddescr)
+ opnum = OpHelpers.getfield_for_descr(fielddescr)
if (ginfo is not None and fielddescr in ginfo.green_field_descrs
and not self._nonstandard_virtualizable(pc, box, fielddescr)):
# fetch the result, but consider it as a Const box and don't
@@ -2095,6 +2099,9 @@
resvalue = executor.execute(self.cpu, self, opnum, descr, *argboxes)
if rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST:
return self._record_helper_pure(opnum, resvalue, descr, *argboxes)
+ if is_pure_getfield(opnum, descr):
+ # TODO Don't base purity of an operation solely on opnum
+ return self._record_helper_pure(opnum, resvalue, descr, *argboxes)
if rop._OVF_FIRST <= opnum <= rop._OVF_LAST:
return self._record_helper_ovf(opnum, resvalue, descr, *argboxes)
return self._record_helper_nonpure_varargs(opnum, resvalue, descr,
diff --git a/rpython/jit/metainterp/resoperation.py
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -84,6 +84,10 @@
def get_forwarded(self):
return self._forwarded
+def is_pure_getfield(opnum, descr):
+ if opnum not in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F, rop.GETFIELD_GC_R):
+ return False
+ return descr is not None and descr.is_always_pure() != False
class AbstractResOp(AbstractResOpOrInputArg):
"""The central ResOperation class, representing one operation."""
@@ -267,9 +271,7 @@
return self.opnum in (rop.SAME_AS_I, rop.SAME_AS_F, rop.SAME_AS_R)
def is_getfield(self):
- return self.opnum in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F,
- rop.GETFIELD_GC_R, rop.GETFIELD_GC_PURE_I,
- rop.GETFIELD_GC_PURE_R, rop.GETFIELD_GC_PURE_F)
+ return self.opnum in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F,
rop.GETFIELD_GC_R)
def is_getarrayitem(self):
return self.opnum in (rop.GETARRAYITEM_GC_I, rop.GETARRAYITEM_GC_F,
@@ -340,6 +342,11 @@
_descr = None
+ def is_always_pure(self):
+ if self.is_getfield():
+ return self._descr.is_always_pure() != False
+ return AbstractResOp.is_always_pure(self)
+
def getdescr(self):
return self._descr
@@ -770,7 +777,6 @@
'ARRAYLEN_GC/1d/i',
'STRLEN/1/i',
'STRGETITEM/2/i',
- 'GETFIELD_GC_PURE/1d/rfi',
'GETFIELD_RAW_PURE/1d/rfi',
'GETARRAYITEM_GC_PURE/2d/rfi',
'GETARRAYITEM_RAW_PURE/2d/fi',
@@ -1110,14 +1116,6 @@
return rop.CALL_LOOPINVARIANT_N
@staticmethod
- def getfield_pure_for_descr(descr):
- if descr.is_pointer_field():
- return rop.GETFIELD_GC_PURE_R
- elif descr.is_float_field():
- return rop.GETFIELD_GC_PURE_F
- return rop.GETFIELD_GC_PURE_I
-
- @staticmethod
def getfield_for_descr(descr):
if descr.is_pointer_field():
return rop.GETFIELD_GC_R
diff --git a/rpython/jit/metainterp/test/test_ajit.py
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -320,7 +320,7 @@
assert res == 252
self.check_trace_count(1)
self.check_resops({'jump': 1, 'int_gt': 2, 'int_add': 2,
- 'getfield_gc_pure_i': 1, 'int_mul': 1,
+ 'getfield_gc_i': 1, 'int_mul': 1,
'guard_true': 2, 'int_sub': 2})
def test_loops_are_transient(self):
@@ -1405,7 +1405,7 @@
return tup[1]
res = self.interp_operations(f, [3, 5])
assert res == 5
- self.check_operations_history(setfield_gc=2, getfield_gc_pure_i=0)
+ self.check_operations_history(setfield_gc=2, getfield_gc_i=0)
def test_oosend_look_inside_only_one(self):
class A:
@@ -2522,7 +2522,7 @@
if counter > 10:
return 7
assert self.meta_interp(build, []) == 7
- self.check_resops(getfield_gc_pure_r=2)
+ self.check_resops(getfield_gc_r=2)
def test_args_becomming_equal(self):
myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', 'b'])
diff --git a/rpython/jit/metainterp/test/test_immutable.py
b/rpython/jit/metainterp/test/test_immutable.py
--- a/rpython/jit/metainterp/test/test_immutable.py
+++ b/rpython/jit/metainterp/test/test_immutable.py
@@ -19,7 +19,7 @@
return y.x + 5
res = self.interp_operations(f, [23])
assert res == 28
- self.check_operations_history(getfield_gc_i=0, getfield_gc_pure_i=1,
int_add=1)
+ self.check_operations_history(getfield_gc_i=1, int_add=1)
def test_fields_subclass(self):
class X(object):
@@ -41,8 +41,7 @@
return z.x + z.y + 5
res = self.interp_operations(f, [23, 11])
assert res == 39
- self.check_operations_history(getfield_gc_i=0, getfield_gc_pure_i=2,
- int_add=2)
+ self.check_operations_history(getfield_gc_i=2, int_add=2)
def f(x, y):
# this time, the field 'x' only shows up on subclass 'Y'
@@ -50,8 +49,7 @@
return z.x + z.y + 5
res = self.interp_operations(f, [23, 11])
assert res == 39
- self.check_operations_history(getfield_gc_i=0, getfield_gc_pure_i=2,
- int_add=2)
+ self.check_operations_history(getfield_gc_i=2, int_add=2)
def test_array(self):
class X(object):
@@ -66,8 +64,7 @@
return a.y[index]
res = self.interp_operations(f, [2], listops=True)
assert res == 30
- self.check_operations_history(getfield_gc_r=0, getfield_gc_pure_r=1,
- getarrayitem_gc_i=0, getarrayitem_gc_pure_i=1)
+ self.check_operations_history(getfield_gc_r=1, getarrayitem_gc_i=0,
getarrayitem_gc_pure_i=1)
def test_array_index_error(self):
class X(object):
@@ -89,8 +86,7 @@
return a.get(index)
res = self.interp_operations(f, [2], listops=True)
assert res == 30
- self.check_operations_history(getfield_gc_r=0, getfield_gc_pure_r=1,
- getarrayitem_gc_i=0, getarrayitem_gc_pure_i=1)
+ self.check_operations_history(getfield_gc_r=1, getarrayitem_gc_i=0,
getarrayitem_gc_pure_i=1)
def test_array_in_immutable(self):
class X(object):
@@ -106,8 +102,7 @@
return y.lst[index] + y.y + 5
res = self.interp_operations(f, [23, 0], listops=True)
assert res == 23 + 24 + 5
- self.check_operations_history(getfield_gc_r=0, getfield_gc_pure_r=1,
- getfield_gc_pure_i=1,
+ self.check_operations_history(getfield_gc_r=1, getfield_gc_i=1,
getarrayitem_gc_i=0, getarrayitem_gc_pure_i=1,
int_add=3)
diff --git a/rpython/jit/metainterp/test/test_quasiimmut.py
b/rpython/jit/metainterp/test/test_quasiimmut.py
--- a/rpython/jit/metainterp/test/test_quasiimmut.py
+++ b/rpython/jit/metainterp/test/test_quasiimmut.py
@@ -74,7 +74,7 @@
#
res = self.meta_interp(f, [100, 7])
assert res == 700
- self.check_resops(guard_not_invalidated=2, getfield_gc=0)
+ self.check_resops(guard_not_invalidated=2)
#
from rpython.jit.metainterp.warmspot import get_stats
loops = get_stats().loops
@@ -101,7 +101,7 @@
res = self.meta_interp(f, [100, 7], enable_opts="")
assert res == 700
# there should be no getfields, even though optimizations are turned
off
- self.check_resops(guard_not_invalidated=1, getfield_gc=0)
+ self.check_resops(guard_not_invalidated=1)
def test_nonopt_1(self):
myjitdriver = JitDriver(greens=[], reds=['x', 'total', 'lst'])
@@ -124,8 +124,7 @@
assert f(100, 7) == 721
res = self.meta_interp(f, [100, 7])
assert res == 721
- self.check_resops(guard_not_invalidated=0, getfield_gc_r=1,
- getfield_gc_pure_i=2)
+ self.check_resops(guard_not_invalidated=0, getfield_gc_r=1,
getfield_gc_i=2)
#
from rpython.jit.metainterp.warmspot import get_stats
loops = get_stats().loops
@@ -156,7 +155,7 @@
#
res = self.meta_interp(f, [100, 7])
assert res == 700
- self.check_resops(guard_not_invalidated=2, getfield_gc=0)
+ self.check_resops(guard_not_invalidated=2)
def test_change_during_tracing_1(self):
myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -208,7 +207,7 @@
assert f(100, 7) == 700
res = self.meta_interp(f, [100, 7])
assert res == 700
- self.check_resops(guard_not_invalidated=0, getfield_gc=0)
+ self.check_resops(guard_not_invalidated=0)
def test_change_invalidate_reentering(self):
myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -234,7 +233,7 @@
assert g(100, 7) == 700707
res = self.meta_interp(g, [100, 7])
assert res == 700707
- self.check_resops(guard_not_invalidated=4, getfield_gc=0)
+ self.check_resops(guard_not_invalidated=4)
def test_invalidate_while_running(self):
jitdriver = JitDriver(greens=['foo'], reds=['i', 'total'])
@@ -348,7 +347,7 @@
res = self.meta_interp(f, [100, 30])
assert res == 6019
self.check_resops(guard_not_invalidated=8, guard_not_forced=0,
- call_may_force=0, getfield_gc=0)
+ call_may_force=0)
def test_list_simple_1(self):
myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
@@ -374,8 +373,7 @@
getarrayitem_gc_pure_r=0,
getarrayitem_gc_i=0,
getarrayitem_gc_r=0,
- getfield_gc_i=0, getfield_gc_pure_i=0,
- getfield_gc_r=0, getfield_gC_pure_r=0)
+ getfield_gc_i=0, getfield_gc_r=0)
#
from rpython.jit.metainterp.warmspot import get_stats
loops = get_stats().loops
@@ -405,9 +403,7 @@
assert res == 700
# operations must have been removed by the frontend
self.check_resops(getarrayitem_gc_pure_i=0, guard_not_invalidated=1,
- getarrayitem_gc_i=0,
- getfield_gc=0, getfield_gc_pure_i=0,
- getfield_gc_pure_r=0)
+ getarrayitem_gc_i=0, getfield_gc_i=0,
getfield_gc_r=0)
def test_list_length_1(self):
myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
diff --git a/rpython/jit/metainterp/test/test_tracingopts.py
b/rpython/jit/metainterp/test/test_tracingopts.py
--- a/rpython/jit/metainterp/test/test_tracingopts.py
+++ b/rpython/jit/metainterp/test/test_tracingopts.py
@@ -436,10 +436,10 @@
return p.x[0] + p.x[1]
res = self.interp_operations(fn, [7])
assert res == 7 + 7 + 1
- self.check_operations_history(getfield_gc_r=0, getfield_gc_pure_r=0)
+ self.check_operations_history(getfield_gc_r=0)
res = self.interp_operations(fn, [-7])
assert res == -7 - 7 + 1
- self.check_operations_history(getfield_gc_r=0, getfield_gc_pure_r=0)
+ self.check_operations_history(getfield_gc_r=0)
def test_heap_caching_and_elidable_function(self):
class A:
@@ -517,12 +517,12 @@
return a1[0] + a2[0] + gn(a1, a2)
res = self.interp_operations(fn, [7])
assert res == 2 * 7 + 2 * 6
- self.check_operations_history(getfield_gc_pure_i=0,
- getfield_gc_pure_r=0)
+ self.check_operations_history(getfield_gc_i=0,
+ getfield_gc_r=0)
res = self.interp_operations(fn, [-7])
assert res == 2 * -7 + 2 * -8
- self.check_operations_history(getfield_gc_pure_i=0,
- getfield_gc_pure_r=0)
+ self.check_operations_history(getfield_gc_i=0,
+ getfield_gc_r=0)
def test_heap_caching_multiple_arrays(self):
class Gbl(object):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit