[pypy-commit] pypy jit-leaner-frontend: pass the first tests of optimizeopt, yay!

fijal pypy.commits at gmail.com
Fri Mar 4 08:14:02 EST 2016


Author: fijal
Branch: jit-leaner-frontend
Changeset: r82763:b36f4652488a
Date: 2016-03-04 15:13 +0200
http://bitbucket.org/pypy/pypy/changeset/b36f4652488a/

Log:	pass the first tests of optimizeopt, yay!

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
@@ -1,10 +1,11 @@
 
-from rpython.jit.metainterp.history import ConstInt, Const, AbstractDescr,\
-    AbstractValue
+""" Storage format:
+"""
+
+from rpython.jit.metainterp.history import ConstInt, Const
 from rpython.jit.metainterp.resoperation import AbstractResOp, AbstractInputArg,\
-    ResOperation, oparity, opname, rop, ResOperation, opwithdescr
+    ResOperation, oparity, rop, opwithdescr
 from rpython.rlib.rarithmetic import intmask
-from rpython.jit.metainterp import resume
 from rpython.rlib.objectmodel import we_are_translated
 
 TAGINT, TAGCONST, TAGBOX = range(3)
@@ -20,7 +21,12 @@
         self.trace = main_iter.trace
         self.main_iter = main_iter
         self.end = end_pos
+        self.start = pos
         self.pos = pos
+        self.save_pos = -1
+
+    def length(self):
+        return self.end - self.start
 
     def done(self):
         return self.pos >= self.end
@@ -36,7 +42,16 @@
         return r
 
     def get_size_jitcode_pc(self):
-        return self._next(), self._next(), self._next()
+        if self.save_pos >= 0:
+            self.pos = self.save_pos
+        size = self._next()
+        if size < 0:
+            self.save_pos = self.pos
+            self.pos = -size - 1
+            assert self.pos >= 0
+            size = self._next()
+            assert size >= 0
+        return size, self._next(), self._next()
 
 class TraceIterator(object):
     def __init__(self, trace, end):
@@ -204,6 +219,10 @@
             assert isinstance(prev, Sentinel)
         self._ops[p] = len(self._ops)
 
+    def check_snapshot_jitcode_pc(self, jitcode, pc, resumedata_pos):
+        assert self._ops[resumedata_pos + 1] == jitcode.index
+        assert self._ops[resumedata_pos + 2] == pc
+
     def get_iter(self):
         return TraceIterator(self, len(self._ops))
 
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
@@ -27,7 +27,7 @@
 class BasicLoopInfo(LoopInfo):
     def __init__(self, inputargs, quasi_immutable_deps):
         self.inputargs = inputargs
-        self.label_op = ResOperation(rop.LABEL, inputargs)
+        self.label_op = ResOperation(rop.LABEL, inputargs, -1)
         self.quasi_immutable_deps = quasi_immutable_deps
         self.extra_same_as = []
 
@@ -509,30 +509,24 @@
         trace = trace.get_iter()
         self.trace = trace
         self.call_pure_results = call_pure_results
+        last_op = None
+        i = 0
         while not trace.done():
             self._really_emitted_operation = None
             op = trace.next()
             if op.getopnum() in (rop.FINISH, rop.JUMP):
-                xxx
-            self.first_optimization.propagate_forward(trace.next())
-        xxxx
-        if ops[-1].getopnum() in (rop.FINISH, rop.JUMP):
-            last = len(ops) - 1
-            extra_jump = True
-        else:
-            extra_jump = False
-            last = len(ops)
-        for i in range(last):
-            self._really_emitted_operation = None
-            self.first_optimization.propagate_forward(ops[i])
+                last_op = op
+                break
+            self.first_optimization.propagate_forward(op)
+            i += 1
         # accumulate counters
         if flush:
             self.flush()
-        if extra_jump:
-            self.first_optimization.propagate_forward(ops[-1])
+        if last_op:
+            self.first_optimization.propagate_forward(last_op)
         self.resumedata_memo.update_counters(self.metainterp_sd.profiler)
         
-        return (BasicLoopInfo(newargs, self.quasi_immutable_deps),
+        return (BasicLoopInfo(trace.inputargs, self.quasi_immutable_deps),
                 self._newoperations)
 
     def _clean_optimization_info(self, lst):
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -49,7 +49,6 @@
         return None
 
     def lookup(self, optimizer, op):
-        return None
         numargs = op.numargs()
         if numargs == 1:
             return self.lookup1(optimizer,
@@ -76,8 +75,8 @@
         dispatch_opt(self, op)
 
     def optimize_default(self, op):
-        canfold = OpHelpers.is_always_pure(op.opnum)
-        if OpHelpers.is_ovf(op.opnum):
+        canfold = op.is_always_pure()
+        if op.is_ovf():
             self.postponed_op = op
             return
         if self.postponed_op:
@@ -91,7 +90,7 @@
         save = False
         if canfold:
             for i in range(op.numargs()):
-                if not self.optimizer.is_constant(op.getarg(i)):
+                if self.get_constant_box(op.getarg(i)) is None:
                     break
             else:
                 # all constant arguments: constant-fold away
@@ -207,7 +206,7 @@
     def pure_from_args(self, opnum, args, op, descr=None):
         newop = ResOperation(opnum,
                              [self.get_box_replacement(arg) for arg in args],
-                             descr=descr)
+                             -1, descr=descr)
         newop.set_forwarded(op)
         self.pure(opnum, newop)
 
@@ -222,7 +221,7 @@
     def produce_potential_short_preamble_ops(self, sb):
         ops = self.optimizer._newoperations
         for i, op in enumerate(ops):
-            if OpHelpers.is_always_pure(op.opnum):
+            if op.is_always_pure():
                 sb.add_pure_op(op)
             if op.is_ovf() and ops[i + 1].getopnum() == rop.GUARD_NO_OVERFLOW:
                 sb.add_pure_op(op)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -35,7 +35,7 @@
         compile_data = compile.SimpleCompileData(label_op, trace,
                                                  call_pure_results)
         info, ops = self._do_optimize_loop(compile_data)
-        label_op = ResOperation(rop.LABEL, info.inputargs)
+        label_op = ResOperation(rop.LABEL, info.inputargs, -1)
         loop.inputargs = info.inputargs
         loop.operations = [label_op] + ops
         #print '\n'.join([str(o) for o in loop.operations])
diff --git a/rpython/jit/metainterp/optimizeopt/util.py b/rpython/jit/metainterp/optimizeopt/util.py
--- a/rpython/jit/metainterp/optimizeopt/util.py
+++ b/rpython/jit/metainterp/optimizeopt/util.py
@@ -154,7 +154,7 @@
             if op1.type != 'v':
                 remap[op2] = op1
         if (op1.getopnum() not in [rop.JUMP, rop.LABEL, rop.FINISH] and
-            not OpHelpers.is_guard(op1.getopnum())):
+            not rop.is_guard(op1.getopnum())):
             assert op1.getdescr() == op2.getdescr()
         if op1.getfailargs() or op2.getfailargs():
             assert len(op1.getfailargs()) == len(op2.getfailargs())
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
@@ -396,7 +396,16 @@
         except KeyError:
             return '<%d>' % self.getopnum()
 
-    # XXX kill all those in favor of ophelpers
+    def is_guard(self):
+        return rop.is_guard(self.getopnum())
+
+    def is_ovf(self):
+        return rop.is_ovf(self.getopnum())
+
+    def can_raise(self):
+        return rop.can_raise(self.getopnum())
+
+    # XXX fix
 
     def is_foldable_guard(self):
         return rop._GUARD_FOLDABLE_FIRST <= self.getopnum() <= rop._GUARD_FOLDABLE_LAST
@@ -1430,6 +1439,14 @@
         xxxx
 
     @staticmethod
+    def is_pure_getfield(opnum, descr):
+        if (opnum == rop.GETFIELD_GC_I or
+            opnum == rop.GETFIELD_GC_F or
+            opnum == rop.GETFIELD_GC_R):
+            return descr is not None and descr.is_always_pure()
+        return False
+
+    @staticmethod
     def has_no_side_effect(opnum):
         return rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST
 
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -115,6 +115,7 @@
 def _ensure_parent_resumedata(framestack, n, t):
     if n == 0:
         return
+    _ensure_parent_resumedata(framestack, n - 1, t)
     target = framestack[n]
     back = framestack[n - 1]
     if target.parent_resumedata_position != -1:
@@ -124,7 +125,6 @@
         return
     pos = t.record_snapshot(back.jitcode, back.pc,
                             back.get_list_of_active_boxes(True))
-    _ensure_parent_resumedata(framestack, n - 1, t)
     target.parent_resumedata_position = pos
 
 def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes, t):
@@ -138,9 +138,9 @@
     if n >= 0:
         top = framestack[n]
         pos = t.get_patchable_position()
+        _ensure_parent_resumedata(framestack, n, t)
         t.record_snapshot(top.jitcode, top.pc,
                           top.get_list_of_active_boxes(False))
-        _ensure_parent_resumedata(framestack, n, t)
         t.patch_position_to_current(pos)
     else:
         yyy
@@ -196,22 +196,13 @@
 TAG_CONST_OFFSET = 0
 
 class NumberingState(object):
-    def __init__(self, snapshot_list):
+    def __init__(self, size):
         self.liveboxes = {}
-        self.current = [rffi.cast(rffi.SHORT, 0)] * self.count_boxes(snapshot_list)
-        self.position = len(self.current)
+        self.current = [rffi.cast(rffi.SHORT, 0)] * (size + 2)
+        self.position = 0
         self.n = 0
         self.v = 0
 
-    def count_boxes(self, lst):
-        snapshot = lst[0]
-        assert isinstance(snapshot, TopSnapshot)
-        c = len(snapshot.vable_boxes)
-        for snapshot in lst:
-            c += len(snapshot.boxes)
-        c += 2 * (len(lst) - 1) + 1 + 1
-        return c
-
     def append(self, item):
         self.current[self.position] = item
         self.position += 1
@@ -267,15 +258,14 @@
 
     # env numbering
 
-    def _number_boxes(self, boxes, optimizer, state):
+    def _number_boxes(self, iter, length, optimizer, state):
         """ Number boxes from one snapshot
         """
         n = state.n
         v = state.v
         liveboxes = state.liveboxes
-        length = len(boxes)
         for i in range(length):
-            box = boxes[i]
+            box = iter.next()
             box = optimizer.get_box_replacement(box)
 
             if isinstance(box, Const):
@@ -302,32 +292,33 @@
         state.v = v
 
     def number(self, optimizer, position, trace):
-        state = NumberingState(snapshot_list)
+        snapshot_iter = trace.get_snapshot_iter(position)
+        state = NumberingState(snapshot_iter.length())
+        while not snapshot_iter.done():
+            size, jitcode_index, pc = snapshot_iter.get_size_jitcode_pc()
+            state.append(rffi.cast(rffi.SHORT, jitcode_index))
+            state.append(rffi.cast(rffi.SHORT, pc))
+            self._number_boxes(snapshot_iter, size, optimizer, state)
 
