[pypy-commit] pypy jit-leaner-frontend: implement deadranges

fijal pypy.commits at gmail.com
Mon Mar 21 08:40:30 EDT 2016


Author: fijal
Branch: jit-leaner-frontend
Changeset: r83214:71d4428daa8d
Date: 2016-03-21 14:39 +0200
http://bitbucket.org/pypy/pypy/changeset/71d4428daa8d/

Log:	implement deadranges

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
@@ -88,8 +88,16 @@
         self.start = start
         self.pos = start
         self._count = start
+        self.start_index = start
         self.end = end
 
+    def get_dead_ranges(self):
+        return self.trace.get_dead_ranges(self.metainterp_sd)
+
+    def kill_cache_at(self, pos):
+        if pos:
+            self._cache[pos] = None
+
     def _get(self, i):
         res = self._cache[i]
         assert res is not None
@@ -183,6 +191,7 @@
         iter = TraceIterator(self.trace, self.start, self.trace._pos,
                              self.inputargs, metainterp_sd=metainterp_sd)
         iter._count = self.count
+        iter.start_index = self.count
         return iter
 
 def combine_uint(index1, index2):
@@ -210,6 +219,8 @@
         self.vref_array = vref_array
 
 class Trace(BaseTrace):
+    _deadranges = (-1, -1)
+
     def __init__(self, inputargs):
         self._ops = [rffi.cast(rffi.SHORT, -15)] * 30000
         self._pos = 0
@@ -403,12 +414,37 @@
             index = t.next_element_update_live_range(index, liveranges)
         return liveranges
 
-    def unpack(self):
-        iter = self.get_iter()
+    def get_dead_ranges(self, metainterp_sd):
+        """ Same as get_live_ranges, but returns a list of "dying" indexes,
+        such as for each index x, the number found there is for sure dead
+        before x
+        """
+        def insert(ranges, pos, v):
+            # XXX skiplist
+            while ranges[pos]:
+                pos += 1
+                if pos == len(ranges):
+                    return
+            ranges[pos] = v
+
+        if self._deadranges != (-1, -1):
+            if self._deadranges[0] == self._count:
+                return self._deadranges[1]
+        liveranges = self.get_live_ranges(metainterp_sd)
+        deadranges = [0] * (self._count + 1)
+        for i in range(self._start, len(liveranges)):
+            elem = liveranges[i]
+            if elem:
+                insert(deadranges, elem + 1, i)
+        self._deadranges = (self._count, deadranges)
+        return deadranges
+
+    def unpack(self, metainterp_sd):
+        iter = self.get_iter(metainterp_sd)
         ops = []
         while not iter.done():
             ops.append(iter.next())
-        return ops
+        return iter.inputargs, ops
 
 def tag(kind, pos):
     #if not SMALL_INT_START <= pos < SMALL_INT_STOP:
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
@@ -507,6 +507,7 @@
 
     def propagate_all_forward(self, trace, call_pure_results=None, flush=True):
         self.trace = trace
+        deadranges = trace.get_dead_ranges()
         self.call_pure_results = call_pure_results
         last_op = None
         i = 0
@@ -517,6 +518,7 @@
                 last_op = op
                 break
             self.first_optimization.propagate_forward(op)
+            trace.kill_cache_at(deadranges[i + trace.start_index])
             i += 1
         # accumulate counters
         if flush:
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -557,9 +557,21 @@
             call_pure_results[list(k)] = v
         return call_pure_results
 
+    def pick_cls(self, inp):
+        if inp.type == 'i':
+            return history.IntFrontendOp
+        elif inp.type == 'r':
+            xxx
+        else:
+            assert inp.type == 'f'
+            xxx
+
     def convert_loop_to_packed(self, loop, skip_last=False):
+        XXX # rewrite
         from rpython.jit.metainterp.opencoder import Trace
-        trace = Trace(loop.inputargs)
+        inputargs = [self.pick_cls(inparg)(i) for i, inparg in
+                     enumerate(loop.inputargs)]
+        trace = Trace(inputargs)
         ops = loop.operations
         if skip_last:
             ops = ops[:-1]
@@ -635,7 +647,7 @@
 def convert_old_style_to_targets(loop, jump):
     newloop = TreeLoop(loop.name)
     newloop.inputargs = loop.inputargs
-    newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, -1, descr=FakeDescr())] + \
+    newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, descr=FakeDescr())] + \
                       loop.operations
     if not jump:
         assert newloop.operations[-1].getopnum() == rop.JUMP
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
@@ -195,3 +195,19 @@
         t.record_op(rop.GUARD_TRUE, [i0])
         resume.capture_resumedata([], [i1, i2, p0], [p0, i1], t)
         assert t.get_live_ranges(metainterp_sd) == [4, 4, 4, 4, 0]
+
+    def test_deadranges(self):
+        i0, i1, i2 = IntFrontendOp(0), IntFrontendOp(0), IntFrontendOp(0)
+        t = Trace([i0, i1, i2])
+        p0 = FakeOp(t.record_op(rop.NEW_WITH_VTABLE, [], descr=SomeDescr()))
+        t.record_op(rop.GUARD_TRUE, [i0])
+        resume.capture_resumedata([], [i1, i2, p0], [p0, i1], t)
+        i3 = FakeOp(t.record_op(rop.INT_ADD, [i1, ConstInt(1)]))
+        i4 = FakeOp(t.record_op(rop.INT_ADD, [i3, ConstInt(1)]))
+        t.record_op(rop.ESCAPE_N, [ConstInt(3)])
+        t.record_op(rop.ESCAPE_N, [ConstInt(3)])
+        t.record_op(rop.ESCAPE_N, [ConstInt(3)])
+        t.record_op(rop.ESCAPE_N, [ConstInt(3)])
+        t.record_op(rop.ESCAPE_N, [ConstInt(3)])
+        t.record_op(rop.FINISH, [i4])
+        assert t.get_dead_ranges(metainterp_sd) == [0, 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 6]


More information about the pypy-commit mailing list