Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: record-known-result
Changeset: r97695:0f0cf3af2deb
Date: 2019-10-01 13:47 +0200
http://bitbucket.org/pypy/pypy/changeset/0f0cf3af2deb/

Log:    (cfbolz porting, yodada did the actual work) implement
        record_exact_value by stealing the code from the record-exact-value
        branch. it's another rlib.jit.record_* hint, this one can be used to
        tell the JIT about a known constant value

diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -309,6 +309,9 @@
             op1 = [op1, SpaceOperation('-live-', [], None)]
         return op1
 
+    def rewrite_op_jit_record_exact_value(self, op):
+        return SpaceOperation("record_exact_value", [op.args[0], op.args[1]], 
None)
+
     def rewrite_op_debug_assert_not_none(self, op):
         if isinstance(op.args[0], Variable):
             return SpaceOperation('assert_not_none', [op.args[0]], None)
diff --git a/rpython/jit/metainterp/blackhole.py 
b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -602,6 +602,10 @@
                                      calldescr):
         pass
 
+    @arguments("r", "r")
+    def bhimpl_record_exact_value(a, b):
+        pass
+
     @arguments("i", returns="i")
     def bhimpl_int_copy(a):
         return a
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
@@ -541,6 +541,12 @@
         self.make_constant_class(op.getarg(0), expectedclassbox,
                                  update_last_guard=False)
 
+    def optimize_RECORD_EXACT_VALUE(self, op):
+        box = op.getarg(0)
+        expectedconstbox = op.getarg(1)
+        assert isinstance(expectedconstbox, Const)
+        self.make_constant(box, expectedconstbox)
+
     def optimize_GUARD_CLASS(self, op):
         expectedclassbox = op.getarg(1)
         info = self.ensure_ptr_info_arg0(op)
diff --git a/rpython/jit/metainterp/optimizeopt/simplify.py 
b/rpython/jit/metainterp/optimizeopt/simplify.py
--- a/rpython/jit/metainterp/optimizeopt/simplify.py
+++ b/rpython/jit/metainterp/optimizeopt/simplify.py
@@ -43,6 +43,9 @@
     def optimize_RECORD_EXACT_CLASS(self, op):
         pass
 
+    def optimize_RECORD_EXACT_VALUE(self, op):
+        pass
+
     def optimize_GUARD_FUTURE_CONDITION(self, op):
         self.optimizer.notice_guard_future_condition(op)
 
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
@@ -7212,6 +7212,21 @@
         self.optimize_loop(ops, expected)
 
 
