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