[pypy-commit] pypy share-guard-info: an attempt at sharing guards
fijal
noreply at buildbot.pypy.org
Thu Sep 17 19:14:24 CEST 2015
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: share-guard-info
Changeset: r79675:95a1828c06f1
Date: 2015-09-17 19:14 +0200
http://bitbucket.org/pypy/pypy/changeset/95a1828c06f1/
Log: an attempt at sharing guards
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
@@ -68,11 +68,13 @@
the label
"""
def __init__(self, start_label, operations, call_pure_results=None,
- enable_opts=None):
+ enable_opts=None, origin_jitcode=None, origin_pc=0):
self.start_label = start_label
self.operations = operations
self.call_pure_results = call_pure_results
self.enable_opts = enable_opts
+ self.origin_jitcode = origin_jitcode
+ self.origin_pc = origin_pc
def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer
@@ -80,19 +82,23 @@
#assert not unroll
opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations)
return opt.propagate_all_forward(self.start_label.getarglist(),
- self.operations, self.call_pure_results)
+ self.operations, self.call_pure_results,
+ origin_jitcode=self.origin_jitcode, origin_pc=self.origin_pc)
class BridgeCompileData(CompileData):
""" This represents ops() with a jump at the end that goes to some
loop, we need to deal with virtual state and inlining of short preamble
"""
def __init__(self, start_label, operations, call_pure_results=None,
- enable_opts=None, inline_short_preamble=False):
+ enable_opts=None, inline_short_preamble=False,
+ origin_jitcode=None, origin_pc=0):
self.start_label = start_label
self.operations = operations
self.call_pure_results = call_pure_results
self.enable_opts = enable_opts
self.inline_short_preamble = inline_short_preamble
+ self.origin_jitcode = origin_jitcode
+ self.origin_pc = origin_pc
def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer
@@ -101,7 +107,8 @@
return opt.optimize_bridge(self.start_label, self.operations,
self.call_pure_results,
self.inline_short_preamble,
- self.box_names_memo)
+ self.box_names_memo,
+ self.origin_jitcode, self.origin_pc)
class UnrolledLoopData(CompileData):
""" This represents label() ops jump with extra info that's from the
@@ -675,10 +682,13 @@
class ResumeGuardDescr(ResumeDescr):
_attrs_ = ('rd_numb', 'rd_count', 'rd_consts', 'rd_virtuals',
- 'rd_frame_info_list', 'rd_pendingfields', 'status')
+ 'rd_frame_info_list', 'rd_pendingfields', 'status',
+ 'rd_origin_jitcode', 'rd_origin_pc')
rd_numb = lltype.nullptr(NUMBERING)
rd_count = 0
+ rd_origin_pc = 0
+ rd_origin_jitcode = None
rd_consts = None
rd_virtuals = None
rd_frame_info_list = None
@@ -990,6 +1000,9 @@
return resumedescr
class ResumeFromInterpDescr(ResumeDescr):
+ rd_origin_jitcode = None
+ rd_origin_pc = 0
+
def __init__(self, original_greenkey):
self.original_greenkey = original_greenkey
@@ -1042,11 +1055,15 @@
data = BridgeCompileData(label, operations[:],
call_pure_results=call_pure_results,
enable_opts=enable_opts,
- inline_short_preamble=inline_short_preamble)
+ inline_short_preamble=inline_short_preamble,
+ origin_jitcode=resumekey.rd_origin_jitcode,
+ origin_pc=resumekey.rd_origin_pc)
else:
data = SimpleCompileData(label, operations[:],
call_pure_results=call_pure_results,
- enable_opts=enable_opts)
+ enable_opts=enable_opts,
+ origin_jitcode=resumekey.rd_origin_jitcode,
+ origin_pc=resumekey.rd_origin_pc)
try:
info, newops = optimize_trace(metainterp_sd, jitdriver_sd,
data, metainterp.box_names_memo)
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -107,6 +107,8 @@
self.last_guard_pos = -1
def mark_last_guard(self, optimizer):
+ if optimizer.getlastop() is None:
+ return
self.last_guard_pos = len(optimizer._newoperations) - 1
assert self.get_last_guard(optimizer).is_guard()
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
@@ -497,7 +497,10 @@
return CONST_0
def propagate_all_forward(self, inputargs, ops, call_pure_results=None,
- rename_inputargs=True, flush=True):
+ rename_inputargs=True, flush=True,
+ origin_jitcode=None, origin_pc=0):
+ self.origin_jitcode = origin_jitcode
+ self.origin_pc = origin_pc
if rename_inputargs:
newargs = []
for inparg in inputargs:
@@ -563,6 +566,14 @@
op.setarg(i, arg)
self.metainterp_sd.profiler.count(jitprof.Counters.OPT_OPS)
if op.is_guard():
+ assert isinstance(op, GuardResOp)
+ if self.origin_jitcode is not None:
+ if (self.origin_jitcode is op.rd_frame_info_list.jitcode and
+ self.origin_pc is op.rd_frame_info_list.pc):
+ self.origin_jitcode = None
+ self.origin_pc = 0
+ else:
+ return # we optimize the guard
self.metainterp_sd.profiler.count(jitprof.Counters.OPT_GUARDS)
pendingfields = self.pendingfields
self.pendingfields = None
@@ -573,7 +584,8 @@
else:
guard_op = self.replace_op_with(op, op.getopnum())
if (self._last_guard_op and guard_op.getdescr() is None and
- guard_op.getopnum() != rop.GUARD_VALUE):
+ guard_op.getopnum() != rop.GUARD_VALUE and
+ not guard_op.same_guard_position(self._last_guard_op)):
op = self._copy_resume_data_from(guard_op,
self._last_guard_op)
else:
@@ -599,6 +611,8 @@
guard_op.setdescr(descr)
descr.store_final_boxes(guard_op, last_guard_op.getfailargs(),
self.metainterp_sd)
+ descr.rd_origin_jitcode = guard_op.rd_frame_info_list.jitcode
+ descr.rd_origin_pc = guard_op.rd_frame_info_list.pc
if guard_op.getopnum() == rop.GUARD_VALUE:
guard_op = self._maybe_replace_guard_value(guard_op, descr)
return guard_op
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -223,12 +223,14 @@
return label_vs
def optimize_bridge(self, start_label, operations, call_pure_results,
- inline_short_preamble, box_names_memo):
+ inline_short_preamble, box_names_memo,
+ origin_jitcode=None, origin_pc=0):
self._check_no_forwarding([start_label.getarglist(),
operations])
info, ops = self.optimizer.propagate_all_forward(
start_label.getarglist()[:], operations[:-1],
- call_pure_results, True)
+ call_pure_results, True, origin_jitcode=origin_jitcode,
+ origin_pc=origin_pc)
jump_op = operations[-1]
cell_token = jump_op.getdescr()
assert isinstance(cell_token, JitCellToken)
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
@@ -378,6 +378,13 @@
newop.rd_frame_info_list = self.rd_frame_info_list
return newop
+ def same_guard_position(self, other):
+ assert isinstance(other, GuardResOp)
+ frame_info1 = self.rd_frame_info_list
+ frame_info2 = other.rd_frame_info_list
+ return (frame_info1.jitcode is frame_info2.jitcode and
+ frame_info1.pc == frame_info2.pc)
+
# ===========
# type mixins
# ===========
diff --git a/rpython/jit/metainterp/test/test_loop.py b/rpython/jit/metainterp/test/test_loop.py
--- a/rpython/jit/metainterp/test/test_loop.py
+++ b/rpython/jit/metainterp/test/test_loop.py
@@ -1090,5 +1090,23 @@
self.meta_interp(f, [30])
self.check_trace_count(3)
+ def test_sharing_guards(self):
+ driver = JitDriver(greens = [], reds = 'auto')
+
+ def f(i):
+ s = 0
+ while i > 0:
+ driver.jit_merge_point()
+ if s > 100:
+ raise Exception
+ if s > 9:
+ s += 1 # bridge
+ s += 1
+ i -= 1
+
+ self.meta_interp(f, [15])
+ # one guard_false got removed
+ self.check_resops(guard_false=4, guard_true=5)
+
class TestLLtype(LoopTest, LLJitMixin):
pass
More information about the pypy-commit
mailing list