Author: Maciej Fijalkowski <fij...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit