[pypy-svn] r67913 - in pypy/branch/refactor-x86/pypy/jit/backend/llsupport: . test

fijal at codespeak.net fijal at codespeak.net
Sun Sep 27 10:24:52 CEST 2009


Author: fijal
Date: Sun Sep 27 10:24:52 2009
New Revision: 67913

Added:
   pypy/branch/refactor-x86/pypy/jit/backend/llsupport/regalloc.py   (contents, props changed)
   pypy/branch/refactor-x86/pypy/jit/backend/llsupport/test/test_regalloc.py   (contents, props changed)
Log:
Start moving register allocation in a more abstract manner to llsupport
(it's mostly the same interface + tests)


Added: pypy/branch/refactor-x86/pypy/jit/backend/llsupport/regalloc.py
==============================================================================
--- (empty file)
+++ pypy/branch/refactor-x86/pypy/jit/backend/llsupport/regalloc.py	Sun Sep 27 10:24:52 2009
@@ -0,0 +1,84 @@
+
+from pypy.jit.metainterp.history import Const
+from pypy.rlib.objectmodel import we_are_translated
+
+class StackManager(object):
+    """ Manage stack positions
+    """
+
+class RegisterManager(object):
+    """ Class that keeps track of register allocations
+    """
+    def __init__(self, register_pool, longevity):
+        self.free_regs = register_pool[:]
+        self.all_regs = register_pool
+        self.longevity = longevity
+        self.reg_bindings = {}
+        self.position = 0
+
+    def next_instruction(self, incr=1):
+        self.position += incr
+
+    def possibly_free_var(self, v):
+        if isinstance(v, Const) or v not in self.reg_bindings:
+            return
+        if v not in self.longevity or self.longevity[v][1] <= self.position:
+            self.free_regs.append(self.reg_bindings[v])
+            del self.reg_bindings[v]
+
+    def possibly_free_vars(self, vars):
+        for v in vars:
+            self.possibly_free_var(v)
+
+    def _check_invariants(self):
+        if not we_are_translated():
+            # make sure no duplicates
+            assert len(dict.fromkeys(self.reg_bindings.values())) == len(self.reg_bindings)
+            rev_regs = dict.fromkeys(self.reg_bindings.values())
+            for reg in self.free_regs:
+                assert reg not in rev_regs
+            assert len(rev_regs) + len(self.free_regs) == len(self.all_regs)
+        else:
+            assert len(self.reg_bindings) + len(self.free_regs) == len(self.all_regs)
+        if self.longevity:
+            for v in self.reg_bindings:
+                assert self.longevity[v][1] > self.position
+
+    def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
+        assert not isinstance(v, Const)
+        if selected_reg is not None:
+            res = self.reg_bindings.get(v, None)
+            if res:
+                if res is selected_reg:
+                    return res
+                else:
+                    del self.reg_bindings[v]
+                    self.free_regs.append(res)
+            if selected_reg in self.free_regs:
+                self.free_regs = [reg for reg in self.free_regs
+                                  if reg is not selected_reg]
+                self.reg_bindings[v] = selected_reg
+                return selected_reg
+            return None
+        if need_lower_byte:
+            loc = self.reg_bindings.get(v, None)
+            if loc is not None and loc is not edi and loc is not esi:
+                return loc
+            for i in range(len(self.free_regs)):
+                reg = self.free_regs[i]
+                if reg is not edi and reg is not esi:
+                    if loc is not None:
+                        self.free_regs[i] = loc
+                    else:
+                        del self.free_regs[i]
+                    self.reg_bindings[v] = reg
+                    return reg
+            return None
+        try:
+            return self.reg_bindings[v]
+        except KeyError:
+            if self.free_regs:
+                loc = self.free_regs.pop()
+                self.reg_bindings[v] = loc
+                return loc
+

Added: pypy/branch/refactor-x86/pypy/jit/backend/llsupport/test/test_regalloc.py
==============================================================================
--- (empty file)
+++ pypy/branch/refactor-x86/pypy/jit/backend/llsupport/test/test_regalloc.py	Sun Sep 27 10:24:52 2009
@@ -0,0 +1,40 @@
+
+from pypy.jit.metainterp.history import BoxInt, ConstInt
+from pypy.jit.backend.llsupport.regalloc import RegisterManager
+
+def boxes(*values):
+    return [BoxInt(v) for v in values]
+
+class FakeReg(object):
+    pass
+
+r0, r1, r2, r3 = [FakeReg() for _ in range(4)]
+regs = [r0, r1, r2, r3]
+
+class TestRegalloc(object):
+    def test_freeing_vars(self):
+        b0, b1, b2 = boxes(0, 0, 0)
+        longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)}
+        rm = RegisterManager(regs, longevity)
+        for b in b0, b1, b2:
+            rm.try_allocate_reg(b)
+        rm._check_invariants()
+        assert len(rm.free_regs) == 1
+        assert len(rm.reg_bindings) == 3
+        rm.possibly_free_vars([b0, b1, b2])
+        assert len(rm.free_regs) == 1
+        assert len(rm.reg_bindings) == 3
+        rm._check_invariants()
+        rm.next_instruction()
+        rm.possibly_free_vars([b0, b1, b2])
+        rm._check_invariants()
+        assert len(rm.free_regs) == 2
+        assert len(rm.reg_bindings) == 2
+        rm._check_invariants()
+        rm.next_instruction()
+        rm.possibly_free_vars([b0, b1, b2])
+        rm._check_invariants()
+        assert len(rm.free_regs) == 4
+        assert len(rm.reg_bindings) == 0
+        
+        



More information about the Pypy-commit mailing list