Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: regalloc-playground
Changeset: r92244:2e31b6e3f902
Date: 2017-08-24 10:19 +0200
http://bitbucket.org/pypy/pypy/changeset/2e31b6e3f902/

Log:    improve allocation choice for coalesced variables

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
@@ -482,7 +482,7 @@
                                     need_lower_byte=need_lower_byte)
         if loc:
             return loc
-        loc = self._spill_var(v, forbidden_vars, selected_reg,
+        loc = self._spill_var(forbidden_vars, selected_reg,
                               need_lower_byte=need_lower_byte)
         prev_loc = self.reg_bindings.get(v, None)
         if prev_loc is not None:
@@ -707,7 +707,7 @@
                              if reg not in self.save_around_call_regs]
             # chose which to spill using the usual spill heuristics
             while len(move_or_spill) > len(free_regs):
-                v = self._pick_variable_to_spill(None, [], vars=move_or_spill)
+                v = self._pick_variable_to_spill([], vars=move_or_spill)
                 self._bc_spill(v, new_free_regs)
                 move_or_spill.remove(v)
             assert len(move_or_spill) <= len(free_regs)
@@ -807,6 +807,11 @@
             assert op.numargs() == 1
             return [self.loc(op.getarg(0))]
 
+
+# ____________________________________________________________
+
+
+
 UNDEF_POS = -42
 
 class Lifetime(object):
@@ -834,6 +839,11 @@
         # the other lifetime will have this variable set to self.definition_pos
         self._definition_pos_shared = UNDEF_POS
 
+    def last_usage_including_sharing(self):
+        while self.share_with is not None:
+            self = self.share_with
+        return self.last_usage
+
     def is_last_real_use_before(self, position):
         if self.real_usages is None:
             return True
@@ -918,6 +928,9 @@
                     return index
         return sys.maxint
 
+    def __repr__(self):
+        return "%s: fixed at %s" % (self.register, self.index_lifetimes)
+
 
 class LifetimeManager(object):
     def __init__(self, longevity):
@@ -986,10 +999,10 @@
                 unfixed_reg = reg
                 continue
             use_after = fixed_reg_pos.free_until_pos(position)
-            if use_after < longevityvar.last_usage:
+            if use_after < longevityvar.last_usage_including_sharing():
                 # can't fit
                 continue
-            assert use_after >= longevityvar.last_usage
+            assert use_after >= longevityvar.last_usage_including_sharing()
             if use_after < min_fixed_use_after:
                 best_reg = reg
                 min_fixed_use_after = use_after
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
@@ -341,6 +341,21 @@
     # r1 is picked, because b4 fits before b0
     assert loc is r1
 
+def test_coalescing_non_fixed_regs():
+    b0, b1, b2, b3, b4 = newboxes(0, 0, 0, 0, 0)
+    l0 = Lifetime(0, 10)
+    l1 = Lifetime(10, 20)
+    l2 = Lifetime(25, 40)
+    l3 = Lifetime(15, 40)
+    longevity = LifetimeManager({b0: l0, b1: l1, b2: l2, b3: l3})
+    longevity.try_use_same_register(b0, b1)
+    longevity.fixed_register(35, r2, b2)
+    longevity.fixed_register(35, r3, b3)
+
+    loc = longevity.try_pick_free_reg(0, b0, [r1, r2, r3])
+    # r2 is picked, otherwise b1 can't end up in the same reg as b0
+    assert loc is r2
+
 
 def test_chained_coalescing():
     #              5 + b4
@@ -419,7 +434,7 @@
 
         class XRegisterManager(RegisterManager):
             no_lower_byte_regs = [r2, r3]
-        
+
         rm = XRegisterManager(longevity)
         rm.next_instruction()
         loc0 = rm.try_allocate_reg(b0, need_lower_byte=True)
@@ -454,7 +469,7 @@
 
         class XRegisterManager(RegisterManager):
             no_lower_byte_regs = [r2, r3]
-        
+
         rm = XRegisterManager(longevity,
                               frame_manager=fm,
                               assembler=MockAsm())
@@ -649,7 +664,7 @@
         rm.after_call(boxes[-1])
         assert len(rm.reg_bindings) == 1
         rm._check_invariants()
-        
+
 
     def test_different_frame_width(self):
         class XRegisterManager(RegisterManager):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to