Author: Richard Plangger <[email protected]>
Branch: fix-longevity
Changeset: r82451:848d331e295a
Date: 2016-02-23 17:22 +0100
http://bitbucket.org/pypy/pypy/changeset/848d331e295a/
Log: (remi, plan_rich) refactored the register manager to use the
LiveRanges class
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
@@ -276,10 +276,10 @@
save_around_call_regs = []
frame_reg = None
- def __init__(self, longevity, frame_manager=None, assembler=None):
+ def __init__(self, live_ranges, frame_manager=None, assembler=None):
self.free_regs = self.all_regs[:]
self.free_regs.reverse()
- self.longevity = longevity
+ self.live_ranges = live_ranges
self.temp_boxes = []
if not we_are_translated():
self.reg_bindings = OrderedDict()
@@ -293,12 +293,12 @@
def is_still_alive(self, v):
# Check if 'v' is alive at the current position.
# Return False if the last usage is strictly before.
- return self.longevity[v][1] >= self.position
+ return self.live_ranges.last_use(v) >= self.position
def stays_alive(self, v):
# Check if 'v' stays alive after the current position.
# Return False if the last usage is before or at position.
- return self.longevity[v][1] > self.position
+ return self.live_ranges.last_use(v) > self.position
def next_instruction(self, incr=1):
self.position += incr
@@ -315,7 +315,7 @@
self._check_type(v)
if isinstance(v, Const):
return
- if v not in self.longevity or self.longevity[v][1] <= self.position:
+ if not self.live_ranges.exists(v) or self.live_ranges.last_use(v) <=
self.position:
if v in self.reg_bindings:
self.free_regs.append(self.reg_bindings[v])
del self.reg_bindings[v]
@@ -347,9 +347,9 @@
else:
assert len(self.reg_bindings) + len(self.free_regs) ==
len(self.all_regs)
assert len(self.temp_boxes) == 0
- if self.longevity:
+ if self.live_ranges.longevity:
for v in self.reg_bindings:
- assert self.longevity[v][1] > self.position
+ assert self.live_ranges.last_use(v) > self.position
def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
""" Try to allocate a register, if we have one free.
@@ -425,7 +425,7 @@
continue
if need_lower_byte and reg in self.no_lower_byte_regs:
continue
- max_age = self.longevity[next][1]
+ max_age = self.live_ranges.last_use(next)
if cur_max_age < max_age:
cur_max_age = max_age
candidate = next
@@ -444,7 +444,7 @@
"""
self._check_type(v)
if isinstance(v, TempVar):
- self.longevity[v] = (self.position, self.position)
+ self.live_ranges.new_live_range(v, self.position, self.position)
loc = self.try_allocate_reg(v, selected_reg,
need_lower_byte=need_lower_byte)
if loc:
@@ -554,7 +554,7 @@
loc = self.force_allocate_reg(v, forbidden_vars)
self.assembler.regalloc_mov(prev_loc, loc)
assert v in self.reg_bindings
- if self.longevity[v][1] > self.position:
+ if self.live_ranges.last_use(v) > self.position:
# we need to find a new place for variable v and
# store result in the same place
loc = self.reg_bindings[v]
@@ -583,7 +583,7 @@
1 (save all), or 2 (save default+PTRs).
"""
for v, reg in self.reg_bindings.items():
- if v not in force_store and self.longevity[v][1] <= self.position:
+ if v not in force_store and self.live_ranges.last_use(v) <=
self.position:
# variable dies
del self.reg_bindings[v]
self.free_regs.append(reg)
@@ -677,6 +677,15 @@
self.last_real_usage = last_real_usage
self.dist_to_next_call = dist_to_next_call
+ def exists(self, var):
+ return var in self.longevity
+
+ def last_use(self, var):
+ return self.longevity[var][1]
+
+ def new_live_range(self, var, start, end):
+ self.longevity[var] = (start, end)
+
def compute_var_live_ranges(inputargs, operations):
# compute a dictionary that maps variables to index in
# operations that is a "last-time-seen"
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
@@ -2,6 +2,7 @@
from rpython.jit.metainterp.history import ConstInt, INT, FLOAT
from rpython.jit.backend.llsupport.regalloc import FrameManager, LinkedList
from rpython.jit.backend.llsupport.regalloc import RegisterManager as
BaseRegMan
+from rpython.jit.backend.llsupport.regalloc import LiveRanges
from rpython.jit.metainterp.resoperation import InputArgInt, InputArgRef,\
InputArgFloat
@@ -77,7 +78,7 @@
def test_freeing_vars(self):
b0, b1, b2 = newboxes(0, 0, 0)
longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)}
- rm = RegisterManager(longevity)
+ rm = RegisterManager(LiveRanges(longevity, None, None))
rm.next_instruction()
for b in b0, b1, b2:
rm.try_allocate_reg(b)
@@ -102,7 +103,7 @@
def test_register_exhaustion(self):
boxes, longevity = boxes_and_longevity(5)
- rm = RegisterManager(longevity)
+ rm = RegisterManager(LiveRanges(longevity, None, None))
rm.next_instruction()
for b in boxes[:len(regs)]:
assert rm.try_allocate_reg(b)
@@ -116,7 +117,7 @@
class XRegisterManager(RegisterManager):
no_lower_byte_regs = [r2, r3]
- rm = XRegisterManager(longevity)
+ rm = XRegisterManager(LiveRanges(longevity, None, None))
rm.next_instruction()
loc0 = rm.try_allocate_reg(b0, need_lower_byte=True)
assert loc0 not in XRegisterManager.no_lower_byte_regs
@@ -130,7 +131,7 @@
def test_specific_register(self):
boxes, longevity = boxes_and_longevity(5)
- rm = RegisterManager(longevity)
+ rm = RegisterManager(LiveRanges(longevity, None, None))
rm.next_instruction()
loc = rm.try_allocate_reg(boxes[0], selected_reg=r1)
assert loc is r1
@@ -151,7 +152,7 @@
class XRegisterManager(RegisterManager):
no_lower_byte_regs = [r2, r3]
- rm = XRegisterManager(longevity,
+ rm = XRegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm,
assembler=MockAsm())
rm.next_instruction()
@@ -177,7 +178,7 @@
def test_make_sure_var_in_reg(self):
boxes, longevity = boxes_and_longevity(5)
fm = TFrameManager()
- rm = RegisterManager(longevity, frame_manager=fm,
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm,
assembler=MockAsm())
rm.next_instruction()
# allocate a stack position
@@ -193,7 +194,7 @@
longevity = {b0: (0, 1), b1: (1, 3)}
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
rm.next_instruction()
# first path, var is already in reg and dies
loc0 = rm.force_allocate_reg(b0)
@@ -209,7 +210,7 @@
longevity = {b0: (0, 2), b1: (1, 3)}
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
rm.next_instruction()
loc0 = rm.force_allocate_reg(b0)
rm._check_invariants()
@@ -225,7 +226,7 @@
longevity = {b0: (0, 2), b1: (0, 2), b3: (0, 2), b2: (0, 2), b4: (1,
3)}
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
rm.next_instruction()
for b in b0, b1, b2, b3:
rm.force_allocate_reg(b)
@@ -241,7 +242,7 @@
longevity = {b0: (0, 1), b1: (0, 1)}
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
rm.next_instruction()
fm.loc(b0)
rm.force_result_in_reg(b1, b0)
@@ -257,7 +258,7 @@
longevity = {b0: (0, 1), b1: (0, 1)}
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
rm.free_regs = rm.free_regs[:1]
rm.all_regs = rm.free_regs[:]
rm.next_instruction()
@@ -275,7 +276,7 @@
longevity = {b0: (0, 1)}
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
rm.next_instruction()
# invalid call to make_sure_var_in_reg(): box unknown so far
py.test.raises(KeyError, rm.make_sure_var_in_reg, b0)
@@ -284,7 +285,7 @@
asm = MockAsm()
boxes, longevity = boxes_and_longevity(5)
fm = TFrameManager()
- rm = RegisterManager(longevity, assembler=asm,
+ rm = RegisterManager(LiveRanges(longevity, None, None), assembler=asm,
frame_manager=fm)
rm.next_instruction()
loc = rm.return_constant(ConstInt(1), selected_reg=r1)
@@ -303,7 +304,7 @@
boxes, longevity = boxes_and_longevity(2)
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm,
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm,
assembler=asm)
rm.next_instruction()
c = ConstInt(0)
@@ -325,7 +326,7 @@
fm = TFrameManager()
asm = MockAsm()
boxes, longevity = boxes_and_longevity(5)
- rm = XRegisterManager(longevity, frame_manager=fm,
+ rm = XRegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm,
assembler=asm)
for b in boxes[:-1]:
rm.force_allocate_reg(b)
@@ -348,7 +349,7 @@
fm = TFrameManager()
asm = MockAsm()
boxes, longevity = boxes_and_longevity(5)
- rm = XRegisterManager(longevity, frame_manager=fm,
+ rm = XRegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm,
assembler=asm)
for b in boxes[:-1]:
rm.force_allocate_reg(b)
@@ -370,10 +371,10 @@
b0 = InputArgInt()
longevity = {b0: (0, 1)}
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
f0 = InputArgFloat()
longevity = {f0: (0, 1)}
- xrm = XRegisterManager(longevity, frame_manager=fm, assembler=asm)
+ xrm = XRegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
xrm.loc(f0)
rm.loc(b0)
assert fm.get_frame_depth() == 3
@@ -383,7 +384,7 @@
longevity = {b0: (0, 3), b1: (0, 3), b3: (0, 5), b2: (0, 2), b4: (1,
4), b5: (1, 3)}
fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm = RegisterManager(LiveRanges(longevity, None, None),
frame_manager=fm, assembler=asm)
rm.next_instruction()
for b in b0, b1, b2, b3:
rm.force_allocate_reg(b)
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -168,10 +168,10 @@
self.live_ranges = live_ranges
self.longevity = live_ranges.longevity
self.last_real_usage = live_ranges.last_real_usage
- self.rm = gpr_reg_mgr_cls(self.longevity,
+ self.rm = gpr_reg_mgr_cls(self.live_ranges,
frame_manager = self.fm,
assembler = self.assembler)
- self.xrm = xmm_reg_mgr_cls(self.longevity, frame_manager = self.fm,
+ self.xrm = xmm_reg_mgr_cls(self.live_ranges, frame_manager = self.fm,
assembler = self.assembler)
return operations
@@ -515,7 +515,7 @@
# and won't be used after the current operation finishes,
# then swap the role of 'x' and 'y'
if (symm and isinstance(argloc, RegLoc) and
- self.rm.longevity[y][1] == self.rm.position):
+ self.rm.live_ranges.last_use(y) == self.rm.position):
x, y = y, x
argloc = self.loc(y)
#
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit