Author: Carl Friedrich Bolz <[email protected]>
Branch: regalloc-playground
Changeset: r92208:ffb5755ee817
Date: 2017-08-22 15:41 +0200
http://bitbucket.org/pypy/pypy/changeset/ffb5755ee817/

Log:    a special case for repeated uses of the same fixed register (with
        different vars). a test for longest_free_reg

diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -852,12 +852,18 @@
         return l[low]
 
     def fixed_register(self, position, reg):
+        """ registers a fixed register use for the variable at position in
+        register reg. returns the position from where on the register should be
+        held free. """
         assert self.definition_pos <= position <= self.last_usage
         if self.fixed_positions is None:
             self.fixed_positions = []
+            res = self.definition_pos
         else:
             assert position > self.fixed_positions[-1][0]
+            res = self.fixed_positions[-1][0]
         self.fixed_positions.append((position, reg))
+        return res
 
     def _check_invariants(self):
         assert self.definition_pos <= self.last_usage
@@ -876,16 +882,17 @@
 
         self.index_lifetimes = []
 
-    def fixed_register(self, opindex, varlifetime):
+    def fixed_register(self, opindex, definition_pos):
         if self.index_lifetimes:
             assert opindex > self.index_lifetimes[-1][0]
-        self.index_lifetimes.append((opindex, varlifetime))
+        self.index_lifetimes.append((opindex, definition_pos))
 
     def free_until_pos(self, opindex):
-        for (index, varlifetime) in self.index_lifetimes:
+        # XXX could use binary search
+        for (index, definition_pos) in self.index_lifetimes:
             if opindex <= index:
-                if varlifetime is not None and varlifetime.definition_pos >= 
opindex:
-                    return varlifetime.definition_pos
+                if definition_pos >= opindex:
+                    return definition_pos
                 else:
                     # the variable doesn't exist or didn't make it into the
                     # register despite being defined already. so we don't care
@@ -894,6 +901,7 @@
                     return index
         return sys.maxint
 
+
 class LifetimeManager(object):
     def __init__(self, longevity):
         self.longevity = longevity
@@ -906,19 +914,19 @@
         operation opindex. var can be None, if no variable at all can be in
         that register at the point."""
         if var is None:
-            varlifetime = None
+            definition_pos = opindex
         else:
             varlifetime = self.longevity[var]
-            varlifetime.fixed_register(opindex, register)
+            definition_pos = varlifetime.fixed_register(opindex, register)
         if register not in self.fixed_register_use:
             self.fixed_register_use[register] = 
FixedRegisterPositions(register)
-        self.fixed_register_use[register].fixed_register(opindex, varlifetime)
+        self.fixed_register_use[register].fixed_register(opindex, 
definition_pos)
 
     def longest_free_reg(self, position, free_regs):
-        """ for every register in free_regs, compute how far into the
-        future that register can remain free, according to the constraints of
-        the fixed registers. Find the register that is free the longest. 
Return a tuple
-        (reg, free_until_pos). """
+        """ for every register in free_regs, compute how far into the future
+        that register can remain free, according to the constraints of the
+        fixed registers. Find the register that is free the longest. Return a
+        tuple (reg, free_until_pos). """
         free_until_pos = {}
         max_free_pos = -1
         best_reg = None
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py 
b/rpython/jit/backend/llsupport/test/test_regalloc.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc.py
@@ -144,9 +144,9 @@
     fpr1 = longevity.fixed_register_use[r1]
     fpr2 = longevity.fixed_register_use[r2]
     assert r3 not in longevity.fixed_register_use
-    assert fpr0.index_lifetimes == [(1, l0)]
-    assert fpr1.index_lifetimes == [(5, l1), (8, l1)]
-    assert fpr2.index_lifetimes == [(4, l0)]
+    assert fpr0.index_lifetimes == [(1, 0)]
+    assert fpr1.index_lifetimes == [(5, 2), (8, 5)]
+    assert fpr2.index_lifetimes == [(4, 1)]
 
 def test_fixed_position_none():
     b0, b1, b2 = newboxes(0, 0, 0)
@@ -163,9 +163,9 @@
     fpr1 = longevity.fixed_register_use[r1]
     fpr2 = longevity.fixed_register_use[r2]
     assert r3 not in longevity.fixed_register_use
-    assert fpr0.index_lifetimes == [(1, None)]
-    assert fpr1.index_lifetimes == [(5, None), (8, None)]
-    assert fpr2.index_lifetimes == [(4, None)]
+    assert fpr0.index_lifetimes == [(1, 1)]
+    assert fpr1.index_lifetimes == [(5, 5), (8, 8)]
+    assert fpr2.index_lifetimes == [(4, 4)]
 
 
 def test_free_until_pos_none():
@@ -228,6 +228,33 @@
     assert fpr1.free_until_pos(34) == 35
     assert fpr1.free_until_pos(35) == 35
 
+def test_free_until_pos_different_regs():
+    b0, b1, b2 = newboxes(0, 0, 0)
+    l0 = Lifetime(0, 5)
+    l1 = Lifetime(2, 9)
+    l2 = Lifetime(30, 40)
+    longevity = LifetimeManager({b0: l0, b1: l1, b2: l2})
+    longevity.fixed_register(1, r0, b0)
+    longevity.fixed_register(4, r2, b0)
+    fpr2 = longevity.fixed_register_use[r2]
+    # the definition of b0 is before the other fixed register use of r0, so the
+    # earliest b0 can be in r2 is that use point at index 1
+    assert fpr2.free_until_pos(0) == 1
+
+
+def test_longest_free_reg():
+    b0, b1, b2 = newboxes(0, 0, 0)
+    l0 = Lifetime(0, 5)
+    l1 = Lifetime(2, 9)
+    l2 = Lifetime(30, 40)
+    longevity = LifetimeManager({b0: l0, b1: l1, b2: l2})
+    longevity.fixed_register(1, r0, b0)
+    longevity.fixed_register(4, r2, b0)
+    longevity.fixed_register(5, r1, b1)
+    longevity.fixed_register(8, r1, b1)
+    longevity.fixed_register(35, r1, b2)
+
+    assert longevity.longest_free_reg(0, [r0, r1, r2]) == (r2, 2)
 
 class TestRegalloc(object):
     def test_freeing_vars(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to