Author: Richard Plangger <planri...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit