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

Reply via email to