-        # we want to number snapshots starting from the back, but ending
-        # with a forward list
-        for i in range(len(snapshot_list) - 1, 0, -1):
-            state.position -= len(snapshot_list[i].boxes) + 2
-            frameinfo = framestack_list[i - 1]
-            jitcode_pos, pc = unpack_uint(frameinfo.packed_jitcode_pc)
-            state.append(rffi.cast(rffi.SHORT, jitcode_pos))
-            state.append(rffi.cast(rffi.SHORT, pc))
-            self._number_boxes(snapshot_list[i].boxes, optimizer, state)
-            state.position -= len(snapshot_list[i].boxes) + 2
-
-        assert isinstance(topsnapshot, TopSnapshot)
-        special_boxes_size = (1 + len(topsnapshot.vable_boxes) +
-                              1 + len(topsnapshot.boxes))
-        assert state.position == special_boxes_size
-
-        state.position = 0
-        state.append(rffi.cast(rffi.SHORT, len(topsnapshot.vable_boxes)))
-        self._number_boxes(topsnapshot.vable_boxes, optimizer, state)
-        n = len(topsnapshot.boxes)
+        state.append(rffi.cast(rffi.SHORT, 0))
+        n = 0 # len(topsnapshot.boxes)
         assert not (n & 1)
         state.append(rffi.cast(rffi.SHORT, n >> 1))
-        self._number_boxes(topsnapshot.boxes, optimizer, state)
-        assert state.position == special_boxes_size
+        #
+        # XXX ignore vables and virtualrefs for now
+        #assert isinstance(topsnapshot, TopSnapshot)
+        #special_boxes_size = (1 + len(topsnapshot.vable_boxes) +
+        #                      1 + len(topsnapshot.boxes))
+        #assert state.position == special_boxes_size
+
+        #state.position = 0
+        #state.append(rffi.cast(rffi.SHORT, len(topsnapshot.vable_boxes)))
+        #self._number_boxes(topsnapshot.vable_boxes, optimizer, state)
+        #n = len(topsnapshot.boxes)
+        #assert not (n & 1)
+        #state.append(rffi.cast(rffi.SHORT, n >> 1))
+        #self._number_boxes(topsnapshot.boxes, optimizer, state)
+        #assert state.position == special_boxes_size
 
         numb = resumecode.create_numbering(state.current)
         return numb, state.liveboxes, state.v
@@ -476,11 +467,10 @@
         assert resume_position > 0
         # count stack depth
         numb, liveboxes_from_env, v = self.memo.number(optimizer,
-            resume_position, self.optimize.trace)
+            resume_position, self.optimizer.trace)
         self.liveboxes_from_env = liveboxes_from_env
         self.liveboxes = {}
         storage.rd_numb = numb
-        self.snapshot_storage.rd_snapshot = None
         
         # collect liveboxes and virtuals
         n = len(liveboxes_from_env) - v
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
@@ -77,7 +77,7 @@
         assert boxes == [i0, i1]
         assert l[2].opnum == rop.GUARD_FALSE
         boxes = self.unpack_snapshot(iter, l[2].rd_resume_position)
-        assert boxes == [i0, i0, l[0], i0, i1]
+        assert boxes == [i0, i1, i0, i0, l[0]]
 
     def test_read_snapshot_interface(self):
         i0, i1, i2 = InputArgInt(), InputArgInt(), InputArgInt()
@@ -86,16 +86,26 @@
         frame0 = FakeFrame(1, JitCode(2), [i0, i1])
         frame1 = FakeFrame(3, JitCode(4), [i2, i2])
         resume.capture_resumedata([frame0, frame1], None, [], t)
+        t.record_op(rop.GUARD_TRUE, [i1])
+        resume.capture_resumedata([frame0, frame1], None, [], t)
         (i0, i1, i2), l, iter = self.unpack(t)
         pos = l[0].rd_resume_position
         snapshot_iter = iter.get_snapshot_iter(pos)
         size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
         assert size == 2
+        assert jc_index == 2
+        assert pc == 1
+        assert [snapshot_iter.next() for i in range(2)] == [i0, i1]
+        size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
+        assert size == 2
         assert jc_index == 4
         assert pc == 3
         assert [snapshot_iter.next() for i in range(2)] == [i2, i2]
+        pos = l[1].rd_resume_position
+        snapshot_iter = iter.get_snapshot_iter(pos)
         size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
         assert size == 2
         assert jc_index == 2
         assert pc == 1
         assert [snapshot_iter.next() for i in range(2)] == [i0, i1]
+        
\ No newline at end of file


More information about the pypy-commit mailing list