[pypy-commit] pypy ppc-jit-backend: (bivab, hager): Adjust size of FPR_SAVE_AREA on PPC64. Also, resize stackframe if bridges need more space.
hager
noreply at buildbot.pypy.org
Thu Jan 12 00:25:43 CET 2012
Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r51253:b55636b23f7a
Date: 2012-01-11 15:24 -0800
http://bitbucket.org/pypy/pypy/changeset/b55636b23f7a/
Log: (bivab, hager): Adjust size of FPR_SAVE_AREA on PPC64. Also, resize
stackframe if bridges need more space.
diff --git a/pypy/jit/backend/ppc/ppcgen/arch.py b/pypy/jit/backend/ppc/ppcgen/arch.py
--- a/pypy/jit/backend/ppc/ppcgen/arch.py
+++ b/pypy/jit/backend/ppc/ppcgen/arch.py
@@ -9,10 +9,12 @@
WORD = 4
IS_PPC_32 = True
BACKCHAIN_SIZE = 2
+ FPR_SAVE_AREA = len(NONVOLATILES_FLOAT) * DWORD
else:
WORD = 8
IS_PPC_32 = False
BACKCHAIN_SIZE = 6
+ FPR_SAVE_AREA = len(NONVOLATILES_FLOAT) * WORD
DWORD = 2 * WORD
IS_PPC_64 = not IS_PPC_32
@@ -20,8 +22,10 @@
FORCE_INDEX = WORD
GPR_SAVE_AREA = len(NONVOLATILES) * WORD
-FPR_SAVE_AREA = len(NONVOLATILES_FLOAT) * DWORD
FLOAT_INT_CONVERSION = WORD
MAX_REG_PARAMS = 8
+# we need at most 5 instructions to load a constant
+# and one instruction to patch the stack pointer
+SIZE_LOAD_IMM_PATCH_SP = 6
FORCE_INDEX_OFS = len(MANAGED_REGS) * WORD
diff --git a/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py b/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py
--- a/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py
+++ b/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py
@@ -13,7 +13,8 @@
NONVOLATILES, MAX_REG_PARAMS,
GPR_SAVE_AREA, BACKCHAIN_SIZE,
FPR_SAVE_AREA,
- FLOAT_INT_CONVERSION, FORCE_INDEX)
+ FLOAT_INT_CONVERSION, FORCE_INDEX,
+ SIZE_LOAD_IMM_PATCH_SP)
from pypy.jit.backend.ppc.ppcgen.helper.assembler import (gen_emit_cmp_op,
encode32, encode64,
decode32, decode64,
@@ -405,12 +406,13 @@
start_pos = self.mc.currpos()
looptoken._ppc_loop_code = start_pos
- clt.frame_depth = -1
- spilling_area = self._assemble(operations, regalloc)
+ clt.frame_depth = clt.param_depth = -1
+ spilling_area, param_depth = self._assemble(operations, regalloc)
clt.frame_depth = spilling_area
+ clt.param_depth = param_depth
direct_bootstrap_code = self.mc.currpos()
- frame_depth = self.compute_frame_depth(spilling_area)
+ frame_depth = self.compute_frame_depth(spilling_area, param_depth)
self.gen_bootstrap_code(start_pos, frame_depth)
self.write_pending_failure_recoveries()
@@ -439,14 +441,16 @@
regalloc.compute_hint_frame_locations(operations)
self._walk_operations(operations, regalloc)
frame_depth = regalloc.frame_manager.get_frame_depth()
+ param_depth = self.max_stack_params
jump_target_descr = regalloc.jump_target_descr
if jump_target_descr is not None:
frame_depth = max(frame_depth,
jump_target_descr._ppc_clt.frame_depth)
- return frame_depth
+ param_depth = max(param_depth,
+ jump_target_descr._ppc_clt.param_depth)
+ return frame_depth, param_depth
- # XXX stack needs to be moved if bridge needs to much space
def assemble_bridge(self, faildescr, inputargs, operations, looptoken, log):
operations = self.setup(looptoken, operations)
assert isinstance(faildescr, AbstractFailDescr)
@@ -456,22 +460,39 @@
arglocs = self.decode_inputargs(enc)
if not we_are_translated():
assert len(inputargs) == len(arglocs)
-
regalloc = Regalloc(assembler=self, frame_manager=PPCFrameManager())
regalloc.prepare_bridge(inputargs, arglocs, operations)
- spilling_area = self._assemble(operations, regalloc)
+ sp_patch_location = self._prepare_sp_patch_position()
+
+ spilling_area, param_depth = self._assemble(operations, regalloc)
+
self.write_pending_failure_recoveries()
rawstart = self.materialize_loop(looptoken, False)
self.process_pending_guards(rawstart)
self.patch_trace(faildescr, looptoken, rawstart, regalloc)
-
self.fixup_target_tokens(rawstart)
self.current_clt.frame_depth = max(self.current_clt.frame_depth,
spilling_area)
+ self.current_clt.param_depth = max(self.current_clt.param_depth, param_depth)
+ self._patch_sp_offset(sp_patch_location, rawstart)
+ if not we_are_translated():
+ print 'Loop', inputargs, operations
+ self.mc._dump_trace(rawstart, 'bridge_%s.asm' % self.cpu.total_compiled_loops)
+ print 'Done assembling bridge with token %r' % looptoken
self._teardown()
+ def _patch_sp_offset(self, sp_patch_location, rawstart):
+ mc = PPCBuilder()
+ frame_depth = self.compute_frame_depth(self.current_clt.frame_depth,
+ self.current_clt.param_depth)
+ frame_depth -= self.OFFSET_SPP_TO_OLD_BACKCHAIN
+ mc.load_imm(r.SCRATCH, -frame_depth)
+ mc.add(r.SP.value, r.SPP.value, r.SCRATCH.value)
+ mc.prepare_insts_blocks()
+ mc.copy_to_raw_memory(rawstart + sp_patch_location)
+
# For an explanation of the encoding, see
# backend/arm/assembler.py
def gen_descr_encoding(self, descr, args, arglocs):
@@ -599,8 +620,8 @@
data[1] = 0
data[2] = 0
- def compute_frame_depth(self, spilling_area):
- PARAMETER_AREA = self.max_stack_params * WORD
+ def compute_frame_depth(self, spilling_area, param_depth):
+ PARAMETER_AREA = param_depth * WORD
if IS_PPC_64:
PARAMETER_AREA += MAX_REG_PARAMS * WORD
SPILLING_AREA = spilling_area * WORD
@@ -701,6 +722,15 @@
clt.asmmemmgr_blocks = []
return clt.asmmemmgr_blocks
+ def _prepare_sp_patch_position(self):
+ """Generate NOPs as placeholder to patch the instruction(s) to update
+ the sp according to the number of spilled variables"""
+ size = SIZE_LOAD_IMM_PATCH_SP
+ l = self.mc.currpos()
+ for _ in range(size):
+ self.mc.nop()
+ return l
+
def regalloc_mov(self, prev_loc, loc):
if prev_loc.is_imm():
value = prev_loc.getint()
More information about the pypy-commit
mailing list