Author: Maciej Fijalkowski <[email protected]>
Branch: share-guard-info
Changeset: r79854:3fb386e048dd
Date: 2015-09-26 13:35 +0200
http://bitbucket.org/pypy/pypy/changeset/3fb386e048dd/
Log: implement fishing guard_value value directly from a jitframe, hence
removing the need of failargs storing the argument, hence we can
share stuff across guard_value
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
@@ -671,6 +671,8 @@
a0, a1 = boxes
imm_a1 = check_imm_box(a1)
l0 = self.make_sure_var_in_reg(a0, boxes)
+ op.getdescr().make_a_counter_per_value(op,
+ self.cpu.all_reg_indexes[l0.value])
if not imm_a1:
l1 = self.make_sure_var_in_reg(a1, boxes)
else:
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
@@ -40,6 +40,10 @@
self.inputargs = map(mapping, inputargs)
self.operations = []
for op in operations:
+ if op.getopnum() == rop.GUARD_VALUE:
+ # we don't care about the value 13 here, because we gonna
+ # fish it from the extra slot on frame anyway
+ op.getdescr().make_a_counter_per_value(op, 13)
if op.getdescr() is not None:
if op.is_guard() or op.getopnum() == rop.FINISH:
newdescr = op.getdescr()
@@ -372,6 +376,18 @@
except ExecutionFinished, e:
return e.deadframe
+ def get_value_direct(self, deadframe, tp, index):
+ v = deadframe._extra_value
+ if tp == 'i':
+ assert lltype.typeOf(v) == lltype.Signed
+ elif tp == 'r':
+ assert lltype.typeOf(v) == llmemory.GCREF
+ elif tp == 'f':
+ assert lltype.typeOf(v) == longlong.FLOATSTORAGE
+ else:
+ assert False
+ return v
+
def get_int_value(self, deadframe, index):
v = deadframe._values[index]
assert lltype.typeOf(v) == lltype.Signed
@@ -775,11 +791,13 @@
_TYPE = llmemory.GCREF
def __init__(self, latest_descr, values,
- last_exception=None, saved_data=None):
+ last_exception=None, saved_data=None,
+ extra_value=None):
self._latest_descr = latest_descr
self._values = values
self._last_exception = last_exception
self._saved_data = saved_data
+ self._extra_value = extra_value
class LLFrame(object):
@@ -872,7 +890,7 @@
# -----------------------------------------------------
- def fail_guard(self, descr, saved_data=None):
+ def fail_guard(self, descr, saved_data=None, extra_value=None):
values = []
for box in self.current_op.getfailargs():
if box is not None:
@@ -887,7 +905,7 @@
else:
raise ExecutionFinished(LLDeadFrame(descr, values,
self.last_exception,
- saved_data))
+ saved_data, extra_value))
def execute_force_spill(self, _, arg):
pass
@@ -909,7 +927,7 @@
def execute_guard_value(self, descr, arg1, arg2):
if arg1 != arg2:
- self.fail_guard(descr)
+ self.fail_guard(descr, extra_value=arg1)
def execute_guard_nonnull(self, descr, arg):
if not arg:
diff --git a/rpython/jit/backend/llsupport/llmodel.py
b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -389,20 +389,40 @@
descr = self.get_latest_descr(deadframe)
return rffi.cast(lltype.Signed, descr.rd_locs[index]) * WORD
+ @specialize.arg(2)
+ def get_value_direct(self, deadframe, tp, index):
+ if tp == 'i':
+ return self.get_int_value_direct(deadframe, index * WORD)
+ elif tp == 'r':
+ return self.get_ref_value_direct(deadframe, index * WORD)
+ elif tp == 'f':
+ return self.get_float_value_direct(deadframe, index * WORD)
+ else:
+ assert False
+
def get_int_value(self, deadframe, index):
pos = self._decode_pos(deadframe, index)
+ return self.get_int_value_direct(deadframe, pos)
+
+ def get_int_value_direct(self, deadframe, pos):
descr = self.gc_ll_descr.getframedescrs(self).arraydescr
ofs = self.unpack_arraydescr(descr)
return self.read_int_at_mem(deadframe, pos + ofs, WORD, 1)
def get_ref_value(self, deadframe, index):
pos = self._decode_pos(deadframe, index)
+ return self.get_ref_value_direct(deadframe, pos)
+
+ def get_ref_value_direct(self, deadframe, pos):
descr = self.gc_ll_descr.getframedescrs(self).arraydescr
ofs = self.unpack_arraydescr(descr)
return self.read_ref_at_mem(deadframe, pos + ofs)
def get_float_value(self, deadframe, index):
pos = self._decode_pos(deadframe, index)
+ return self.get_float_value_direct(deadframe, pos)
+
+ def get_float_value_direct(self, deadframe, pos):
descr = self.gc_ll_descr.getframedescrs(self).arraydescr
ofs = self.unpack_arraydescr(descr)
return self.read_float_at_mem(deadframe, pos + ofs)
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
@@ -424,6 +424,8 @@
def consider_guard_value(self, op):
x = self.make_sure_var_in_reg(op.getarg(0))
+ loc = self.assembler.cpu.all_reg_indexes[x.value]
+ op.getdescr().make_a_counter_per_value(op, loc)
y = self.loc(op.getarg(1))
self.perform_guard(op, [x, y], None)
diff --git a/rpython/jit/metainterp/compile.py
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -777,12 +777,15 @@
# fetch the actual value of the guard_value, possibly turning
# it to an integer
if typetag == self.TY_INT:
- intval = metainterp_sd.cpu.get_int_value(deadframe, index)
+ intval = metainterp_sd.cpu.get_value_direct(deadframe, 'i',
+ index)
elif typetag == self.TY_REF:
- refval = metainterp_sd.cpu.get_ref_value(deadframe, index)
+ refval = metainterp_sd.cpu.get_value_direct(deadframe, 'r',
+ index)
intval = lltype.cast_ptr_to_int(refval)
elif typetag == self.TY_FLOAT:
- floatval = metainterp_sd.cpu.get_float_value(deadframe, index)
+ floatval = metainterp_sd.cpu.get_value_direct(deadframe, 'f',
+ index)
intval = longlong.gethash_fast(floatval)
else:
assert 0, typetag
@@ -798,11 +801,6 @@
increment = jitdriver_sd.warmstate.increment_trace_eagerness
return jitcounter.tick(hash, increment)
- def get_index_of_guard_value(self):
- if (self.status & self.ST_TYPE_MASK) == 0:
- return -1
- return intmask(self.status >> self.ST_SHIFT)
-
def start_compiling(self):
# start tracing and compiling from this guard.
self.status |= self.ST_BUSY_FLAG
@@ -829,23 +827,18 @@
new_loop.original_jitcell_token,
metainterp.box_names_memo)
- def make_a_counter_per_value(self, guard_value_op):
+ def make_a_counter_per_value(self, guard_value_op, index):
assert guard_value_op.getopnum() == rop.GUARD_VALUE
box = guard_value_op.getarg(0)
- try:
- i = guard_value_op.getfailargs().index(box)
- except ValueError:
- return # xxx probably very rare
+ if box.type == history.INT:
+ ty = self.TY_INT
+ elif box.type == history.REF:
+ ty = self.TY_REF
+ elif box.type == history.FLOAT:
+ ty = self.TY_FLOAT
else:
- if box.type == history.INT:
- ty = self.TY_INT
- elif box.type == history.REF:
- ty = self.TY_REF
- elif box.type == history.FLOAT:
- ty = self.TY_FLOAT
- else:
- assert 0, box.type
- self.status = ty | (r_uint(i) << self.ST_SHIFT)
+ assert 0, box.type
+ self.status = ty | (r_uint(index) << self.ST_SHIFT)
class ResumeGuardExcDescr(ResumeGuardDescr):
pass
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -597,8 +597,7 @@
def emit_guard_operation(self, op, pendingfields):
guard_op = self.replace_op_with(op, op.getopnum())
opnum = guard_op.getopnum()
- if (self._last_guard_op and guard_op.getdescr() is None and
- opnum != rop.GUARD_VALUE):
+ if (self._last_guard_op and guard_op.getdescr() is None):
self.metainterp_sd.profiler.count_ops(opnum,
jitprof.Counters.OPT_GUARDS_SHARED)
op = self._copy_resume_data_from(guard_op,
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
@@ -1480,16 +1480,6 @@
res = self.meta_interp(f, [299], listops=True)
assert res == f(299)
self.check_resops(guard_class=4, guard_value=6)
- #
- # The original 'guard_class' is rewritten to be directly 'guard_value'.
- # Check that this rewrite does not interfere with the descr, which
- # should be a full-fledged multivalued 'guard_value' descr.
- if self.basic:
- for loop in get_stats().get_all_loops():
- for op in loop.get_operations():
- if op.getopname() == "guard_value":
- descr = op.getdescr()
- assert descr.get_index_of_guard_value() >= 0
def test_merge_guardnonnull_guardclass(self):
myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit