[pypy-svn] r79999 - in pypy/branch/arm-backend/pypy/jit/backend/arm: . helper

david at codespeak.net david at codespeak.net
Sun Dec 12 14:05:51 CET 2010


Author: david
Date: Sun Dec 12 14:05:48 2010
New Revision: 79999

Modified:
   pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/helper/regalloc.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py
Log:
Improve constant loading, some related fixes and well and register allocation fixes

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py	Sun Dec 12 14:05:48 2010
@@ -375,9 +375,9 @@
         if regalloc.frame_manager.frame_depth == 1:
             return
         n = (regalloc.frame_manager.frame_depth-1)*WORD
-        self._adjust_sp(n, regalloc, cb, base_reg=r.fp)
+        self._adjust_sp(n, cb, base_reg=r.fp)
 
-    def _adjust_sp(self, n, regalloc, cb=None, fcond=c.AL, base_reg=r.sp):
+    def _adjust_sp(self, n, cb=None, fcond=c.AL, base_reg=r.sp):
         if cb is None:
             cb = self.mc
         if n < 0:
@@ -391,14 +391,11 @@
             else:
                 cb.SUB_ri(r.sp.value, base_reg.value, n)
         else:
-            b = TempBox()
-            reg = regalloc.force_allocate_reg(b)
-            cb.gen_load_int(reg.value, n, cond=fcond)
+            cb.gen_load_int(r.ip.value, n, cond=fcond)
             if rev:
                 cb.ADD_rr(r.sp.value, base_reg.value, reg.value, cond=fcond)
             else:
                 cb.SUB_rr(r.sp.value, base_reg.value, reg.value, cond=fcond)
-            regalloc.possibly_free_var(b)
 
     def _walk_operations(self, operations, regalloc):
         fcond=c.AL

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/codebuilder.py	Sun Dec 12 14:05:48 2010
@@ -120,18 +120,18 @@
     def currpos(self):
         return self._pos
 
-    size_of_gen_load_int = 7 * WORD
+    size_of_gen_load_int = 4 * WORD
+    #XXX use MOV_ri if value fits in imm
     def gen_load_int(self, r, value, cond=cond.AL):
         """r is the register number, value is the value to be loaded to the
         register"""
-        assert r != reg.ip.value, 'ip is used to load int'
-        ip = reg.ip.value
-
         self.MOV_ri(r, (value & 0xFF), cond=cond)
-        for offset in range(8, 25, 8):
-            t = (value >> offset) & 0xFF
-            self.MOV_ri(ip, t, cond=cond)
-            self.ORR_rr(r, r, ip, offset, cond=cond)
+        for offset, shift in zip(range(8, 25, 8), range(12, 0, -4)):
+            b = (value >> offset) & 0xFF
+            if b == 0:
+                continue
+            t = b | (shift << 8)
+            self.ORR_ri(r, r, imm=t, cond=cond)
 
 
 class ARMv7InMemoryBuilder(AbstractARMv7Builder):

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/helper/regalloc.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/helper/regalloc.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/helper/regalloc.py	Sun Dec 12 14:05:48 2010
@@ -49,10 +49,13 @@
         arg2 = self.make_sure_var_in_reg(a1, selected_reg=r.r1)
         assert arg1 == r.r0
         assert arg2 == r.r1
+        spilled = False
         if isinstance(a0, Box) and self.stays_alive(a0):
+            spilled = True
             self.force_spill_var(a0)
         self.after_call(op.result)
-        self.possibly_free_var(a0)
+        if spilled:
+            self.possibly_free_var(a0)
         self.possibly_free_var(a1)
         self.possibly_free_var(op.result)
         return []

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py	Sun Dec 12 14:05:48 2010
@@ -280,7 +280,7 @@
         if n_args > 4:
             stack_args = n_args - 4
             n = stack_args*WORD
-            self._adjust_sp(n, regalloc, fcond=fcond)
+            self._adjust_sp(n, fcond=fcond)
             for i in range(4, n_args):
                 reg, box = regalloc._ensure_value_is_boxed(args[i], regalloc)
                 self.mc.STR_ri(reg.value, r.sp.value, (i-4)*WORD)
@@ -293,7 +293,7 @@
         # readjust the sp in case we passed some args on the stack
         if n_args > 4:
             assert n > 0
-            self._adjust_sp(-n, regalloc, fcond=fcond)
+            self._adjust_sp(-n, fcond=fcond)
 
         # restore the argumets stored on the stack
         if spill_all_regs:
@@ -653,12 +653,10 @@
         assert value <= 0xff
 
         # check value
