[pypy-commit] pypy ppc-jit-backend: (bivab, hager): Implemented support for bridges.

hager noreply at buildbot.pypy.org
Fri Oct 21 11:45:55 CEST 2011


Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r48301:e944a8524e86
Date: 2011-10-21 11:45 +0200
http://bitbucket.org/pypy/pypy/changeset/e944a8524e86/

Log:	(bivab, hager): Implemented support for bridges.

diff --git a/pypy/jit/backend/ppc/ppcgen/opassembler.py b/pypy/jit/backend/ppc/ppcgen/opassembler.py
--- a/pypy/jit/backend/ppc/ppcgen/opassembler.py
+++ b/pypy/jit/backend/ppc/ppcgen/opassembler.py
@@ -201,12 +201,11 @@
             curpos = self.mc.get_rel_pos()
             self.mc.b(descr._ppc_loop_code - curpos)
         else:
-            assert 0, "case not implemented yet"
+            target = descr._ppc_bootstrap_code + descr._ppc_loop_code
+            self.mc.b_abs(target)
+            new_fd = max(regalloc.frame_manager.frame_depth,
+                         descr._ppc_frame_manager_depth)
+            regalloc.frame_manager.frame_depth = new_fd
 
     def nop(self):
         self.mc.ori(0, 0, 0)
-
-    def branch_abs(self, address):
-        self.load_imm(r.r0.value, address)
-        self.mc.mtctr(0)
-        self.mc.bctr()
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
@@ -261,6 +261,37 @@
         self.fail_force_index = spp_loc
         return descr
 
+    def decode_inputargs(self, enc, inputargs, regalloc):
+        locs = []
+        j = 0
+        for i in range(len(inputargs)):
+            res = enc[j]
+            if res == self.END_OF_LOCS:
+                assert 0, 'reached end of encoded area'
+            while res == self.EMPTY_LOC:
+                j += 1
+                res = enc[j]
+
+            assert res in [self.INT_TYPE, self.REF_TYPE],\
+                    'location type is not supported'
+            res_type = res
+            j += 1
+            res = enc[j]
+            if res == self.IMM_LOC:
+                # XXX decode imm if necessary
+                assert 0, 'Imm Locations are not supported'
+            elif res == self.STACK_LOC:
+                stack_loc = decode32(enc, j+1)
+                loc = regalloc.frame_manager.frame_pos(stack_loc, INT)
+                j += 4
+            else: # REG_LOC
+                #loc = r.all_regs[ord(res)]
+                #import pdb; pdb.set_trace()
+                loc = r.MANAGED_REGS[ord(res) - 2]
+            j += 1
+            locs.append(loc)
+        return locs
+
     def _gen_leave_jitted_hook_code(self, save_exc=False):
         mc = PPCBuilder()
 
@@ -390,14 +421,40 @@
 
         start_pos = self.mc.currpos()
         self.framesize = frame_depth = self.compute_frame_depth(regalloc)
+        looptoken._ppc_frame_manager_depth = regalloc.frame_manager.frame_depth
         self._make_prologue(regalloc_head, frame_depth)
      
         self.write_pending_failure_recoveries()
         loop_start = self.materialize_loop(looptoken, False)
+        looptoken._ppc_bootstrap_code = loop_start
         looptoken.ppc_code = loop_start + start_pos
         self.process_pending_guards(loop_start)
         self._teardown()
 
+    def assemble_bridge(self, faildescr, inputargs, operations, looptoken, log):
+        self.setup(looptoken, operations)
+        assert isinstance(faildescr, AbstractFailDescr)
+        code = faildescr._failure_recovery_code
+        enc = rffi.cast(rffi.CCHARP, code)
+        longevity = compute_vars_longevity(inputargs, operations)
+        regalloc = Regalloc(longevity, assembler=self, 
+                            frame_manager=PPCFrameManager())
+
+        #sp_patch_location = self._prepare_sp_patch_position()
+        frame_depth = faildescr._ppc_frame_depth
+        locs = self.decode_inputargs(enc, inputargs, regalloc)
+        regalloc.update_bindings(locs, frame_depth, inputargs)
+
+        self._walk_operations(operations, regalloc)
+
+        #self._patch_sp_offset(sp_patch_location, 
+        #                      regalloc.frame_manager.frame_depth)
+        self.write_pending_failure_recoveries()
+        bridge_start = self.materialize_loop(looptoken, False)
+        self.process_pending_guards(bridge_start)
+        self.patch_trace(faildescr, looptoken, bridge_start, regalloc)
+        self._teardown()
+
     # For an explanation of the encoding, see
     # backend/arm/assembler.py
     def gen_descr_encoding(self, descr, args, arglocs):
@@ -516,7 +573,7 @@
             path = self._leave_jitted_hook_save_exc
         else:
             path = self._leave_jitted_hook
-        self.branch_abs(path)
+        self.mc.b_abs(path)
         return memaddr
 
     def process_pending_guards(self, block_start):
@@ -535,6 +592,15 @@
             else:
                 assert 0, "not implemented yet"
 
+    def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc):
+        # The first instruction (word) is not overwritten, because it is the
+        # one that actually checks the condition
+        mc = PPCBuilder()
+        patch_addr = faildescr._ppc_block_start + faildescr._ppc_guard_pos
+        mc.b_abs(bridge_addr)
+        mc.prepare_insts_blocks()
+        mc.copy_to_raw_memory(patch_addr)
+
     def get_asmmemmgr_blocks(self, looptoken):
         clt = looptoken.compiled_loop_token
         if clt.asmmemmgr_blocks is None:
diff --git a/pypy/jit/backend/ppc/ppcgen/regalloc.py b/pypy/jit/backend/ppc/ppcgen/regalloc.py
--- a/pypy/jit/backend/ppc/ppcgen/regalloc.py
+++ b/pypy/jit/backend/ppc/ppcgen/regalloc.py
@@ -120,6 +120,31 @@
         self.possibly_free_vars(inputargs)
         return nonfloatlocs
 
+    def update_bindings(self, locs, frame_depth, inputargs):
+        used = {}
+        i = 0
+        self.frame_manager.frame_depth = frame_depth
+        for loc in locs:
+            arg = inputargs[i]
+            i += 1
+            if loc.is_reg():
+                self.rm.reg_bindings[arg] = loc
+            elif loc.is_vfp_reg():
+                self.vfprm.reg_bindings[arg] = loc
+            else:
+                assert loc.is_stack()
+                self.frame_manager.frame_bindings[arg] = loc
+            used[loc] = None
+
+        # XXX combine with x86 code and move to llsupport
+        self.rm.free_regs = []
+        for reg in self.rm.all_regs:
+            if reg not in used:
+                self.rm.free_regs.append(reg)
+        # note: we need to make a copy of inputargs because possibly_free_vars
+        # is also used on op args, which is a non-resizable list
+        self.possibly_free_vars(list(inputargs))
+
     def possibly_free_var(self, var):
         self.rm.possibly_free_var(var)
 


More information about the pypy-commit mailing list