Author: Carl Friedrich Bolz <[email protected]>
Branch: regalloc-playground
Changeset: r92182:32c23f8fb859
Date: 2017-08-18 21:36 +0200
http://bitbucket.org/pypy/pypy/changeset/32c23f8fb859/

Log:    a branch to try out some register allocation ideas

        first step: refactor lifetime storage to not be tuple-based

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
@@ -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.longevity[v].last_usage >= 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.longevity[v].last_usage > 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 v not in self.longevity or self.longevity[v].last_usage <= 
self.position:
             if v in self.reg_bindings:
                 self.free_regs.append(self.reg_bindings[v])
                 del self.reg_bindings[v]
@@ -351,7 +351,7 @@
             for v in self.reg_bindings:
                 if v not in self.longevity:
                     llop.debug_print(lltype.Void, "variable %s not in 
longevity\n" % v.repr({}))
-                assert self.longevity[v][1] > self.position
+                assert self.longevity[v].last_usage > 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.
@@ -427,7 +427,7 @@
                     continue
             if need_lower_byte and reg in self.no_lower_byte_regs:
                 continue
-            max_age = self.longevity[next][1]
+            max_age = self.longevity[next].last_usage
             if cur_max_age < max_age:
                 cur_max_age = max_age
                 candidate = next
@@ -446,7 +446,7 @@
         """
         self._check_type(v)
         if isinstance(v, TempVar):
-            self.longevity[v] = (self.position, self.position)
+            self.longevity[v] = Lifetime(self.position, self.position)
         loc = self.try_allocate_reg(v, selected_reg,
                                     need_lower_byte=need_lower_byte)
         if loc:
@@ -556,7 +556,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.longevity[v].last_usage > self.position:
             # we need to find a new place for variable v and
             # store result in the same place
             loc = self.reg_bindings[v]
@@ -643,7 +643,7 @@
         move_or_spill = []
 
         for v, reg in self.reg_bindings.items():
-            max_age = self.longevity[v][1]
+            max_age = self.longevity[v].last_usage
             if v not in force_store and max_age <= self.position:
                 # variable dies
                 del self.reg_bindings[v]
@@ -765,7 +765,7 @@
         # of COND_CALL don't accept a cc as input
         if next_op.getarg(0) is not op:
             return False
-        if self.longevity[op][1] > i + 1:
+        if self.longevity[op].last_usage > i + 1:
             return False
         if opnum != rop.COND_CALL:
             if op in operations[i + 1].getfailargs():
@@ -785,6 +785,10 @@
             assert op.numargs() == 1
             return [self.loc(op.getarg(0))]
 
+class Lifetime(object):
+    def __init__(self, definition_pos, last_usage):
+        self.definition_pos = definition_pos
+        self.last_usage = last_usage
 
 def compute_vars_longevity(inputargs, operations):
     # compute a dictionary that maps variables to index in
@@ -824,14 +828,14 @@
         if arg.type != 'v' and arg in last_used:
             assert not isinstance(arg, Const)
             assert i < last_used[arg]
-            longevity[arg] = (i, last_used[arg])
+            longevity[arg] = Lifetime(i, last_used[arg])
             del last_used[arg]
     for arg in inputargs:
         assert not isinstance(arg, Const)
         if arg not in last_used:
-            longevity[arg] = (-1, -1)
+            longevity[arg] = Lifetime(-1, -1)
         else:
-            longevity[arg] = (0, last_used[arg])
+            longevity[arg] = Lifetime(0, last_used[arg])
             del last_used[arg]
     assert len(last_used) == 0
 
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
@@ -1,7 +1,7 @@
 import py
 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 RegisterManager as 
BaseRegMan, Lifetime
 from rpython.jit.metainterp.resoperation import InputArgInt, InputArgRef,\
      InputArgFloat
 
@@ -17,7 +17,7 @@
     for i in range(num):
         box = InputArgInt(0)
         res.append(box)
-        longevity[box] = (0, 1)
+        longevity[box] = Lifetime(0, 1)
     return res, longevity
 
 class FakeReg(object):
@@ -76,7 +76,7 @@
 class TestRegalloc(object):
     def test_freeing_vars(self):
         b0, b1, b2 = newboxes(0, 0, 0)
-        longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)}
+        longevity = {b0: Lifetime(0, 1), b1: Lifetime(0, 2), b2: Lifetime(0, 
2)}
         rm = RegisterManager(longevity)
         rm.next_instruction()
         for b in b0, b1, b2:
@@ -190,7 +190,7 @@
         
     def test_force_result_in_reg_1(self):
         b0, b1 = newboxes(0, 0)
-        longevity = {b0: (0, 1), b1: (1, 3)}
+        longevity = {b0: Lifetime(0, 1), b1: Lifetime(1, 3)}
         fm = TFrameManager()
         asm = MockAsm()
         rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
@@ -206,7 +206,7 @@
 
     def test_force_result_in_reg_2(self):
         b0, b1 = newboxes(0, 0)
-        longevity = {b0: (0, 2), b1: (1, 3)}
+        longevity = {b0: Lifetime(0, 2), b1: Lifetime(1, 3)}
         fm = TFrameManager()
         asm = MockAsm()
         rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
@@ -222,7 +222,9 @@
 
     def test_force_result_in_reg_3(self):
         b0, b1, b2, b3, b4 = newboxes(0, 0, 0, 0, 0)
-        longevity = {b0: (0, 2), b1: (0, 2), b3: (0, 2), b2: (0, 2), b4: (1, 
3)}
+        longevity = {b0: Lifetime(0, 2), b1: Lifetime(0, 2),
+                     b3: Lifetime(0, 2), b2: Lifetime(0, 2),
+                     b4: Lifetime(1, 3)}
         fm = TFrameManager()
         asm = MockAsm()
         rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
@@ -238,7 +240,7 @@
 
     def test_force_result_in_reg_4(self):
         b0, b1 = newboxes(0, 0)
-        longevity = {b0: (0, 1), b1: (0, 1)}
+        longevity = {b0: Lifetime(0, 1), b1: Lifetime(0, 1)}
         fm = TFrameManager()
         asm = MockAsm()
         rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
@@ -254,7 +256,7 @@
 
     def test_bogus_make_sure_var_in_reg(self):
         b0, = newboxes(0)
-        longevity = {b0: (0, 1)}
+        longevity = {b0: Lifetime(0, 1)}
         fm = TFrameManager()
         asm = MockAsm()
         rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
@@ -350,11 +352,11 @@
 
         fm = TFrameManager()
         b0 = InputArgInt()
-        longevity = {b0: (0, 1)}
+        longevity = {b0: Lifetime(0, 1)}
         asm = MockAsm()
         rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
         f0 = InputArgFloat()
-        longevity = {f0: (0, 1)}
+        longevity = {f0: Lifetime(0, 1)}
         xrm = XRegisterManager(longevity, frame_manager=fm, assembler=asm)
         xrm.loc(f0)
         rm.loc(b0)
@@ -362,7 +364,9 @@
                 
     def test_spilling(self):
         b0, b1, b2, b3, b4, b5 = newboxes(0, 1, 2, 3, 4, 5)
-        longevity = {b0: (0, 3), b1: (0, 3), b3: (0, 5), b2: (0, 2), b4: (1, 
4), b5: (1, 3)}
+        longevity = {b0: Lifetime(0, 3), b1: Lifetime(0, 3),
+                     b3: Lifetime(0, 5), b2: Lifetime(0, 2),
+                     b4: Lifetime(1, 4), b5: Lifetime(1, 3)}
         fm = TFrameManager()
         asm = MockAsm()
         rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
@@ -378,7 +382,6 @@
         assert spilled2 is loc
         rm._check_invariants()
 
-
     def test_hint_frame_locations_1(self):
         for hint_value in range(11):
             b0, = newboxes(0)
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
@@ -511,7 +511,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.longevity[y].last_usage == self.rm.position):
             x, y = y, x
             argloc = self.loc(y)
         #
diff --git a/rpython/jit/backend/zarch/regalloc.py 
b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -1,6 +1,7 @@
 from rpython.jit.backend.llsupport.regalloc import (RegisterManager, 
FrameManager,
                                                     TempVar, 
compute_vars_longevity,
-                                                    BaseRegalloc, 
NoVariableToSpill)
+                                                    BaseRegalloc, 
NoVariableToSpill,
+                                                    Lifetime)
 from rpython.jit.backend.llsupport.jump import remap_frame_layout_mixed
 from rpython.jit.backend.zarch.arch import WORD
 from rpython.jit.codewriter import longlong
@@ -255,9 +256,9 @@
         self._check_type(even_var)
         self._check_type(odd_var)
         if isinstance(even_var, TempVar):
-            self.longevity[even_var] = (self.position, self.position)
+            self.longevity[even_var] = Lifetime(self.position, self.position)
         if isinstance(odd_var, TempVar):
-            self.longevity[odd_var] = (self.position, self.position)
+            self.longevity[odd_var] = Lifetime(self.position, self.position)
 
         # this function steps through the following:
         # 1) maybe there is an even/odd pair that is always
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to