-        t = TempBox()
-        #XXX is this correct?
+        loc, t = regalloc._ensure_value_is_boxed(ConstInt(value))
         resloc = regalloc.force_allocate_reg(resbox)
-        loc = regalloc.force_allocate_reg(t)
-        self.mc.gen_load_int(loc.value, value)
-        self.mc.CMP_rr(resloc.value, loc.value)
+        self.mc.gen_load_int(r.ip.value, value)
+        self.mc.CMP_rr(resloc.value, r.ip.value)
         regalloc.possibly_free_var(resbox)
 
         fast_jmp_pos = self.mc.currpos()
@@ -702,8 +700,7 @@
 
         if op.result is not None:
             # load the return value from fail_boxes_xxx[0]
-            loc = regalloc.force_allocate_reg(t)
-            resloc = regalloc.force_allocate_reg(op.result, [t])
+            resloc = regalloc.force_allocate_reg(op.result)
             kind = op.result.type
             if kind == INT:
                 adr = self.fail_boxes_int.get_addr_for_num(0)
@@ -711,9 +708,8 @@
                 adr = self.fail_boxes_ptr.get_addr_for_num(0)
             else:
                 raise AssertionError(kind)
-            self.mc.gen_load_int(loc.value, adr)
-            self.mc.LDR_ri(resloc.value, loc.value)
-            regalloc.possibly_free_var(t)
+            self.mc.gen_load_int(r.ip.value, adr)
+            self.mc.LDR_ri(resloc.value, r.ip.value)
 
         offset = self.mc.currpos() - jmp_pos
         pmc = ARMv7InMemoryBuilder(jmp_location, WORD)
@@ -737,9 +733,9 @@
         self._emit_guard(guard_op, arglocs, c.GE)
         return fcond
 
-    def _write_fail_index(self, fail_index, temp_reg):
-        self.mc.gen_load_int(temp_reg.value, fail_index)
-        self.mc.STR_ri(temp_reg.value, r.fp.value)
+    def _write_fail_index(self, fail_index):
+        self.mc.gen_load_int(r.ip.value, fail_index)
+        self.mc.STR_ri(r.ip.value, r.fp.value)
 
 class AllocOpAssembler(object):
 
@@ -771,23 +767,17 @@
         callargs = arglocs[:-1]
         self._emit_call(self.malloc_func_addr, callargs,
                                 regalloc, result=op.result)
-        self.set_vtable(op.result, classint, regalloc)
+        self.set_vtable(op.result, classint)
         #XXX free args here, because _emit_call works on regalloc
         regalloc.possibly_free_vars(callargs)
         regalloc.possibly_free_var(op.result)
         return fcond
 
-    def set_vtable(self, box, vtable, regalloc):
+    def set_vtable(self, box, vtable):
         if self.cpu.vtable_offset is not None:
-            loc = regalloc.loc(box) # r0
-            assert loc is r.r0
             adr = rffi.cast(lltype.Signed, vtable)
-            t = TempBox()
-            loc_vtable = regalloc.force_allocate_reg(t, [box])
-            assert loc_vtable is not loc
-            regalloc.possibly_free_var(t)
-            self.mc.gen_load_int(loc_vtable.value, adr)
-            self.mc.STR_ri(loc_vtable.value, loc.value, self.cpu.vtable_offset)
+            self.mc.gen_load_int(r.ip.value, adr)
+            self.mc.STR_ri(r.ip.value, r.r0.value, self.cpu.vtable_offset)
 
     def emit_op_new_array(self, op, arglocs, regalloc, fcond):
         value_loc, base_loc, ofs_length = arglocs

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/regalloc.py	Sun Dec 12 14:05:48 2010
@@ -79,28 +79,14 @@
         # is also used on op args, which is a non-resizable list
         self.possibly_free_vars(list(inputargs))
 
-    #XXX remove
-    def force_allocate_reg(self, v, forbidden_vars=[], selected_reg=None,
-                           need_lower_byte=False):
-        # override ../llsupport/regalloc.py to set longevity for vals not in longevity
-        self._check_type(v)
-        if isinstance(v, TempBox) or v not in self.longevity:
-            self.longevity[v] = (self.position, self.position)
-        loc = self.try_allocate_reg(v, selected_reg,
-                                    need_lower_byte=need_lower_byte)
-        if loc:
-            return loc
-        loc = self._spill_var(v, forbidden_vars, selected_reg,
-                              need_lower_byte=need_lower_byte)
-        prev_loc = self.reg_bindings.get(v, None)
-        if prev_loc is not None:
-            self.free_regs.append(prev_loc)
-        self.reg_bindings[v] = loc
-        return loc
-
     def force_spill_var(self, var):
         self._sync_var(var)
