[pypy-commit] pypy regalloc-playground: first stab at coalescing support

cfbolz pypy.commits at gmail.com
Wed Aug 23 02:42:21 EDT 2017


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: regalloc-playground
Changeset: r92216:5c8cbd8502e7
Date: 2017-08-23 07:41 +0200
http://bitbucket.org/pypy/pypy/changeset/5c8cbd8502e7/

Log:	first stab at coalescing support

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
@@ -838,6 +838,11 @@
         # specific register
         self.fixed_positions = None
 
+        # another Lifetime that lives after the current one that would like to
+        # share a register with this variable
+        self.share_with = None
+
+
     def is_last_real_use_before(self, position):
         if self.real_usages is None:
             return True
@@ -873,11 +878,12 @@
 
     def find_fixed_register(self, opindex):
         # XXX could use binary search
-        if self.fixed_positions is None:
-            return None
-        for (index, reg) in self.fixed_positions:
-            if opindex <= index:
-                return reg
+        if self.fixed_positions is not None:
+            for (index, reg) in self.fixed_positions:
+                if opindex <= index:
+                    return reg
+        if self.share_with is not None:
+            return self.share_with.find_fixed_register(opindex)
 
     def _check_invariants(self):
         assert self.definition_pos <= self.last_usage
@@ -936,6 +942,17 @@
             self.fixed_register_use[register] = FixedRegisterPositions(register)
         self.fixed_register_use[register].fixed_register(opindex, definition_pos)
 
+    def try_use_same_register(self, v0, v1):
+        """ Try to arrange things to put v0 and v1 into the same register.
+        v0 must be defined before v1"""
+        # only works in limited situations now
+        longevityvar0 = self[v0]
+        longevityvar1 = self[v1]
+        assert longevityvar0.definition_pos < longevityvar1.definition_pos
+        if longevityvar0.last_usage != longevityvar1.definition_pos:
+            return # not supported for now
+        longevityvar0.share_with = longevityvar1
+
     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
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
@@ -297,6 +297,18 @@
     loc = longevity.try_pick_free_reg(0, b4, [r1, r2, r3])
     assert loc is r3
 
+def test_simple_coalescing():
+    b0, b1, b2, b3, b4 = newboxes(0, 0, 0, 0, 0)
+    l0 = Lifetime(0, 4)
+    l1 = Lifetime(4, 20)
+    l2 = Lifetime(4, 20)
+    longevity = LifetimeManager({b0: l0, b1: l1, b2: l2})
+    longevity.fixed_register(10, r1, b1)
+    longevity.fixed_register(10, r2, b2)
+    longevity.try_use_same_register(b0, b2)
+
+    loc = longevity.try_pick_free_reg(0, b0, [r0, r1, r2, r3, r4])
+    assert loc is r2
 
 class TestRegalloc(object):
     def test_freeing_vars(self):


More information about the pypy-commit mailing list