Author: fijal Branch: jit-leaner-frontend Changeset: r82897:ee3bb1c8b518 Date: 2016-03-09 09:58 +0200 http://bitbucket.org/pypy/pypy/changeset/ee3bb1c8b518/
Log: progress towards a non-unrolled features 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 @@ -1563,7 +1563,6 @@ def _done_with_this_frame(self): # rare case: we only get there if the blackhole interps all returned # normally (in general we get a ContinueRunningNormally exception). - sd = self.builder.metainterp_sd kind = self._return_type if kind == 'v': raise jitexc.DoneWithThisFrameVoid() 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 @@ -200,20 +200,15 @@ # ____________________________________________________________ -def compile_simple_loop(metainterp, greenkey, start, trace, jumpargs, - enable_opts): - xxxx +def compile_simple_loop(metainterp, greenkey, trace, enable_opts): from rpython.jit.metainterp.optimizeopt import optimize_trace jitdriver_sd = metainterp.jitdriver_sd metainterp_sd = metainterp.staticdata jitcell_token = make_jitcell_token(jitdriver_sd) - label = ResOperation(rop.LABEL, inputargs[:], descr=jitcell_token) - jump_op = ResOperation(rop.JUMP, jumpargs[:], descr=jitcell_token) call_pure_results = metainterp.call_pure_results - data = SimpleCompileData(label, ops + [jump_op], - call_pure_results=call_pure_results, - enable_opts=enable_opts) + data = SimpleCompileData(trace, call_pure_results=call_pure_results, + enable_opts=enable_opts) try: loop_info, ops = optimize_trace(metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo) @@ -234,7 +229,7 @@ loop.check_consistency() jitcell_token.target_tokens = [target_token] send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop", - inputargs, metainterp.box_names_memo) + loop_info.inputargs, metainterp.box_names_memo) record_loop_or_bridge(metainterp_sd, loop) return target_token @@ -262,9 +257,8 @@ jitcell_token = make_jitcell_token(jitdriver_sd) history.record(rop.JUMP, jumpargs, None, descr=jitcell_token) if 'unroll' not in enable_opts or not metainterp.cpu.supports_guard_gc_type: - return compile_simple_loop(metainterp, greenkey, start, inputargs, - history.trace, - jumpargs, enable_opts) + return compile_simple_loop(metainterp, greenkey, history.trace, + enable_opts) call_pure_results = metainterp.call_pure_results preamble_data = LoopCompileData(history.trace, inputargs, call_pure_results=call_pure_results, @@ -332,22 +326,22 @@ to the first operation. """ from rpython.jit.metainterp.optimizeopt import optimize_trace - from rpython.jit.metainterp.optimizeopt.optimizer import BasicLoopInfo - history = metainterp.history + trace = metainterp.history.trace.cut_trace_from(start, inputargs) metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd + history = metainterp.history loop_jitcell_token = metainterp.get_procedure_token(greenkey) assert loop_jitcell_token end_label = ResOperation(rop.LABEL, inputargs[:], descr=loop_jitcell_token) - jump_op = ResOperation(rop.JUMP, jumpargs[:], descr=loop_jitcell_token) + cut_pos = history.get_trace_position() + history.record(rop.JUMP, jumpargs[:], None, descr=loop_jitcell_token) enable_opts = jitdriver_sd.warmstate.enable_opts - ops = history.operations[start:] call_pure_results = metainterp.call_pure_results - loop_data = UnrolledLoopData(end_label, jump_op, ops, start_state, + loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state, call_pure_results=call_pure_results, enable_opts=enable_opts) try: @@ -356,6 +350,7 @@ metainterp.box_names_memo) except InvalidLoop: # Fall back on jumping directly to preamble + xxxx jump_op = ResOperation(rop.JUMP, inputargs[:], descr=loop_jitcell_token) loop_data = UnrolledLoopData(end_label, jump_op, [jump_op], start_state, call_pure_results=call_pure_results, diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py --- a/rpython/jit/metainterp/history.py +++ b/rpython/jit/metainterp/history.py @@ -657,8 +657,8 @@ def length(self): return self.trace._count - def get_cut_position(self): - return len(self.trace._ops) + def get_trace_position(self): + return self.trace.cut_point() def cut(self, cut_at): self.trace.cut_at(cut_at) @@ -686,11 +686,13 @@ op.setref_base(value) return op + def record_nospec(self, opnum, argboxes, descr=None): + return self.trace.record_op(opnum, argboxes, descr) + def record_default_val(self, opnum, argboxes, descr=None): - op = ResOperation(opnum, argboxes, descr) - assert op.is_same_as() + assert rop.is_same_as(opnum) + op = self.trace.record_op(opnum, argboxes, descr) op.copy_value_from(argboxes[0]) - self.operations.append(op) return op diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py --- a/rpython/jit/metainterp/opencoder.py +++ b/rpython/jit/metainterp/opencoder.py @@ -57,15 +57,22 @@ return size, self._next(), self._next() class TraceIterator(object): - def __init__(self, trace, end): + def __init__(self, trace, start, end, force_inputargs=None): self.trace = trace - self.inputargs = [rop.inputarg_from_tp(arg.type) for - arg in self.trace.inputargs] - self.start = 0 - self.pos = 0 + self._cache = [None] * trace._count + if force_inputargs is not None: + self.inputargs = [rop.inputarg_from_tp(arg.type) for + arg in force_inputargs] + for i, arg in enumerate(force_inputargs): + if arg.position >= 0: + self._cache[arg.position] = self.inputargs[i] + else: + self.inputargs = [rop.inputarg_from_tp(arg.type) for + arg in self.trace.inputargs] + self.start = start + self.pos = start self._count = 0 self.end = end - self._cache = [None] * trace._count def _get(self, i): if i < 0: @@ -126,7 +133,23 @@ self._count += 1 return res -class Trace(object): +class BaseTrace(object): + pass + +class CutTrace(BaseTrace): + def __init__(self, trace, start, count, inputargs): + self.trace = trace + self.start = start + self.inputargs = inputargs + self.count = count + + def get_iter(self): + iter = TraceIterator(self.trace, self.start, len(self.trace._ops), + self.inputargs) + iter._count = self.count + return iter + +class Trace(BaseTrace): def __init__(self, inputargs): self._ops = [] self._descrs = [None] @@ -139,8 +162,15 @@ def length(self): return len(self._ops) + def cut_point(self): + return len(self._ops), self._count + def cut_at(self, end): - self._ops = self._ops[:end] + self._ops = self._ops[:end[0]] + self._count = end[1] + + def cut_trace_from(self, (start, count), inputargs): + return CutTrace(self, start, count, inputargs) def _encode(self, box): if isinstance(box, Const): @@ -237,7 +267,7 @@ assert self._ops[resumedata_pos + 2] == pc def get_iter(self): - return TraceIterator(self, len(self._ops)) + return TraceIterator(self, 0, len(self._ops)) def _get_operations(self): """ NOT_RPYTHON 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 @@ -226,8 +226,9 @@ def optimize_bridge(self, trace, runtime_boxes, call_pure_results, inline_short_preamble, box_names_memo): + trace = trace.get_iter() self._check_no_forwarding([trace.inputargs]) - info, ops = self.optimizer.propagate_all_forward(trace.get_iter(), + info, ops = self.optimizer.propagate_all_forward(trace, call_pure_results, False) jump_op = info.jump_op cell_token = jump_op.getdescr() 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 @@ -1523,10 +1523,11 @@ @specialize.arg(1) def execute_varargs(self, opnum, argboxes, descr, exc, pure): self.metainterp.clear_exception() + patch_pos = self.metainterp.history.get_trace_position() op = self.metainterp.execute_and_record_varargs(opnum, argboxes, descr=descr) if pure and not self.metainterp.last_exc_value and op: - op = self.metainterp.record_result_of_call_pure(op) + op = self.metainterp.record_result_of_call_pure(op, patch_pos) exc = exc and not isinstance(op, Const) if exc: if op is not None: @@ -1918,7 +1919,7 @@ def retrace_needed(self, trace, exported_state): self.partial_trace = trace - self.retracing_from = self.history.length() + self.retracing_from = self.potential_retrace_position self.exported_state = exported_state self.heapcache.reset() @@ -2435,7 +2436,7 @@ break else: if self.partial_trace: - if start != self.retracing_from: + if start != self.retracing_from: raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) # For now # Found! Compile it as a loop. # raises in case it works -- which is the common case @@ -2454,7 +2455,7 @@ self.staticdata.log('cancelled, tracing more...') # Otherwise, no loop found so far, so continue tracing. - start = self.history.get_cut_position() + start = self.history.get_trace_position() self.current_merge_points.append((live_arg_boxes, start)) def _unpack_boxes(self, boxes, start, stop): @@ -2606,7 +2607,8 @@ if not target_jitcell_token: return - cut_at = self.history.get_cut_position() + cut_at = self.history.get_trace_position() + self.potential_retrace_position = cut_at self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None, descr=target_jitcell_token) self.history.ends_with_jump = True @@ -2981,7 +2983,7 @@ debug_stop("jit-abort-longest-function") return max_jdsd, max_key - def record_result_of_call_pure(self, op): + def record_result_of_call_pure(self, op, patch_pos): """ Patch a CALL into a CALL_PURE. """ opnum = op.getopnum() @@ -2993,15 +2995,16 @@ else: # all-constants: remove the CALL operation now and propagate a # constant result - self.history.operations.pop() + self.history.cut(patch_pos) return resbox_as_const # not all constants (so far): turn CALL into CALL_PURE, which might # be either removed later by optimizeopt or turned back into CALL. arg_consts = [executor.constant_from_op(a) for a in op.getarglist()] self.call_pure_results[arg_consts] = resbox_as_const opnum = OpHelpers.call_pure_for_descr(op.getdescr()) - newop = op.copy_and_change(opnum, args=op.getarglist()) - self.history.operations[-1] = newop + self.history.cut(patch_pos) + newop = self.history.record_nospec(opnum, op.getarglist(), op.getdescr()) + newop.copy_value_from(op) return newop def direct_assembler_call(self, targetjitdriver_sd): 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 @@ -1470,8 +1470,9 @@ def can_malloc(self): return self.is_call() or self.is_malloc() - def is_same_as(self): - return self.opnum in (rop.SAME_AS_I, rop.SAME_AS_F, rop.SAME_AS_R) + @staticmethod + def is_same_as(opnum): + return opnum in (rop.SAME_AS_I, rop.SAME_AS_F, rop.SAME_AS_R) def is_getfield(self): return self.opnum in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F, diff --git a/rpython/jit/metainterp/test/test_opencoder.py b/rpython/jit/metainterp/test/test_opencoder.py --- a/rpython/jit/metainterp/test/test_opencoder.py +++ b/rpython/jit/metainterp/test/test_opencoder.py @@ -130,4 +130,18 @@ loop2.inputargs = inpargs loop2.operations = l BaseTest.assert_equal(loop1, loop2) - print "success" \ No newline at end of file + + def test_cut_trace_from(self): + i0, i1, i2 = InputArgInt(), InputArgInt(), InputArgInt() + t = Trace([i0, i1, i2]) + add1 = t.record_op(rop.INT_ADD, [i0, i1]) + cut_point = t.cut_point() + add2 = t.record_op(rop.INT_ADD, [add1, i1]) + t.record_op(rop.GUARD_TRUE, [add2]) + resume.capture_resumedata([FakeFrame(3, JitCode(4), [add2, add1, i1])], + None, [], t) + t.record_op(rop.INT_SUB, [add2, add1]) + t2 = t.cut_trace_from(cut_point, [add1, i1]) + (i0, i1), l, iter = self.unpack(t2) + assert len(l) == 3 + assert l[0].getarglist() == [i0, i1] \ No newline at end of file _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit