Author: Spenser Bauman <saba...@gmail.com>
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
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to