[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