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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit