[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