+    def test_record_exact_value(self):
+        ops = """
+        [p0]
+        record_exact_value(p0, ConstPtr(myptr3))
+        i1 = getfield_gc_i(p0, descr=valuedescr3)
+        escape_i(i1)
+        jump(p0)
+        """
+        expected = """
+        []
+        escape_i(7)
+        jump()
+        """
+        self.optimize_loop(ops, expected)
+
     def test_quasi_immut(self):
         ops = """
         [p0, p1, i0]
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
@@ -313,6 +313,21 @@
         # an operation
         
self.metainterp._record_helper_nonpure_varargs(rop.RECORD_KNOWN_RESULT, None, 
calldescr, allboxes)
 
+    @arguments("box", "box")
+    def opimpl_record_exact_value(self, box, const_box):
+        if isinstance(const_box, Const):
+            self.execute(rop.RECORD_EXACT_VALUE, box, const_box)
+        elif have_debug_prints():
+            if len(self.metainterp.framestack) >= 2:
+                # caller of ll_record_exact_value
+                name = self.metainterp.framestack[-2].jitcode.name
+            else:
+                name = self.jitcode.name
+            loc = 
self.metainterp.jitdriver_sd.warmstate.get_location_str(self.greenkey)
+            debug_print("record_exact_value with non-constant second argument, 
ignored",
+                    name, loc)
+
+
     @arguments("box")
     def _opimpl_any_return(self, box):
         self.metainterp.finishframe(box)
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
@@ -137,7 +137,7 @@
         return 'v' + str(num)
     if hasattr(self, '_vec_debug_info'):
         vecinfo = self._vec_debug_info
-        count = vecinfo.count 
+        count = vecinfo.count
         datatype = vecinfo.datatype
         bytesize = vecinfo.bytesize
     elif self.vector == -2:
@@ -322,7 +322,7 @@
         "shallow copy: the returned operation is meant to be used in place of 
self"
         # XXX specialize
         from rpython.jit.metainterp.history import DONT_CHANGE
-        
+
         if args is None:
             args = self.getarglist_copy()
         if descr is None:
@@ -1143,6 +1143,7 @@
     'QUASIIMMUT_FIELD/1d/n',    # [objptr], descr=SlowMutateDescr
     'ASSERT_NOT_NONE/1/n',      # [objptr]
     'RECORD_EXACT_CLASS/2/n',   # [objptr, clsptr]
+    'RECORD_EXACT_VALUE/2/n',   # [objptr, objptr]
     'KEEPALIVE/1/n',
     'SAVE_EXCEPTION/0/r',
     'SAVE_EXC_CLASS/0/i',       # XXX kill me
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
@@ -2,7 +2,6 @@
 import sys
 
 import py
-import weakref
 
 from rpython.rlib import rgc
 from rpython.jit.codewriter.policy import StopAtXPolicy
@@ -14,7 +13,8 @@
 from rpython.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside,
     loop_invariant, elidable, promote, jit_debug, assert_green,
     AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
-    isconstant, isvirtual, set_param, record_exact_class, record_known_result)
+    isconstant, isvirtual, set_param, record_exact_class, record_known_result,
+    record_exact_value)
 from rpython.rlib.longlong2float import float2longlong, longlong2float
 from rpython.rlib.rarithmetic import ovfcheck, is_valid_int, int_force_ge_zero
 from rpython.rtyper.lltypesystem import lltype, rffi
@@ -4016,6 +4016,33 @@
         assert res == main(10)
         self.check_resops(call_i=2)  # two calls to f, both get removed by the 
backend
 
+
+    def test_record_exact_value(self):
+        class A(object):
+            _immutable_fields_ = ['x']
+
+        a = A()
+        b = A()
+        a.x = 42
+        b.x = 233
+
+        @dont_look_inside
+        def make(x):
+            if x > 0:
+                return a
+            else:
+                return b
+        def f(x):
+            inst = make(x)
+            if x > 0:
+                record_exact_value(inst, a)
+            else:
+                record_exact_value(inst, b)
+            return inst.x
+        res = self.interp_operations(f, [1])
+        assert res == 42
+        self.check_operations_history(record_exact_value=1)
+
     def test_generator(self):
         def g(n):
             yield n+1
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1232,6 +1232,36 @@
         return hop.genop("jit_record_known_result", args_v, 
resulttype=lltype.Void)
 
 
+def record_exact_value(value, const_value):
+    """
+    Assure the JIT that value is the same as const_value
+    """
+    assert value is const_value
+
+def ll_record_exact_value(ll_value, ll_const_value):
+    from rpython.rlib.debug import ll_assert
+    from rpython.rtyper.lltypesystem.lloperation import llop
+    from rpython.rtyper.lltypesystem import lltype
+    ll_assert(ll_value is ll_const_value, "record_exact_value called with two 
different arguments")
+    llop.jit_record_exact_value(lltype.Void, ll_value, ll_const_value)
+
+class Entry(ExtRegistryEntry):
+    _about_ = record_exact_value
+
+    def compute_result_annotation(self, s_inst, s_const_inst):
+        from rpython.annotator import model as annmodel
+        assert isinstance(s_inst, annmodel.SomeInstance)
+        assert isinstance(s_const_inst, annmodel.SomeInstance)
+
+    def specialize_call(self, hop):
+        from rpython.rtyper.lltypesystem import lltype
+        from rpython.rtyper import rclass
+
+        v_inst = hop.inputarg(hop.args_r[0], arg=0)
+        v_const_inst = hop.inputarg(hop.args_r[1], arg=1)
+        hop.exception_is_here()
+        return hop.gendirectcall(ll_record_exact_value, v_inst, v_const_inst)
+
 def _jit_conditional_call(condition, function, *args):
     pass           # special-cased below
 
diff --git a/rpython/rlib/test/test_jit.py b/rpython/rlib/test/test_jit.py
--- a/rpython/rlib/test/test_jit.py
+++ b/rpython/rlib/test/test_jit.py
@@ -5,7 +5,8 @@
 from rpython.rlib.jit import (hint, we_are_jitted, JitDriver, elidable_promote,
     JitHintError, oopspec, isconstant, conditional_call,
     elidable, unroll_safe, dont_look_inside, conditional_call_elidable,
-    enter_portal_frame, leave_portal_frame, record_known_result)
+    enter_portal_frame, leave_portal_frame, record_known_result,
+    record_exact_value)
 from rpython.rlib.rarithmetic import r_uint
 from rpython.rtyper.test.tool import BaseRtypingTest
 from rpython.rtyper.lltypesystem import lltype
@@ -121,6 +122,15 @@
         def f():
             pass
 
+def test_record_exact_value():
+    class A(object):
+        pass
+    a = A()
+    b = A()
+    record_exact_value(a,a) # assume not crash
+    with pytest.raises(AssertionError):
+        record_exact_value(a, b)
+
 class TestJIT(BaseRtypingTest):
     def test_hint(self):
         def f():
@@ -351,6 +361,15 @@
         t = Translation(g, [])
         t.compile_c() # does not crash
 
+    def test_record_exact_value(self):
+        class A(object):
+            pass
+        def g():
+            a = A()
+            b = A()
+            record_exact_value(a,a) # assume not crash
+        self.interpret(g, [])
+
     def test_record_known_result(self):
         from rpython.translator.interactive import Translation
         @elidable
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -563,6 +563,9 @@
     def op_jit_record_exact_class(self, *args):
         pass
 
+    def op_jit_record_exact_value(self, *args):
+        pass
+
     def op_jit_conditional_call(self, *args):
         raise NotImplementedError("should not be called while not jitted")
 
diff --git a/rpython/rtyper/lltypesystem/lloperation.py 
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -456,6 +456,7 @@
     'jit_is_virtual':       LLOp(canrun=True),
     'jit_force_quasi_immutable': LLOp(canrun=True),
     'jit_record_exact_class'  : LLOp(canrun=True),
+    'jit_record_exact_value'  : LLOp(canrun=True),
     'jit_ffi_save_result':  LLOp(canrun=True),
     'jit_conditional_call': LLOp(),
     'jit_conditional_call_value': LLOp(),
diff --git a/rpython/rtyper/lltypesystem/opimpl.py 
b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -636,6 +636,9 @@
 def op_jit_record_exact_class(x, y):
     pass
 
+def op_jit_record_exact_value(x, y):
+    pass
+
 def op_jit_ffi_save_result(*args):
     pass
 
diff --git a/rpython/translator/c/src/support.h 
b/rpython/translator/c/src/support.h
--- a/rpython/translator/c/src/support.h
+++ b/rpython/translator/c/src/support.h
@@ -7,6 +7,7 @@
 
 #define RUNNING_ON_LLINTERP    0
 #define OP_JIT_RECORD_EXACT_CLASS(i, c, r)  /* nothing */
+#define OP_JIT_RECORD_EXACT_VALUE(i, c, r)  /* nothing */
 
 #define FAIL_OVF(msg) _RPyRaiseSimpleException(RPyExc_OverflowError)
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to