[pypy-commit] pypy arm-backend-2: update backend to new interface provided by compute_vars_longevity

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


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r50943:4a920a79a182
Date: 2011-12-27 14:10 +0100
http://bitbucket.org/pypy/pypy/changeset/4a920a79a182/

Log:	update backend to new interface provided by compute_vars_longevity

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
@@ -14,7 +14,6 @@
                     operations as regalloc_operations,
                     operations_with_guard as regalloc_operations_with_guard)
 from pypy.jit.backend.arm.jump import remap_frame_layout
-from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity
 from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
 from pypy.jit.backend.model import CompiledLoopToken
 from pypy.jit.codewriter import longlong
@@ -277,7 +276,7 @@
         self.fail_force_index = frame_loc
         return descr
 
-    def decode_inputargs(self, enc, regalloc):
+    def decode_inputargs(self, enc):
         locs = []
         j = 0
         while enc[j] != self.END_OF_LOCS:
@@ -302,7 +301,7 @@
                 else:
                     t = REF
                 stack_loc = decode32(enc, j + 1)
-                loc = regalloc.frame_manager.frame_pos(stack_loc, t)
+                loc = ARMFrameManager.frame_pos(stack_loc, t)
                 j += 4
             else:  # REG_LOC
                 if res_type == self.FLOAT_TYPE:
@@ -509,7 +508,8 @@
         mc.SUB_ri(r.r5.value, r.r4.value, imm=2 * WORD)  # ADD r5, r4 [2*WORD]
         mc.STR_ri(r.r5.value, r.ip.value)
 
-    def gen_bootstrap_code(self, nonfloatlocs, floatlocs, inputargs):
+    def gen_bootstrap_code(self, arglocs, inputargs):
+        nonfloatlocs, floatlocs = arglocs
         for i in range(len(nonfloatlocs)):
             loc = nonfloatlocs[i]
             if loc is None:
@@ -636,24 +636,21 @@
 
     # cpu interface
     def assemble_loop(self, inputargs, operations, looptoken, log):
-
         clt = CompiledLoopToken(self.cpu, looptoken.number)
         clt.allgcrefs = []
         looptoken.compiled_loop_token = clt
 
         operations = self.setup(looptoken, operations)
         self._dump(operations)
-        longevity = compute_vars_longevity(inputargs, operations)
-        regalloc = Regalloc(longevity, assembler=self,
-                                frame_manager=ARMFrameManager())
 
         self.align()
         self.gen_func_prolog()
         sp_patch_location = self._prepare_sp_patch_position()
-        nonfloatlocs, floatlocs = regalloc.prepare_loop(inputargs,
-                                                operations, looptoken)
-        self.gen_bootstrap_code(nonfloatlocs, floatlocs, inputargs)
-        looptoken._arm_arglocs = [nonfloatlocs, floatlocs]
+
+        regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
+        arglocs = regalloc.prepare_loop(inputargs, operations)
+        self.gen_bootstrap_code(arglocs, inputargs)
+        looptoken._arm_arglocs = arglocs
         loop_head = self.mc.currpos()
 
         looptoken._arm_loop_code = loop_head
@@ -689,15 +686,15 @@
         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=ARMFrameManager())
+        frame_depth = faildescr._arm_frame_depth
+        arglocs = self.decode_inputargs(enc)
+        if not we_are_translated():
+            assert len(inputargs) == len(arglocs)
+
+        regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
+        regalloc.prepare_bridge(frame_depth, inputargs, arglocs, operations)
 
         sp_patch_location = self._prepare_sp_patch_position()
-        frame_depth = faildescr._arm_frame_depth
-        locs = self.decode_inputargs(enc, regalloc)
-        assert len(inputargs) == len(locs)
-        regalloc.update_bindings(locs, frame_depth, inputargs)
 
         self._walk_operations(operations, regalloc)
 
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
@@ -1,5 +1,5 @@
 from pypy.jit.backend.llsupport.regalloc import FrameManager, \
-        RegisterManager, TempBox, compute_loop_consts
+        RegisterManager, TempBox, compute_vars_longevity
 from pypy.jit.backend.arm import registers as r
 from pypy.jit.backend.arm import locations
 from pypy.jit.backend.arm.locations import imm
@@ -178,13 +178,10 @@
 
 class Regalloc(object):
 
-    def __init__(self, longevity, frame_manager=None, assembler=None):
+    def __init__(self, frame_manager=None, assembler=None):
         self.cpu = assembler.cpu
-        self.longevity = longevity
+        self.assembler = assembler
         self.frame_manager = frame_manager
-        self.assembler = assembler
-        self.vfprm = VFPRegisterManager(longevity, frame_manager, assembler)
-        self.rm = ARMv7RegisterMananger(longevity, frame_manager, assembler)
 
     def loc(self, var):
         if var.type == FLOAT:
@@ -281,15 +278,31 @@
             assert isinstance(value, ConstFloat)
             return self.vfprm.convert_to_imm(value)
 
-    def prepare_loop(self, inputargs, operations, looptoken):
-        loop_consts = compute_loop_consts(inputargs, operations[-1], looptoken)
+    def _prepare(self,  inputargs, operations):
+        longevity, useful = compute_vars_longevity(inputargs, operations)
+        self.longevity = longevity
+        fm = self.frame_manager
+        asm = self.assembler
+        self.vfprm = VFPRegisterManager(longevity, fm, asm)
+        self.rm = ARMv7RegisterMananger(longevity, fm, asm)
+        return useful
+
+    def prepare_loop(self, inputargs, operations):
+        useful = self._prepare(inputargs, operations)
+        return self._process_inputargs(inputargs, useful)
+
+    def prepare_bridge(self, frame_depth, inputargs, arglocs, ops):
+        self._prepare(inputargs, ops)
+        self._update_bindings(arglocs, frame_depth, inputargs)
+
+    def _process_inputargs(self, inputargs, useful):
         floatlocs = [None] * len(inputargs)
         nonfloatlocs = [None] * len(inputargs)
         for i in range(len(inputargs)):
             arg = inputargs[i]
             assert not isinstance(arg, Const)
             loc = inputargs[i]
-            if arg not in loop_consts and self.longevity[arg][1] > -1:
+            if self.longevity[arg][1] > -1 and arg in useful:
                 self.try_allocate_reg(loc)
 
             loc = self.loc(arg)
@@ -300,7 +313,7 @@
         self.possibly_free_vars(list(inputargs))
         return nonfloatlocs, floatlocs
 
-    def update_bindings(self, locs, frame_depth, inputargs):
+    def _update_bindings(self, locs, frame_depth, inputargs):
         used = {}
         i = 0
         self.frame_manager.frame_depth = frame_depth
diff --git a/pypy/jit/backend/arm/test/test_regalloc.py b/pypy/jit/backend/arm/test/test_regalloc.py
--- a/pypy/jit/backend/arm/test/test_regalloc.py
+++ b/pypy/jit/backend/arm/test/test_regalloc.py
@@ -3,14 +3,12 @@
 """
 
 import py
-from pypy.jit.metainterp.history import BoxInt, ConstInt,\
-     BoxPtr, ConstPtr, LoopToken, BasicFailDescr
-from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.jit.metainterp.history import BasicFailDescr
 from pypy.jit.backend.llsupport.descr import GcCache
 from pypy.jit.backend.detect_cpu import getcpuclass
-from pypy.jit.backend.arm.regalloc import Regalloc
+from pypy.jit.backend.arm.regalloc import Regalloc, ARMFrameManager
 from pypy.jit.tool.oparser import parse
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.annlowlevel import llhelper
 from pypy.rpython.lltypesystem import rclass, rstr
 from pypy.jit.codewriter.effectinfo import EffectInfo
@@ -19,6 +17,8 @@
 
 
 CPU = getcpuclass()
+
+
 class MockGcDescr(GcCache):
     def get_funcptr_for_new(self):
         return 123
@@ -29,6 +29,7 @@
     def rewrite_assembler(self, cpu, operations):
         pass
 
+
 class MockAssembler(object):
     gcrefs = None
     _float_constants = None
@@ -60,11 +61,14 @@
     def load_effective_addr(self, *args):
         self.lea.append(args)
 
+
 class RegAllocForTests(Regalloc):
     position = 0
+
     def _compute_next_usage(self, v, _):
         return -1
 
+
 class BaseTestRegalloc(object):
     cpu = CPU(None, None)
     cpu.setup_once()
@@ -138,6 +142,13 @@
             self.cpu.execute_token(loop.token)
         return loop
 
+    def prepare_loop(self, ops):
+        loop = self.parse(ops)
+        regalloc = Regalloc(assembler=self.cpu.assembler,
+        frame_manager=ARMFrameManager())
+        regalloc.prepare_loop(loop.inputargs, loop.operations)
+        return regalloc
+
     def getint(self, index):
         return self.cpu.get_latest_value_int(index)
 
@@ -411,6 +422,34 @@
         self.run(loop)
         assert self.getints(9) == range(9)
 
+    def test_loopargs(self):
+        ops = """
+        [i0, i1, i2, i3]
+        i4 = int_add(i0, i1)
+        jump(i4, i1, i2, i3)
+        """
+        regalloc = self.prepare_loop(ops)
+        assert len(regalloc.rm.reg_bindings) == 2
+
+    def test_loopargs_2(self):
+        ops = """
+        [i0, i1, i2, i3]
+        i4 = int_add(i0, i1)
+        finish(i4, i1, i2, i3)
+        """
+        regalloc = self.prepare_loop(ops)
+        assert len(regalloc.rm.reg_bindings) == 2
+
+    def test_loopargs_3(self):
+        ops = """
+        [i0, i1, i2, i3]
+        i4 = int_add(i0, i1)
+        guard_true(i4) [i0, i1, i2, i3, i4]
+        jump(i4, i1, i2, i3)
+        """
+        regalloc = self.prepare_loop(ops)
+        assert len(regalloc.rm.reg_bindings) == 2
+
 class TestRegallocCompOps(BaseTestRegalloc):
 
     def test_cmp_op_0(self):
diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py
--- a/pypy/jit/backend/llsupport/regalloc.py
+++ b/pypy/jit/backend/llsupport/regalloc.py
@@ -1,4 +1,4 @@
-
+import os
 from pypy.jit.metainterp.history import Const, Box, REF
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.jit.metainterp.resoperation import rop
@@ -393,7 +393,7 @@
         """ Platform specific - Allocates a temporary register """
         raise NotImplementedError("Abstract")
 
-def _compute_vars_longevity(self, inputargs, operations):
+def compute_vars_longevity(inputargs, operations):
     # compute a dictionary that maps variables to index in
     # operations that is a "last-time-seen"
 
@@ -443,16 +443,6 @@
     assert len(last_used) == 0
     return longevity, useful
 
-def compute_loop_consts(inputargs, jump, looptoken):
-    if jump.getopnum() != rop.JUMP or jump.getdescr() is not looptoken:
-        loop_consts = {}
-    else:
-        loop_consts = {}
-        for i in range(len(inputargs)):
-            if inputargs[i] is jump.getarg(i):
-                loop_consts[inputargs[i]] = i
-    return loop_consts
-
 
 def not_implemented(msg):
     os.write(2, '[llsupport/regalloc] %s\n' % msg)


More information about the pypy-commit mailing list