[pypy-commit] pypy arm-backend-2: implement chages to the frame manager

bivab noreply at buildbot.pypy.org
Thu Dec 29 09:57:34 CET 2011


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r50945:57c6036823fe
Date: 2011-12-27 16:06 +0100
http://bitbucket.org/pypy/pypy/changeset/57c6036823fe/

Log:	implement chages to the frame manager

diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -87,6 +87,7 @@
         assert self.memcpy_addr != 0, 'setup_once() not called?'
         self.mc = ARMv7Builder()
         self.pending_guards = []
+        self.currently_compiling_loop = None
         assert self.datablockwrapper is None
         allblocks = self.get_asmmemmgr_blocks(looptoken)
         self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
@@ -98,6 +99,7 @@
         self._regalloc = None
         self.mc = None
         self.pending_guards = None
+        self.currently_compiling_loop = None
         assert self.datablockwrapper is None
 
     def setup_once(self):
@@ -641,6 +643,7 @@
         looptoken.compiled_loop_token = clt
 
         operations = self.setup(looptoken, operations)
+        self.currently_compiling_loop = looptoken
         self._dump(operations)
 
         self.align()
@@ -656,9 +659,9 @@
         looptoken._arm_loop_code = loop_head
         looptoken._arm_bootstrap_code = 0
 
-        self._walk_operations(operations, regalloc)
-
-        looptoken._arm_frame_depth = regalloc.frame_manager.frame_depth
+        looptoken._arm_frame_depth = -1
+        frame_depth = self._assemble(operations, regalloc)
+        looptoken._arm_frame_depth = frame_depth
         self._patch_sp_offset(sp_patch_location, looptoken._arm_frame_depth)
 
         self.align()
@@ -679,6 +682,15 @@
             print 'Done assembling loop with token %r' % looptoken
         self.teardown()
 
+    def _assemble(self, operations, regalloc):
+        regalloc.compute_hint_frame_locations(operations)
+        self._walk_operations(operations, regalloc)
+        frame_depth = regalloc.frame_manager.get_frame_depth()
+        jump_target_descr = regalloc.jump_target_descr
+        if jump_target_descr is not None:
+            frame_depth = max(frame_depth, jump_target_descr._arm_frame_depth)
+        return frame_depth
+
     def assemble_bridge(self, faildescr, inputargs, operations,
                                                     original_loop_token, log):
         operations = self.setup(original_loop_token, operations)
@@ -692,14 +704,13 @@
             assert len(inputargs) == len(arglocs)
 
         regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
-        regalloc.prepare_bridge(frame_depth, inputargs, arglocs, operations)
+        regalloc.prepare_bridge(inputargs, arglocs, operations)
 
         sp_patch_location = self._prepare_sp_patch_position()
 
-        self._walk_operations(operations, regalloc)
+        frame_depth = self._assemble(operations, regalloc)
 
-        self._patch_sp_offset(sp_patch_location,
-                                regalloc.frame_manager.frame_depth)
+        self._patch_sp_offset(sp_patch_location, frame_depth)
 
         self.write_pending_failure_recoveries()
         bridge_start = self.materialize_loop(original_loop_token)
@@ -713,6 +724,10 @@
             self.cpu.total_compiled_bridges)
         self.teardown()
 
+
+    def target_arglocs(self, loop_token):
+        return loop_token._arm_arglocs
+
     def materialize_loop(self, looptoken):
         self.datablockwrapper.done()      # finish using cpu.asmmemmgr
         self.datablockwrapper = None
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -309,14 +309,11 @@
         assert fcond == c.AL
 
         self._insert_checks()
-        if descr._arm_bootstrap_code == 0:
+        if descr is self.currently_compiling_loop:
             self.mc.B_offs(descr._arm_loop_code, fcond)
         else:
             target = descr._arm_bootstrap_code + descr._arm_loop_code
             self.mc.B(target, fcond)
-            new_fd = max(regalloc.frame_manager.frame_depth,
-                                                descr._arm_frame_depth)
-            regalloc.frame_manager.frame_depth = new_fd
         return fcond
 
     def emit_op_finish(self, op, arglocs, regalloc, fcond):
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -51,7 +51,9 @@
 
     def __init__(self):
         FrameManager.__init__(self)
-        self.frame_depth = 1
+        self.used = [True]  # keep first slot free
+        # XXX refactor frame to avoid this issue of keeping the first slot
+        # reserved
 
     @staticmethod
     def frame_pos(loc, type):
@@ -70,6 +72,13 @@
             return  2
         return 1
 
+    @staticmethod
+    def get_loc_index(loc):
+        assert loc.is_stack()
+        if loc.type == FLOAT:
+            return loc.position - 1
+        else:
+            return loc.position
 
 def void(self, op, fcond):
     return []
@@ -182,6 +191,7 @@
         self.cpu = assembler.cpu
         self.assembler = assembler
         self.frame_manager = frame_manager
+        self.jump_target_descr = None
 
     def loc(self, var):
         if var.type == FLOAT:
@@ -291,9 +301,9 @@
         useful = self._prepare(inputargs, operations)
         return self._process_inputargs(inputargs, useful)
 
-    def prepare_bridge(self, frame_depth, inputargs, arglocs, ops):
+    def prepare_bridge(self, inputargs, arglocs, ops):
         self._prepare(inputargs, ops)
-        self._update_bindings(arglocs, frame_depth, inputargs)
+        self._update_bindings(arglocs, inputargs)
 
     def _process_inputargs(self, inputargs, useful):
         floatlocs = [None] * len(inputargs)
@@ -313,10 +323,9 @@
         self.possibly_free_vars(list(inputargs))
         return nonfloatlocs, floatlocs
 
-    def _update_bindings(self, locs, frame_depth, inputargs):
+    def _update_bindings(self, locs, inputargs):
         used = {}
         i = 0
-        self.frame_manager.frame_depth = frame_depth
         for loc in locs:
             arg = inputargs[i]
             i += 1
@@ -326,7 +335,7 @@
                 self.vfprm.reg_bindings[arg] = loc
             else:
                 assert loc.is_stack()
-                self.frame_manager.frame_bindings[arg] = loc
+                self.frame_manager.set_binding(arg, loc)
             used[loc] = None
 
         # XXX combine with x86 code and move to llsupport
@@ -519,7 +528,7 @@
     def _prepare_guard(self, op, args=None):
         if args is None:
             args = []
-        args.append(imm(self.frame_manager.frame_depth))
+        args.append(imm(self.frame_manager.get_frame_depth()))
         for arg in op.getfailargs():
             if arg:
                 args.append(self.loc(arg))
@@ -613,10 +622,34 @@
 
         return arglocs
 
+    def compute_hint_frame_locations(self, operations):
+        # optimization only: fill in the 'hint_frame_locations' dictionary
+        # of rm and xrm based on the JUMP at the end of the loop, by looking
+        # at where we would like the boxes to be after the jump.
+        op = operations[-1]
+        if op.getopnum() != rop.JUMP:
+            return
+        descr = op.getdescr()
+        assert isinstance(descr, LoopToken)
+        nonfloatlocs, floatlocs = self.assembler.target_arglocs(descr)
+        for i in range(op.numargs()):
+            box = op.getarg(i)
+            if isinstance(box, Box):
+                loc = nonfloatlocs[i]
+                if loc is not None and loc.is_stack():
+                    assert box.type != FLOAT
+                    self.frame_manager.hint_frame_locations[box] = loc
+                else:
+                    loc = floatlocs[i]
+                    if loc is not None and loc.is_stack():
+                        assert box.type == FLOAT
+                        self.frame_manager.hint_frame_locations[box] = loc
+
     def prepare_op_jump(self, op, fcond):
         descr = op.getdescr()
         assert isinstance(descr, LoopToken)
-        nonfloatlocs, floatlocs = descr._arm_arglocs
+        self.jump_target_descr = descr
+        nonfloatlocs, floatlocs = self.assembler.target_arglocs(descr)
 
         # get temporary locs
         tmploc = r.ip
@@ -940,7 +973,7 @@
 
     def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
         shape = gcrootmap.get_basic_shape(False)
-        for v, val in self.frame_manager.frame_bindings.items():
+        for v, val in self.frame_manager.bindings.items():
             if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
                 assert val.is_stack()
                 gcrootmap.add_frame_offset(shape, val.position * -WORD)


More information about the pypy-commit mailing list