[pypy-commit] pypy arm-backend-2: Add a method to allocate a scratch register that is managed by the register manager. The register manager keeps a list of temporary boxes that need to freed before before emitting the next operation

bivab noreply at buildbot.pypy.org
Wed Nov 16 14:14:57 CET 2011


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r49468:66a82d2d9786
Date: 2011-11-16 13:58 +0100
http://bitbucket.org/pypy/pypy/changeset/66a82d2d9786/

Log:	Add a method to allocate a scratch register that is managed by the
	register manager. The register manager keeps a list of temporary
	boxes that need to freed before before emitting the next operation

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
@@ -813,6 +813,7 @@
             if op.result:
                 regalloc.possibly_free_var(op.result)
             regalloc.possibly_free_vars_for_op(op)
+            regalloc.free_temp_vars()
             regalloc._check_invariants()
 
     # from ../x86/regalloc.py
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
@@ -84,6 +84,13 @@
         self._check_type(v)
         r = self.force_allocate_reg(v)
         return r
+    def get_scratch_reg(self, type=FLOAT, forbidden_vars=[], selected_reg=None):
+        assert type == FLOAT # for now
+        box = TempFloat()
+        self.temp_boxes.append(box)
+        return self.force_allocate_reg(box, forbidden_vars=forbidden_vars, selected_reg=selected_reg)
+
+
 class ARMv7RegisterMananger(RegisterManager):
     all_regs              = r.all_regs
     box_types             = None       # or a list of acceptable types
@@ -115,6 +122,12 @@
             assert isinstance(c, ConstPtr)
             return locations.ImmLocation(rffi.cast(lltype.Signed, c.value))
     
+    def get_scratch_reg(self, type=INT, forbidden_vars=[], selected_reg=None):
+        assert type == INT or type == REF
+        box = TempBox()
+        self.temp_boxes.append(box)
+        return self.force_allocate_reg(box, forbidden_vars=forbidden_vars, selected_reg=selected_reg)
+
 class Regalloc(object):
 
     def __init__(self, longevity, frame_manager=None, assembler=None):
@@ -191,6 +204,16 @@
             if var is not None: # xxx kludgy
                 self.possibly_free_var(var)
 
+    def get_scratch_reg(self, type, forbidden_vars=[], selected_reg=None):
+        if type == FLOAT:
+            return self.vfprm.get_scratch_reg(type, forbidden_vars, selected_reg)
+        else:
+            return self.rm.get_scratch_reg(type, forbidden_vars, selected_reg)
+
+    def free_temp_vars(self):
+        self.rm.free_temp_vars()
+        self.vfprm.free_temp_vars()
+
     def make_sure_var_in_reg(self, var, forbidden_vars=[],
                          selected_reg=None, need_lower_byte=False):
         if var.type == FLOAT:
@@ -668,11 +691,9 @@
         if _check_imm_arg(c_ofs):
             ofs_loc = imm(ofs)
         else:
-            ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, [base_box, index_box])
-            self.possibly_free_var(ofs_box)
-        self.possibly_free_vars(args)
-        self.possibly_free_var(base_box)
-        self.possibly_free_var(index_box)
+            ofs_loc = self._ensure_value_is_boxed(c_ofs, args)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         result_loc = self.force_allocate_reg(op.result)
         return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs), 
                                         imm(itemsize), imm(fieldsize)]
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
@@ -59,6 +59,7 @@
     no_lower_byte_regs    = []
     save_around_call_regs = []
     frame_reg             = None
+    temp_boxes            = []
 
     def __init__(self, longevity, frame_manager=None, assembler=None):
         self.free_regs = self.all_regs[:]
@@ -101,6 +102,10 @@
         for i in range(op.numargs()):
             self.possibly_free_var(op.getarg(i))
 
+    def free_temp_vars(self):
+        self.possibly_free_vars(self.temp_boxes)
+        self.temp_boxes = []
+
     def _check_invariants(self):
         if not we_are_translated():
             # make sure no duplicates
@@ -111,6 +116,7 @@
             assert len(rev_regs) + len(self.free_regs) == len(self.all_regs)
         else:
             assert len(self.reg_bindings) + len(self.free_regs) == len(self.all_regs)
+        assert len(self.temp_boxes) == 0
         if self.longevity:
             for v in self.reg_bindings:
                 assert self.longevity[v][1] > self.position
@@ -383,6 +389,10 @@
         """
         raise NotImplementedError("Abstract")
 
+    def get_scratch_reg(self, forbidden_vars=[]):
+        """ Platform specific - Allocates a temporary register """
+        raise NotImplementedError("Abstract")
+
 def compute_vars_longevity(inputargs, operations):
     # compute a dictionary that maps variables to index in
     # operations that is a "last-time-seen"


More information about the pypy-commit mailing list