-        del self.reg_bindings[var]
+        try:
+            loc = self.reg_bindings[var]
+            del self.reg_bindings[var]
+            self.free_regs.append(loc)
+        except KeyError:
+            import pdb; pdb.set_trace()
 
     def _check_imm_arg(self, arg, size=0xFF, allow_zero=True):
         if isinstance(arg, ConstInt):
@@ -112,8 +98,6 @@
         return False
 
     def _ensure_value_is_boxed(self, thing, forbidden_vars=[]):
-        # XXX create TempBox subclasses with the corresponding type flags and
-        # remove the overridden force_allocate_reg once done
         box = None
         loc = None
         if isinstance(thing, Const):
@@ -207,13 +191,13 @@
         boxes.append(box)
         reg2, box = self._ensure_value_is_boxed(a1,forbidden_vars=boxes)
         boxes.append(box)
-        self.possibly_free_vars(boxes)
         res = self.force_allocate_reg(op.result, boxes)
 
         args.append(reg1)
         args.append(reg2)
         args.append(res)
         args = self._prepare_guard(guard, args)
+        self.possibly_free_vars(boxes)
         self.possibly_free_var(op.result)
         return args
 
@@ -305,9 +289,10 @@
             boxes.append(box)
         else:
             l1 = self.make_sure_var_in_reg(a1)
-        self.possibly_free_vars(boxes)
         assert op.result is None
-        return  self._prepare_guard(op, [l0, l1])
+        arglocs = self._prepare_guard(op, [l0, l1])
+        self.possibly_free_vars(boxes)
+        return arglocs
 
     def prepare_op_guard_no_overflow(self, op, fcond):
         return  self._prepare_guard(op)
@@ -327,16 +312,19 @@
             boxes.append(resloc)
         else:
             resloc = None
-        self.possibly_free_vars(boxes)
+        # There is some redundancy here ?!
         pos_exc_value = imm(self.assembler.cpu.pos_exc_value())
         pos_exception = imm(self.assembler.cpu.pos_exception())
-        return self._prepare_guard(op, [loc, loc1, resloc, pos_exc_value, pos_exception])
+        arglocs = self._prepare_guard(op, [loc, loc1, resloc, pos_exc_value, pos_exception])
+        self.possibly_free_vars(boxes)
+        return arglocs
 
     def prepare_op_guard_no_exception(self, op, fcond):
         loc, box = self._ensure_value_is_boxed(
                     ConstInt(self.assembler.cpu.pos_exception()))
+        arglocs = self._prepare_guard(op, [loc])
         self.possibly_free_var(box)
-        return self._prepare_guard(op, [loc])
+        return arglocs
 
     def prepare_op_guard_class(self, op, fcond):
         return self._prepare_guard_class(op, fcond)
@@ -356,8 +344,9 @@
         y_val = rffi.cast(lltype.Signed, op.getarg(1).getint())
         self.assembler.load(y, imm(y_val))
 
+        arglocs = self._prepare_guard(op, [x, y])
         self.possibly_free_vars(boxes)
-        return self._prepare_guard(op, [x, y])
+        return arglocs
 
     def prepare_op_jump(self, op, fcond):
         descr = op.getdescr()
@@ -645,11 +634,7 @@
     def prepare_guard_call_may_force(self, op, guard_op, fcond):
         faildescr = guard_op.getdescr()
         fail_index = self.assembler.cpu.get_fail_descr_number(faildescr)
-        # XXX remove tempbox when ip can be used in gen_load_int
-        t = TempBox()
-        l0 = self.force_allocate_reg(t)
-        self.possibly_free_var(t)
-        self.assembler._write_fail_index(fail_index, l0)
+        self.assembler._write_fail_index(fail_index)
         args = [rffi.cast(lltype.Signed, op.getarg(0).getint())]
         # force all reg values to be spilled when calling
         self.assembler.emit_op_call(op, args, self, fcond, spill_all_regs=True)
@@ -659,11 +644,7 @@
     def prepare_guard_call_assembler(self, op, guard_op, fcond):
         faildescr = guard_op.getdescr()
         fail_index = self.assembler.cpu.get_fail_descr_number(faildescr)
-        # XXX remove tempbox when ip can be used in gen_load_int
-        t = TempBox()
-        l0 = self.force_allocate_reg(t)
-        self.possibly_free_var(t)
-        self.assembler._write_fail_index(fail_index, l0)
+        self.assembler._write_fail_index(fail_index)
 
     def _prepare_args_for_new_op(self, new_args):
         gc_ll_descr = self.assembler.cpu.gc_ll_descr



More information about the Pypy-commit mailing list