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