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

fijal at codespeak.net fijal at codespeak.net
Mon Sep 28 14:23:00 CEST 2009


Author: fijal
Date: Mon Sep 28 14:22:59 2009
New Revision: 67929

Modified:
   pypy/branch/refactor-x86/pypy/jit/backend/llsupport/regalloc.py
   pypy/branch/refactor-x86/pypy/jit/backend/llsupport/test/test_regalloc.py
Log:
Support for calls


Modified: pypy/branch/refactor-x86/pypy/jit/backend/llsupport/regalloc.py
==============================================================================
--- pypy/branch/refactor-x86/pypy/jit/backend/llsupport/regalloc.py	(original)
+++ pypy/branch/refactor-x86/pypy/jit/backend/llsupport/regalloc.py	Mon Sep 28 14:22:59 2009
@@ -38,14 +38,16 @@
 class RegisterManager(object):
     """ Class that keeps track of register allocations
     """
-    def __init__(self, register_pool, longevity, no_lower_byte_regs=(),
+    no_lower_byte_regs = ()
+    save_around_call_regs = ()
+    
+    def __init__(self, register_pool, longevity,
                  stack_manager=None, assembler=None):
         self.free_regs = register_pool[:]
         self.all_regs = register_pool
         self.longevity = longevity
         self.reg_bindings = {}
         self.position = -1
-        self.no_lower_byte_regs = no_lower_byte_regs
         self.stack_manager = stack_manager
         self.assembler = assembler
 
@@ -243,7 +245,38 @@
             loc = self.reg_bindings[result_v]
         return loc
 
+    def sync_var(self, v):
+        if not self.stack_manager.get(v):
+            reg = self.reg_bindings[v]
+            self.assembler.regalloc_mov(reg, self.stack_manager.loc(v))
+        # otherwise it's clean
+
+    def before_call(self, force_store=[]):
+        for v, reg in self.reg_bindings.items():
+            if v not in force_store and self.longevity[v][1] <= self.position:
+                # variable dies
+                del self.reg_bindings[v]
+                self.free_regs.append(reg)
+                continue
+            if reg not in self.save_around_call_regs:
+                # we don't need to
+                continue
+            self.sync_var(v)
+            del self.reg_bindings[v]
+            self.free_regs.append(reg)
+
+    def after_call(self, v):
+        if v is not None:
+            r = self.result_stored_in_reg(v)
+            self.reg_bindings[v] = r
+            self.free_regs = [fr for fr in self.free_regs if fr is not r]
+    
     # abstract methods, override
 
     def convert_to_imm(self, c):
         raise NotImplementedError("Abstract")
+
+    def result_stored_in_reg(self, v):
+        # takes a variable and tells where the result will be
+        # stored
+        raise NotImplementedError("Abstract")

Modified: pypy/branch/refactor-x86/pypy/jit/backend/llsupport/test/test_regalloc.py
==============================================================================
--- pypy/branch/refactor-x86/pypy/jit/backend/llsupport/test/test_regalloc.py	(original)
+++ pypy/branch/refactor-x86/pypy/jit/backend/llsupport/test/test_regalloc.py	Mon Sep 28 14:22:59 2009
@@ -75,13 +75,16 @@
     def test_need_lower_byte(self):
         boxes, longevity = boxes_and_longevity(5)
         b0, b1, b2, b3, b4 = boxes
-        no_lower_byte_regs = [r2, r3]
-        rm = RegisterManager(regs, longevity, no_lower_byte_regs)
+
+        class XRegisterManager(RegisterManager):
+            no_lower_byte_regs = [r2, r3]
+        
+        rm = XRegisterManager(regs, longevity)
         rm.next_instruction()
         loc0 = rm.try_allocate_reg(b0, need_lower_byte=True)
-        assert loc0 not in no_lower_byte_regs
+        assert loc0 not in XRegisterManager.no_lower_byte_regs
         loc = rm.try_allocate_reg(b1, need_lower_byte=True)
-        assert loc not in no_lower_byte_regs
+        assert loc not in XRegisterManager.no_lower_byte_regs
         loc = rm.try_allocate_reg(b2, need_lower_byte=True)
         assert loc is None
         loc = rm.try_allocate_reg(b0, need_lower_byte=True)
@@ -107,10 +110,13 @@
         boxes, longevity = boxes_and_longevity(5)
         b0, b1, b2, b3, b4 = boxes
         sm = TStackManager()
-        rm = RegisterManager(regs, longevity,
-                             no_lower_byte_regs = [r2, r3],
-                             stack_manager=sm,
-                             assembler=MockAsm())
+
+        class XRegisterManager(RegisterManager):
+            no_lower_byte_regs = [r2, r3]
+        
+        rm = XRegisterManager(regs, longevity,
+                              stack_manager=sm,
+                              assembler=MockAsm())
         rm.next_instruction()
         loc = rm.force_allocate_reg(b0)
         assert isinstance(loc, FakeReg)
@@ -235,3 +241,26 @@
         rm = RegisterManager(regs, {})
         rm.next_instruction()
         assert isinstance(rm.loc(ConstInt(1)), ConstInt)
+
+    def test_call_support(self):
+        class XRegisterManager(RegisterManager):
+            save_around_call_regs = [r1, r2]
+
+            def result_stored_in_reg(self, v):
+                return r1
+
+        sm = TStackManager()
+        asm = MockAsm()
+        boxes, longevity = boxes_and_longevity(5)
+        rm = XRegisterManager(regs, longevity, stack_manager=sm,
+                              assembler=asm)
+        for b in boxes[:-1]:
+            rm.force_allocate_reg(b)
+        rm.before_call()
+        assert len(rm.reg_bindings) == 2
+        assert sm.stack_depth == 2
+        assert len(asm.moves) == 2
+        rm._check_invariants()
+        rm.after_call(boxes[-1])
+        assert len(rm.reg_bindings) == 3
+        rm._check_invariants()



More information about the Pypy-commit mailing list