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