[pypy-svn] r69981 - in pypy/trunk/pypy/jit: backend/cli/test backend/llsupport backend/llsupport/test backend/llvm/test backend/x86 backend/x86/test metainterp
pedronis at codespeak.net
pedronis at codespeak.net
Tue Dec 8 16:49:13 CET 2009
Author: pedronis
Date: Tue Dec 8 16:49:12 2009
New Revision: 69981
Modified:
pypy/trunk/pypy/jit/backend/cli/test/conftest.py (props changed)
pypy/trunk/pypy/jit/backend/llsupport/regalloc.py
pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py
pypy/trunk/pypy/jit/backend/llsupport/test/test_regalloc.py
pypy/trunk/pypy/jit/backend/llvm/test/conftest.py (props changed)
pypy/trunk/pypy/jit/backend/x86/assembler.py
pypy/trunk/pypy/jit/backend/x86/jump.py
pypy/trunk/pypy/jit/backend/x86/regalloc.py
pypy/trunk/pypy/jit/backend/x86/test/test_assembler.py
pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py (contents, props changed)
pypy/trunk/pypy/jit/backend/x86/test/test_jump.py
pypy/trunk/pypy/jit/backend/x86/test/test_recompilation.py
pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py
pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py
pypy/trunk/pypy/jit/metainterp/logger.py (props changed)
Log:
merge esp-params, avoid esp adjustments around most emitted calls, instead reserve globally space for params after the frame locations
Modified: pypy/trunk/pypy/jit/backend/llsupport/regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/regalloc.py (original)
+++ pypy/trunk/pypy/jit/backend/llsupport/regalloc.py Tue Dec 8 16:49:12 2009
@@ -12,28 +12,28 @@
class NoVariableToSpill(Exception):
pass
-class StackManager(object):
- """ Manage stack positions
+class FrameManager(object):
+ """ Manage frame positions
"""
def __init__(self):
- self.stack_bindings = {}
- self.stack_depth = 0
+ self.frame_bindings = {}
+ self.frame_depth = 0
def get(self, box):
- return self.stack_bindings.get(box, None)
+ return self.frame_bindings.get(box, None)
def loc(self, box, size):
res = self.get(box)
if res is not None:
return res
- newloc = self.stack_pos(self.stack_depth, size)
- self.stack_bindings[box] = newloc
- self.stack_depth += size
+ newloc = self.frame_pos(self.frame_depth, size)
+ self.frame_bindings[box] = newloc
+ self.frame_depth += size
return newloc
# abstract methods that need to be overwritten for specific assemblers
@staticmethod
- def stack_pos(loc, size):
+ def frame_pos(loc, size):
raise NotImplementedError("Purely abstract")
class RegisterManager(object):
@@ -45,12 +45,12 @@
save_around_call_regs = []
reg_width = 1 # in terms of stack space eaten
- def __init__(self, longevity, stack_manager=None, assembler=None):
+ def __init__(self, longevity, frame_manager=None, assembler=None):
self.free_regs = self.all_regs[:]
self.longevity = longevity
self.reg_bindings = {}
self.position = -1
- self.stack_manager = stack_manager
+ self.frame_manager = frame_manager
self.assembler = assembler
def stays_alive(self, v):
@@ -147,8 +147,8 @@
selected_reg, need_lower_byte=need_lower_byte)
loc = self.reg_bindings[v_to_spill]
del self.reg_bindings[v_to_spill]
- if self.stack_manager.get(v_to_spill) is None:
- newloc = self.stack_manager.loc(v_to_spill, self.reg_width)
+ if self.frame_manager.get(v_to_spill) is None:
+ newloc = self.frame_manager.loc(v_to_spill, self.reg_width)
self.assembler.regalloc_mov(loc, newloc)
return loc
@@ -204,7 +204,7 @@
try:
return self.reg_bindings[box]
except KeyError:
- return self.stack_manager.loc(box, self.reg_width)
+ return self.frame_manager.loc(box, self.reg_width)
def return_constant(self, v, forbidden_vars=[], selected_reg=None,
imm_fine=True):
@@ -260,7 +260,7 @@
self.reg_bindings[v] = loc
self.assembler.regalloc_mov(prev_loc, loc)
else:
- loc = self.stack_manager.loc(v, self.reg_width)
+ loc = self.frame_manager.loc(v, self.reg_width)
self.assembler.regalloc_mov(prev_loc, loc)
def force_result_in_reg(self, result_v, v, forbidden_vars=[]):
@@ -280,7 +280,7 @@
self.free_regs = [reg for reg in self.free_regs if reg is not loc]
return loc
if v not in self.reg_bindings:
- prev_loc = self.stack_manager.loc(v, self.reg_width)
+ prev_loc = self.frame_manager.loc(v, self.reg_width)
loc = self.force_allocate_reg(v, forbidden_vars)
self.assembler.regalloc_mov(prev_loc, loc)
assert v in self.reg_bindings
@@ -289,7 +289,7 @@
# store result in the same place
loc = self.reg_bindings[v]
del self.reg_bindings[v]
- if self.stack_manager.get(v) is None:
+ if self.frame_manager.get(v) is None:
self._move_variable_away(v, loc)
self.reg_bindings[result_v] = loc
else:
@@ -298,9 +298,9 @@
return loc
def _sync_var(self, v):
- if not self.stack_manager.get(v):
+ if not self.frame_manager.get(v):
reg = self.reg_bindings[v]
- to = self.stack_manager.loc(v, self.reg_width)
+ to = self.frame_manager.loc(v, self.reg_width)
self.assembler.regalloc_mov(reg, to)
# otherwise it's clean
Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py (original)
+++ pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py Tue Dec 8 16:49:12 2009
@@ -61,11 +61,11 @@
assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i])
def test_GcRootMap_asmgcc():
- def stack_pos(n):
+ def frame_pos(n):
return -4*(4+n)
gcrootmap = GcRootMap_asmgcc()
- num1 = stack_pos(1)
- num2 = stack_pos(55)
+ num1 = frame_pos(1)
+ num2 = frame_pos(55)
shape = gcrootmap.get_basic_shape()
gcrootmap.add_ebp_offset(shape, num1)
gcrootmap.add_ebp_offset(shape, num2)
@@ -99,7 +99,7 @@
expected_shapeaddr = {}
for i in range(1, 600):
shape = gcrootmap.get_basic_shape()
- gcrootmap.add_ebp_offset(shape, stack_pos(i))
+ gcrootmap.add_ebp_offset(shape, frame_pos(i))
shapeaddr = gcrootmap.compress_callshape(shape)
expected_shapeaddr[i] = shapeaddr
retaddr = rffi.cast(llmemory.Address, 123456789 + i)
Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/test/test_regalloc.py (original)
+++ pypy/trunk/pypy/jit/backend/llsupport/test/test_regalloc.py Tue Dec 8 16:49:12 2009
@@ -1,6 +1,6 @@
from pypy.jit.metainterp.history import BoxInt, ConstInt, BoxFloat
-from pypy.jit.backend.llsupport.regalloc import StackManager
+from pypy.jit.backend.llsupport.regalloc import FrameManager
from pypy.jit.backend.llsupport.regalloc import RegisterManager as BaseRegMan
def newboxes(*values):
@@ -26,8 +26,8 @@
def convert_to_imm(self, v):
return v
-class TStackManager(StackManager):
- def stack_pos(self, i, size):
+class TFrameManager(FrameManager):
+ def frame_pos(self, i, size):
return i
class MockAsm(object):
@@ -110,13 +110,13 @@
def test_force_allocate_reg(self):
boxes, longevity = boxes_and_longevity(5)
b0, b1, b2, b3, b4 = boxes
- sm = TStackManager()
+ fm = TFrameManager()
class XRegisterManager(RegisterManager):
no_lower_byte_regs = [r2, r3]
rm = XRegisterManager(longevity,
- stack_manager=sm,
+ frame_manager=fm,
assembler=MockAsm())
rm.next_instruction()
loc = rm.force_allocate_reg(b0)
@@ -140,13 +140,13 @@
def test_make_sure_var_in_reg(self):
boxes, longevity = boxes_and_longevity(5)
- sm = TStackManager()
- rm = RegisterManager(longevity, stack_manager=sm,
+ fm = TFrameManager()
+ rm = RegisterManager(longevity, frame_manager=fm,
assembler=MockAsm())
rm.next_instruction()
# allocate a stack position
b0, b1, b2, b3, b4 = boxes
- sp = sm.loc(b0, 1)
+ sp = fm.loc(b0, 1)
assert sp == 0
loc = rm.make_sure_var_in_reg(b0)
assert isinstance(loc, FakeReg)
@@ -155,9 +155,9 @@
def test_force_result_in_reg_1(self):
b0, b1 = newboxes(0, 0)
longevity = {b0: (0, 1), b1: (1, 3)}
- sm = TStackManager()
+ fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, stack_manager=sm, assembler=asm)
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
rm.next_instruction()
# first path, var is already in reg and dies
loc0 = rm.force_allocate_reg(b0)
@@ -171,9 +171,9 @@
def test_force_result_in_reg_2(self):
b0, b1 = newboxes(0, 0)
longevity = {b0: (0, 2), b1: (1, 3)}
- sm = TStackManager()
+ fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, stack_manager=sm, assembler=asm)
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
rm.next_instruction()
loc0 = rm.force_allocate_reg(b0)
rm._check_invariants()
@@ -187,9 +187,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)}
- sm = TStackManager()
+ fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, stack_manager=sm, assembler=asm)
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
rm.next_instruction()
for b in b0, b1, b2, b3:
rm.force_allocate_reg(b)
@@ -203,11 +203,11 @@
def test_force_result_in_reg_4(self):
b0, b1 = newboxes(0, 0)
longevity = {b0: (0, 1), b1: (0, 1)}
- sm = TStackManager()
+ fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, stack_manager=sm, assembler=asm)
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
rm.next_instruction()
- sm.loc(b0, 1)
+ fm.loc(b0, 1)
rm.force_result_in_reg(b1, b0)
rm._check_invariants()
loc = rm.loc(b1)
@@ -219,9 +219,9 @@
def test_return_constant(self):
asm = MockAsm()
boxes, longevity = boxes_and_longevity(5)
- sm = TStackManager()
+ fm = TFrameManager()
rm = RegisterManager(longevity, assembler=asm,
- stack_manager=sm)
+ frame_manager=fm)
rm.next_instruction()
loc = rm.return_constant(ConstInt(0), imm_fine=False)
assert isinstance(loc, FakeReg)
@@ -241,9 +241,9 @@
def test_force_result_in_reg_const(self):
boxes, longevity = boxes_and_longevity(2)
- sm = TStackManager()
+ fm = TFrameManager()
asm = MockAsm()
- rm = RegisterManager(longevity, stack_manager=sm,
+ rm = RegisterManager(longevity, frame_manager=fm,
assembler=asm)
rm.next_instruction()
c = ConstInt(0)
@@ -262,16 +262,16 @@
def call_result_location(self, v):
return r1
- sm = TStackManager()
+ fm = TFrameManager()
asm = MockAsm()
boxes, longevity = boxes_and_longevity(5)
- rm = XRegisterManager(longevity, stack_manager=sm,
+ rm = XRegisterManager(longevity, frame_manager=fm,
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 fm.frame_depth == 2
assert len(asm.moves) == 2
rm._check_invariants()
rm.after_call(boxes[-1])
@@ -285,16 +285,16 @@
def call_result_location(self, v):
return r1
- sm = TStackManager()
+ fm = TFrameManager()
asm = MockAsm()
boxes, longevity = boxes_and_longevity(5)
- rm = XRegisterManager(longevity, stack_manager=sm,
+ rm = XRegisterManager(longevity, frame_manager=fm,
assembler=asm)
for b in boxes[:-1]:
rm.force_allocate_reg(b)
rm.before_call(save_all_regs=True)
assert len(rm.reg_bindings) == 0
- assert sm.stack_depth == 4
+ assert fm.frame_depth == 4
assert len(asm.moves) == 4
rm._check_invariants()
rm.after_call(boxes[-1])
@@ -302,20 +302,20 @@
rm._check_invariants()
- def test_different_stack_width(self):
+ def test_different_frame_width(self):
class XRegisterManager(RegisterManager):
reg_width = 2
- sm = TStackManager()
+ fm = TFrameManager()
b0 = BoxInt()
longevity = {b0: (0, 1)}
asm = MockAsm()
- rm = RegisterManager(longevity, stack_manager=sm, assembler=asm)
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
f0 = BoxFloat()
longevity = {f0: (0, 1)}
- xrm = XRegisterManager(longevity, stack_manager=sm, assembler=asm)
+ xrm = XRegisterManager(longevity, frame_manager=fm, assembler=asm)
xrm.loc(f0)
rm.loc(b0)
- assert sm.stack_depth == 3
+ assert fm.frame_depth == 3
Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/assembler.py Tue Dec 8 16:49:12 2009
@@ -157,7 +157,8 @@
"""adds the following attributes to looptoken:
_x86_loop_code (an integer giving an address)
_x86_bootstrap_code (an integer giving an address)
- _x86_stack_depth
+ _x86_frame_depth
+ _x86_param_depth
_x86_arglocs
"""
self.make_sure_mc_exists()
@@ -167,10 +168,12 @@
looptoken._x86_bootstrap_code = self.mc.tell()
adr_stackadjust = self._assemble_bootstrap_code(inputargs, arglocs)
looptoken._x86_loop_code = self.mc.tell()
- looptoken._x86_stack_depth = -1 # temporarily
- stack_depth = self._assemble(regalloc, operations)
- self._patch_stackadjust(adr_stackadjust, stack_depth)
- looptoken._x86_stack_depth = stack_depth
+ looptoken._x86_frame_depth = -1 # temporarily
+ looptoken._x86_param_depth = -1 # temporarily
+ frame_depth, param_depth = self._assemble(regalloc, operations)
+ self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth)
+ looptoken._x86_frame_depth = frame_depth
+ looptoken._x86_param_depth = param_depth
def assemble_bridge(self, faildescr, inputargs, operations):
self.make_sure_mc_exists()
@@ -180,16 +183,17 @@
assert ([loc.assembler() for loc in arglocs] ==
[loc.assembler() for loc in faildescr._x86_debug_faillocs])
regalloc = RegAlloc(self, self.cpu.translate_support_code)
- fail_stack_depth = faildescr._x86_current_stack_depth
- regalloc.prepare_bridge(fail_stack_depth, inputargs, arglocs,
+ fail_depths = faildescr._x86_current_depths
+ regalloc.prepare_bridge(fail_depths, inputargs, arglocs,
operations)
adr_bridge = self.mc.tell()
adr_stackadjust = self._patchable_stackadjust()
- stack_depth = self._assemble(regalloc, operations)
- self._patch_stackadjust(adr_stackadjust, stack_depth)
+ frame_depth, param_depth = self._assemble(regalloc, operations)
+ self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth)
if not we_are_translated():
# for the benefit of tests
- faildescr._x86_bridge_stack_depth = stack_depth
+ faildescr._x86_bridge_frame_depth = frame_depth
+ faildescr._x86_bridge_param_depth = param_depth
# patch the jump from original guard
self.patch_jump(faildescr, adr_bridge)
@@ -207,26 +211,29 @@
self.mc2.done()
if we_are_translated() or self.cpu.dont_keepalive_stuff:
self._regalloc = None # else keep it around for debugging
- stack_depth = regalloc.sm.stack_depth
+ frame_depth = regalloc.fm.frame_depth
+ param_depth = regalloc.param_depth
jump_target_descr = regalloc.jump_target_descr
if jump_target_descr is not None:
- target_stack_depth = jump_target_descr._x86_stack_depth
- stack_depth = max(stack_depth, target_stack_depth)
- return stack_depth
+ target_frame_depth = jump_target_descr._x86_frame_depth
+ target_param_depth = jump_target_descr._x86_param_depth
+ frame_depth = max(frame_depth, target_frame_depth)
+ param_depth = max(param_depth, target_param_depth)
+ return frame_depth, param_depth
def _patchable_stackadjust(self):
# stack adjustment LEA
self.mc.LEA(esp, fixedsize_ebp_ofs(0))
return self.mc.tell() - 4
- def _patch_stackadjust(self, adr_lea, stack_depth):
+ def _patch_stackadjust(self, adr_lea, reserved_depth):
# patch stack adjustment LEA
# possibly align, e.g. for Mac OS X
mc = codebuf.InMemoryCodeBuilder(adr_lea, adr_lea + 4)
# Compute the correct offset for the instruction LEA ESP, [EBP-4*words].
# Given that [EBP] is where we saved EBP, i.e. in the last word
# of our fixed frame, then the 'words' value is:
- words = (FRAME_FIXED_SIZE - 1) + stack_depth
+ words = (FRAME_FIXED_SIZE - 1) + reserved_depth
mc.write(packimm32(-WORD * words))
mc.done()
@@ -322,10 +329,10 @@
genop_discard_list[op.opnum](self, op, arglocs)
def regalloc_perform_with_guard(self, op, guard_op, faillocs,
- arglocs, resloc, current_stack_depth):
+ arglocs, resloc, current_depths):
faildescr = guard_op.descr
assert isinstance(faildescr, AbstractFailDescr)
- faildescr._x86_current_stack_depth = current_stack_depth
+ faildescr._x86_current_depths = current_depths
failargs = guard_op.fail_args
guard_opnum = guard_op.opnum
failaddr = self.implement_guard_recovery(guard_opnum,
@@ -342,9 +349,9 @@
faildescr._x86_adr_jump_offset = adr_jump_offset
def regalloc_perform_guard(self, guard_op, faillocs, arglocs, resloc,
- current_stack_depth):
+ current_depths):
self.regalloc_perform_with_guard(None, guard_op, faillocs, arglocs,
- resloc, current_stack_depth)
+ resloc, current_depths)
def load_effective_addr(self, sizereg, baseofs, scale, result):
self.mc.LEA(result, addr_add(imm(0), sizereg, baseofs, scale))
@@ -407,14 +414,34 @@
## self.mc.PUSH(imm(0)) --- or just use a single SUB(esp, imm)
## return extra_on_stack
- def call(self, addr, args, res):
- nargs = len(args)
- extra_on_stack = nargs #self.align_stack_for_call(nargs)
- for i in range(nargs-1, -1, -1):
- self.mc.PUSH(args[i])
- self.mc.CALL(rel32(addr))
+ def _emit_call(self, x, arglocs, start=0, tmp=eax):
+ p = 0
+ n = len(arglocs)
+ for i in range(start, n):
+ loc = arglocs[i]
+ if isinstance(loc, REG):
+ if isinstance(loc, XMMREG):
+ self.mc.MOVSD(mem64(esp, p), loc)
+ else:
+ self.mc.MOV(mem(esp, p), loc)
+ p += round_up_to_4(loc.width)
+ p = 0
+ for i in range(start, n):
+ loc = arglocs[i]
+ if not isinstance(loc, REG):
+ if isinstance(loc, MODRM64):
+ self.mc.MOVSD(xmm0, loc)
+ self.mc.MOVSD(mem64(esp, p), xmm0)
+ else:
+ self.mc.MOV(tmp, loc)
+ self.mc.MOV(mem(esp, p), tmp)
+ p += round_up_to_4(loc.width)
+ self._regalloc.reserve_param(p//WORD)
+ self.mc.CALL(x)
self.mark_gc_roots()
- self.mc.ADD(esp, imm(extra_on_stack * WORD))
+
+ def call(self, addr, args, res):
+ self._emit_call(rel32(addr), args)
assert res is eax
genop_int_neg = _unaryop("NEG")
@@ -858,7 +885,7 @@
self.fail_boxes_float.get_addr_for_num(i)
def rebuild_faillocs_from_descr(self, bytecode):
- from pypy.jit.backend.x86.regalloc import X86StackManager
+ from pypy.jit.backend.x86.regalloc import X86FrameManager
bytecode = rffi.cast(rffi.UCHARP, bytecode)
arglocs = []
while 1:
@@ -883,7 +910,7 @@
size = 2
else:
size = 1
- loc = X86StackManager.stack_pos(code, size)
+ loc = X86FrameManager.frame_pos(code, size)
elif code == self.CODE_STOP:
break
elif code == self.CODE_HOLE:
@@ -1121,12 +1148,7 @@
sizeloc = arglocs[0]
assert isinstance(sizeloc, IMM32)
size = sizeloc.value
- nargs = len(op.args)-1
- extra_on_stack = 0
- for arg in range(2, nargs + 2):
- extra_on_stack += round_up_to_4(arglocs[arg].width)
- #extra_on_stack = self.align_stack_for_call(extra_on_stack)
- self.mc.SUB(esp, imm(extra_on_stack))
+
if isinstance(op.args[0], Const):
x = rel32(op.args[0].getint())
else:
@@ -1135,29 +1157,9 @@
tmp = ecx
else:
tmp = eax
- p = 0
- for i in range(2, nargs + 2):
- loc = arglocs[i]
- if isinstance(loc, REG):
- if isinstance(loc, XMMREG):
- self.mc.MOVSD(mem64(esp, p), loc)
- else:
- self.mc.MOV(mem(esp, p), loc)
- p += round_up_to_4(loc.width)
- p = 0
- for i in range(2, nargs + 2):
- loc = arglocs[i]
- if not isinstance(loc, REG):
- if isinstance(loc, MODRM64):
- self.mc.MOVSD(xmm0, loc)
- self.mc.MOVSD(mem64(esp, p), xmm0)
- else:
- self.mc.MOV(tmp, loc)
- self.mc.MOV(mem(esp, p), tmp)
- p += round_up_to_4(loc.width)
- self.mc.CALL(x)
- self.mark_gc_roots()
- self.mc.ADD(esp, imm(extra_on_stack))
+
+ self._emit_call(x, arglocs, 2, tmp=tmp)
+
if isinstance(resloc, MODRM64):
self.mc.FSTP(resloc)
elif size == 1:
@@ -1245,14 +1247,13 @@
mc.CMP(edx, heap(nursery_top_adr))
mc.write(constlistofchars('\x76\x00')) # JNA after the block
jmp_adr = mc.get_relative_pos()
- mc.PUSH(imm(size))
- mc.CALL(rel32(slowpath_addr))
- self.mark_gc_roots()
+ self._emit_call(rel32(slowpath_addr), [imm(size)])
+
# note that slowpath_addr returns a "long long", or more precisely
# two results, which end up in eax and edx.
# eax should contain the result of allocation, edx new value
# of nursery_free_adr
- mc.ADD(esp, imm(4))
+
offset = mc.get_relative_pos() - jmp_adr
assert 0 < offset <= 127
mc.overwrite(jmp_adr-1, [chr(offset)])
Modified: pypy/trunk/pypy/jit/backend/x86/jump.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/jump.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/jump.py Tue Dec 8 16:49:12 2009
@@ -5,7 +5,7 @@
class __extend__(OPERAND):
__metaclass__ = extendabletype
def _getregkey(self):
- raise AssertionError("should only happen to registers and stack "
+ raise AssertionError("should only happen to registers and frame "
"positions")
class __extend__(REG):
@@ -19,7 +19,7 @@
return self.position
-def remap_stack_layout(assembler, src_locations, dst_locations, tmpreg):
+def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg):
pending_dests = len(dst_locations)
srccount = {} # maps dst_locations to how many times the same
# location appears in src_locations
Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/regalloc.py Tue Dec 8 16:49:12 2009
@@ -11,11 +11,11 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib import rgc
from pypy.jit.backend.llsupport import symbolic
-from pypy.jit.backend.x86.jump import remap_stack_layout
+from pypy.jit.backend.x86.jump import remap_frame_layout
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr
from pypy.jit.backend.llsupport.descr import BaseCallDescr, BaseSizeDescr
-from pypy.jit.backend.llsupport.regalloc import StackManager, RegisterManager,\
+from pypy.jit.backend.llsupport.regalloc import FrameManager, RegisterManager,\
TempBox
WORD = 4
@@ -67,8 +67,8 @@
return lltype.malloc(rffi.CArray(lltype.Float), BASE_CONSTANT_SIZE,
flavor='raw')
- def __init__(self, longevity, stack_manager=None, assembler=None):
- RegisterManager.__init__(self, longevity, stack_manager=stack_manager,
+ def __init__(self, longevity, frame_manager=None, assembler=None):
+ RegisterManager.__init__(self, longevity, frame_manager=frame_manager,
assembler=assembler)
self.constant_arrays = [self.new_const_array()]
self.constant_array_counter = 0
@@ -89,14 +89,14 @@
def after_call(self, v):
# the result is stored in st0, but we don't have this around,
- # so genop_call will move it to some stack location immediately
+ # so genop_call will move it to some frame location immediately
# after the call
- return self.stack_manager.loc(v, 2)
+ return self.frame_manager.loc(v, 2)
-class X86StackManager(StackManager):
+class X86FrameManager(FrameManager):
@staticmethod
- def stack_pos(i, size):
+ def frame_pos(i, size):
if size == 1:
res = mem(ebp, get_ebp_ofs(i))
elif size == 2:
@@ -119,16 +119,17 @@
self.jump_target_descr = None
def _prepare(self, inputargs, operations):
- self.sm = X86StackManager()
+ self.fm = X86FrameManager()
+ self.param_depth = 0
cpu = self.assembler.cpu
cpu.gc_ll_descr.rewrite_assembler(cpu, operations)
# compute longevity of variables
longevity = self._compute_vars_longevity(inputargs, operations)
self.longevity = longevity
self.rm = X86RegisterManager(longevity,
- stack_manager = self.sm,
+ frame_manager = self.fm,
assembler = self.assembler)
- self.xrm = X86XMMRegisterManager(longevity, stack_manager = self.sm,
+ self.xrm = X86XMMRegisterManager(longevity, frame_manager = self.fm,
assembler = self.assembler)
def prepare_loop(self, inputargs, operations, looptoken):
@@ -138,11 +139,15 @@
self.loop_consts = loop_consts
return self._process_inputargs(inputargs)
- def prepare_bridge(self, prev_stack_depth, inputargs, arglocs, operations):
+ def prepare_bridge(self, prev_depths, inputargs, arglocs, operations):
self._prepare(inputargs, operations)
self.loop_consts = {}
self._update_bindings(arglocs, inputargs)
- self.sm.stack_depth = prev_stack_depth
+ self.fm.frame_depth = prev_depths[0]
+ self.param_depth = prev_depths[1]
+
+ def reserve_param(self, n):
+ self.param_depth = max(self.param_depth, n)
def _process_inputargs(self, inputargs):
# XXX we can sort out here by longevity if we need something
@@ -170,7 +175,7 @@
if reg:
loc = reg
else:
- loc = self.sm.loc(arg, width_of_type[arg.type])
+ loc = self.fm.loc(arg, width_of_type[arg.type])
if arg.type == FLOAT:
floatlocs[i] = loc
else:
@@ -241,13 +246,13 @@
self.xrm.reg_bindings[arg] = loc
used[loc] = None
else:
- self.sm.stack_bindings[arg] = loc
+ self.fm.frame_bindings[arg] = loc
else:
if isinstance(loc, REG):
self.rm.reg_bindings[arg] = loc
used[loc] = None
else:
- self.sm.stack_bindings[arg] = loc
+ self.fm.frame_bindings[arg] = loc
self.rm.free_regs = []
for reg in X86RegisterManager.all_regs:
if reg not in used:
@@ -274,9 +279,10 @@
faillocs = self.locs_for_fail(guard_op)
self.rm.position += 1
self.xrm.position += 1
+ current_depths = (self.fm.frame_depth, self.param_depth)
self.assembler.regalloc_perform_with_guard(op, guard_op, faillocs,
arglocs, result_loc,
- self.sm.stack_depth)
+ current_depths)
if op.result is not None:
self.possibly_free_var(op.result)
self.possibly_free_vars(guard_op.fail_args)
@@ -289,9 +295,10 @@
arglocs))
else:
self.assembler.dump('%s(%s)' % (guard_op, arglocs))
+ current_depths = (self.fm.frame_depth, self.param_depth)
self.assembler.regalloc_perform_guard(guard_op, faillocs, arglocs,
result_loc,
- self.sm.stack_depth)
+ current_depths)
self.possibly_free_vars(guard_op.fail_args)
def PerformDiscard(self, op, arglocs):
@@ -888,11 +895,11 @@
src_locations = [self.loc(arg) for arg in op.args if arg.type != FLOAT]
assert tmploc not in nonfloatlocs
dst_locations = [loc for loc in nonfloatlocs if loc is not None]
- remap_stack_layout(assembler, src_locations, dst_locations, tmploc)
+ remap_frame_layout(assembler, src_locations, dst_locations, tmploc)
# Part about floats
src_locations = [self.loc(arg) for arg in op.args if arg.type == FLOAT]
dst_locations = [loc for loc in floatlocs if loc is not None]
- remap_stack_layout(assembler, src_locations, dst_locations, xmmtmp)
+ remap_frame_layout(assembler, src_locations, dst_locations, xmmtmp)
self.rm.possibly_free_var(box)
self.xrm.possibly_free_var(box1)
self.possibly_free_vars(op.args)
@@ -903,7 +910,7 @@
def get_mark_gc_roots(self, gcrootmap):
shape = gcrootmap.get_basic_shape()
- for v, val in self.sm.stack_bindings.items():
+ for v, val in self.fm.frame_bindings.items():
if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
assert isinstance(val, MODRM)
gcrootmap.add_ebp_offset(shape, get_ebp_ofs(val.position))
@@ -937,7 +944,7 @@
oplist[num] = value
def get_ebp_ofs(position):
- # Argument is a stack position (0, 1, 2...).
+ # Argument is a frame position (0, 1, 2...).
# Returns (ebp-20), (ebp-24), (ebp-28)...
# i.e. the n'th word beyond the fixed frame size.
return -WORD * (FRAME_FIXED_SIZE + position)
Modified: pypy/trunk/pypy/jit/backend/x86/test/test_assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_assembler.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_assembler.py Tue Dec 8 16:49:12 2009
@@ -1,6 +1,6 @@
from pypy.jit.backend.x86.ri386 import *
from pypy.jit.backend.x86.assembler import Assembler386
-from pypy.jit.backend.x86.regalloc import X86StackManager, get_ebp_ofs
+from pypy.jit.backend.x86.regalloc import X86FrameManager, get_ebp_ofs
from pypy.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat
from pypy.rlib.rarithmetic import intmask
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
@@ -23,12 +23,12 @@
failargs = [BoxInt(), BoxPtr(), BoxFloat()] * 3
failargs.insert(6, None)
failargs.insert(7, None)
- locs = [X86StackManager.stack_pos(0, 1),
- X86StackManager.stack_pos(1, 1),
- X86StackManager.stack_pos(10, 2),
- X86StackManager.stack_pos(100, 1),
- X86StackManager.stack_pos(101, 1),
- X86StackManager.stack_pos(110, 2),
+ locs = [X86FrameManager.frame_pos(0, 1),
+ X86FrameManager.frame_pos(1, 1),
+ X86FrameManager.frame_pos(10, 2),
+ X86FrameManager.frame_pos(100, 1),
+ X86FrameManager.frame_pos(101, 1),
+ X86FrameManager.frame_pos(110, 2),
None,
None,
ebx,
Modified: pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py Tue Dec 8 16:49:12 2009
@@ -19,7 +19,7 @@
from pypy.jit.backend.x86.test.test_regalloc import MockAssembler
from pypy.jit.backend.x86.test.test_regalloc import BaseTestRegalloc
-from pypy.jit.backend.x86.regalloc import X86RegisterManager, X86StackManager,\
+from pypy.jit.backend.x86.regalloc import X86RegisterManager, X86FrameManager,\
X86XMMRegisterManager
from pypy.rpython.annlowlevel import llhelper
@@ -64,10 +64,10 @@
longevity = {}
for box in boxes:
longevity[box] = (0, 1)
- regalloc.sm = X86StackManager()
- regalloc.rm = X86RegisterManager(longevity, regalloc.sm,
+ regalloc.fm = X86FrameManager()
+ regalloc.rm = X86RegisterManager(longevity, regalloc.fm,
assembler=regalloc.assembler)
- regalloc.xrm = X86XMMRegisterManager(longevity, regalloc.sm,
+ regalloc.xrm = X86XMMRegisterManager(longevity, regalloc.fm,
assembler=regalloc.assembler)
cpu = regalloc.assembler.cpu
for box in boxes:
Modified: pypy/trunk/pypy/jit/backend/x86/test/test_jump.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_jump.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_jump.py Tue Dec 8 16:49:12 2009
@@ -1,8 +1,8 @@
from pypy.jit.backend.x86.ri386 import *
-from pypy.jit.backend.x86.regalloc import X86StackManager
-from pypy.jit.backend.x86.jump import remap_stack_layout
+from pypy.jit.backend.x86.regalloc import X86FrameManager
+from pypy.jit.backend.x86.jump import remap_frame_layout
-stack_pos = X86StackManager.stack_pos
+frame_pos = X86FrameManager.frame_pos
class MockAssembler:
def __init__(self):
@@ -36,33 +36,33 @@
def test_trivial():
assembler = MockAssembler()
- remap_stack_layout(assembler, [], [], '?')
+ remap_frame_layout(assembler, [], [], '?')
assert assembler.ops == []
- remap_stack_layout(assembler, [eax, ebx, ecx, edx, esi, edi],
+ remap_frame_layout(assembler, [eax, ebx, ecx, edx, esi, edi],
[eax, ebx, ecx, edx, esi, edi], '?')
assert assembler.ops == []
- s8 = stack_pos(1, 1)
- s12 = stack_pos(31, 1)
- s20 = stack_pos(6, 1)
- remap_stack_layout(assembler, [eax, ebx, ecx, s20, s8, edx, s12, esi, edi],
+ s8 = frame_pos(1, 1)
+ s12 = frame_pos(31, 1)
+ s20 = frame_pos(6, 1)
+ remap_frame_layout(assembler, [eax, ebx, ecx, s20, s8, edx, s12, esi, edi],
[eax, ebx, ecx, s20, s8, edx, s12, esi, edi],
'?')
assert assembler.ops == []
def test_simple_registers():
assembler = MockAssembler()
- remap_stack_layout(assembler, [eax, ebx, ecx], [edx, esi, edi], '?')
+ remap_frame_layout(assembler, [eax, ebx, ecx], [edx, esi, edi], '?')
assert assembler.ops == [('mov', eax, edx),
('mov', ebx, esi),
('mov', ecx, edi)]
-def test_simple_stacklocs():
+def test_simple_framelocs():
assembler = MockAssembler()
- s8 = stack_pos(0, 1)
- s12 = stack_pos(13, 1)
- s20 = stack_pos(20, 1)
- s24 = stack_pos(221, 1)
- remap_stack_layout(assembler, [s8, eax, s12], [s20, s24, edi], edx)
+ s8 = frame_pos(0, 1)
+ s12 = frame_pos(13, 1)
+ s20 = frame_pos(20, 1)
+ s24 = frame_pos(221, 1)
+ remap_frame_layout(assembler, [s8, eax, s12], [s20, s24, edi], edx)
assert assembler.ops == [('mov', s8, edx),
('mov', edx, s20),
('mov', eax, s24),
@@ -70,11 +70,11 @@
def test_reordering():
assembler = MockAssembler()
- s8 = stack_pos(8, 1)
- s12 = stack_pos(12, 1)
- s20 = stack_pos(19, 1)
- s24 = stack_pos(1, 1)
- remap_stack_layout(assembler, [eax, s8, s20, ebx],
+ s8 = frame_pos(8, 1)
+ s12 = frame_pos(12, 1)
+ s20 = frame_pos(19, 1)
+ s24 = frame_pos(1, 1)
+ remap_frame_layout(assembler, [eax, s8, s20, ebx],
[s8, ebx, eax, edi], '?')
assert assembler.got([('mov', ebx, edi),
('mov', s8, ebx),
@@ -83,11 +83,11 @@
def test_cycle():
assembler = MockAssembler()
- s8 = stack_pos(8, 1)
- s12 = stack_pos(12, 1)
- s20 = stack_pos(19, 1)
- s24 = stack_pos(1, 1)
- remap_stack_layout(assembler, [eax, s8, s20, ebx],
+ s8 = frame_pos(8, 1)
+ s12 = frame_pos(12, 1)
+ s20 = frame_pos(19, 1)
+ s24 = frame_pos(1, 1)
+ remap_frame_layout(assembler, [eax, s8, s20, ebx],
[s8, ebx, eax, s20], '?')
assert assembler.got([('push', s8),
('mov', eax, s8),
@@ -97,13 +97,13 @@
def test_cycle_2():
assembler = MockAssembler()
- s8 = stack_pos(8, 1)
- s12 = stack_pos(12, 1)
- s20 = stack_pos(19, 1)
- s24 = stack_pos(1, 1)
- s2 = stack_pos(2, 1)
- s3 = stack_pos(3, 1)
- remap_stack_layout(assembler,
+ s8 = frame_pos(8, 1)
+ s12 = frame_pos(12, 1)
+ s20 = frame_pos(19, 1)
+ s24 = frame_pos(1, 1)
+ s2 = frame_pos(2, 1)
+ s3 = frame_pos(3, 1)
+ remap_frame_layout(assembler,
[eax, s8, edi, s20, eax, s20, s24, esi, s2, s3],
[s8, s20, edi, eax, edx, s24, ebx, s12, s3, s2],
ecx)
@@ -124,18 +124,18 @@
def test_constants():
assembler = MockAssembler()
c3 = imm(3)
- remap_stack_layout(assembler, [c3], [eax], '?')
+ remap_frame_layout(assembler, [c3], [eax], '?')
assert assembler.ops == [('mov', c3, eax)]
assembler = MockAssembler()
- s12 = stack_pos(12, 1)
- remap_stack_layout(assembler, [c3], [s12], '?')
+ s12 = frame_pos(12, 1)
+ remap_frame_layout(assembler, [c3], [s12], '?')
assert assembler.ops == [('mov', c3, s12)]
def test_constants_and_cycle():
assembler = MockAssembler()
c3 = imm(3)
- s12 = stack_pos(13, 1)
- remap_stack_layout(assembler, [ebx, c3, s12],
+ s12 = frame_pos(13, 1)
+ remap_frame_layout(assembler, [ebx, c3, s12],
[s12, eax, ebx], edi)
assert assembler.ops == [('mov', c3, eax),
('push', s12),
Modified: pypy/trunk/pypy/jit/backend/x86/test/test_recompilation.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_recompilation.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_recompilation.py Tue Dec 8 16:49:12 2009
@@ -33,7 +33,8 @@
jump(i1)
'''
loop = self.interpret(ops, [0])
- previous = loop.token._x86_stack_depth
+ previous = loop.token._x86_frame_depth
+ assert loop.token._x86_param_depth == 0
assert self.getint(0) == 20
ops = '''
[i1]
@@ -48,7 +49,8 @@
'''
bridge = self.attach_bridge(ops, loop, -2)
descr = loop.operations[2].descr
- new = descr._x86_bridge_stack_depth
+ new = descr._x86_bridge_frame_depth
+ assert descr._x86_bridge_param_depth == 0
assert new > previous
self.cpu.set_future_value_int(0, 0)
fail = self.run(loop)
@@ -107,8 +109,10 @@
'''
bridge = self.attach_bridge(ops, loop, 5, looptoken=loop.token)
guard_op = loop.operations[5]
- loop_stack_depth = loop.token._x86_stack_depth
- assert guard_op.descr._x86_bridge_stack_depth > loop_stack_depth
+ loop_frame_depth = loop.token._x86_frame_depth
+ assert loop.token._x86_param_depth == 0
+ assert guard_op.descr._x86_bridge_frame_depth > loop_frame_depth
+ assert guard_op.descr._x86_bridge_param_depth == 0
self.cpu.set_future_value_int(0, 0)
self.cpu.set_future_value_int(1, 0)
self.cpu.set_future_value_int(2, 0)
Modified: pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_regalloc.py Tue Dec 8 16:49:12 2009
@@ -85,6 +85,20 @@
fdescr2 = BasicFailDescr(2)
fdescr3 = BasicFailDescr(3)
+ def f1(x):
+ return x+1
+
+ def f2(x, y):
+ return x*y
+
+ F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
+ F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*2, lltype.Signed))
+ f1ptr = llhelper(F1PTR, f1)
+ f2ptr = llhelper(F2PTR, f2)
+
+ f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT)
+ f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT)
+
namespace = locals().copy()
type_system = 'lltype'
@@ -522,3 +536,73 @@
'''
loop = self.interpret(ops, [0.0, .1, .2, .3, .4, .5, .6, .7, .8, .9])
assert self.getints(9) == [0, 1, 1, 1, 1, 1, 1, 1, 1]
+
+class TestRegAllocCallAndStackDepth(BaseTestRegalloc):
+
+ def test_one_call(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+ i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+ finish(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ '''
+ loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9, 9])
+ assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9]
+ assert loop.token._x86_param_depth == 1
+
+ def test_two_calls(self):
+ ops = '''
+ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+ i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+ i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)
+ finish(i11, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+ '''
+ loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9, 9])
+ assert self.getints(11) == [5*7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9]
+ assert loop.token._x86_param_depth == 2
+
+ def test_bridge_calls_1(self):
+ ops = '''
+ [i0, i1]
+ i2 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
+ guard_value(i2, 0, descr=fdescr1) [i2, i1]
+ finish(i1)
+ '''
+ loop = self.interpret(ops, [4, 7])
+ assert self.getint(0) == 5
+ ops = '''
+ [i2, i1]
+ i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)
+ finish(i3, descr=fdescr2)
+ '''
+ bridge = self.attach_bridge(ops, loop, -2)
+
+ assert loop.operations[-2].descr._x86_bridge_param_depth == 2
+
+ self.cpu.set_future_value_int(0, 4)
+ self.cpu.set_future_value_int(1, 7)
+ self.run(loop)
+ assert self.getint(0) == 5*7
+
+ def test_bridge_calls_2(self):
+ ops = '''
+ [i0, i1]
+ i2 = call(ConstClass(f2ptr), i0, i1, descr=f2_calldescr)
+ guard_value(i2, 0, descr=fdescr1) [i2]
+ finish(i1)
+ '''
+ loop = self.interpret(ops, [4, 7])
+ assert self.getint(0) == 4*7
+ ops = '''
+ [i2]
+ i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)
+ finish(i3, descr=fdescr2)
+ '''
+ bridge = self.attach_bridge(ops, loop, -2)
+
+ assert loop.operations[-2].descr._x86_bridge_param_depth == 2
+
+ self.cpu.set_future_value_int(0, 4)
+ self.cpu.set_future_value_int(1, 7)
+ self.run(loop)
+ assert self.getint(0) == 29
+
Modified: pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py Tue Dec 8 16:49:12 2009
@@ -14,11 +14,8 @@
from pypy.rlib.jit import JitDriver, OPTIMIZER_SIMPLE, dont_look_inside
from pypy.jit.backend.x86.runner import CPU386
from pypy.jit.backend.llsupport.gc import GcRefList, GcRootMap_asmgcc
-from pypy.jit.backend.x86.regalloc import X86StackManager
from pypy.tool.udir import udir
-stack_pos = X86StackManager.stack_pos
-
class X(object):
def __init__(self, x=0):
self.x = x
More information about the Pypy-commit
mailing list