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

david at codespeak.net david at codespeak.net
Sat Nov 20 18:57:11 CET 2010


Author: david
Date: Sat Nov 20 18:57:08 2010
New Revision: 79306

Modified:
   pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
   pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
Log:
Refactor how guards are generated
Now a jump a the head checks the condition and skips the guard if the conditions holds
Fixes an issue with spilling withing a guard which was overwritten when patching the guard code from a bridge
Also free result vars for the case that they are not used.



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	Sat Nov 20 18:57:08 2010
@@ -170,8 +170,7 @@
         """
 
         descr = op.getdescr()
-        box = TempBox()
-        reg = regalloc.force_allocate_reg(box)
+        reg = r.lr
         # XXX free this memory
         # XXX allocate correct amount of memory
         mem = lltype.malloc(rffi.CArray(lltype.Char), len(args)*6+9, flavor='raw')
@@ -214,14 +213,10 @@
 
         n = self.cpu.get_fail_descr_number(descr)
         self.encode32(mem, j+1, n)
+        self.mc.ensure_can_fit(self.mc.size_of_gen_load_int)
         self.mc.gen_load_int(r.lr.value, memaddr, cond=fcond) # use lr to pass an argument
-        self.mc.B(self._exit_code_addr, fcond, reg)
+        self.mc.B(self._exit_code_addr)
 
-        # This register is used for patching when assembling a bridge
-        # guards going to be patched are allways conditional
-        if fcond != c.AL:
-            descr._arm_guard_reg = reg
-        regalloc.possibly_free_var(box)
         return memaddr
 
     def align(self):
@@ -367,7 +362,6 @@
         i = 0
         while i < len(operations):
             op = operations[i]
-            # XXX consider merging ops with next one if it is an adecuate guard
             opnum = op.getopnum()
             if self.can_merge_with_next_guard(op, i, operations):
                 fcond = self.operations_with_guard[opnum](self, op,
@@ -401,7 +395,7 @@
         self._walk_operations(operations, regalloc)
 
         print 'Done building bridges'
-        self.patch_trace(faildescr, bridge_head)
+        self.patch_trace(faildescr, bridge_head, regalloc)
         print 'Done patching trace'
         if self._debug_asm:
             self._dump_trace('bridge.asm')
@@ -418,11 +412,12 @@
         #XXX check ranges for different operations
         return isinstance(arg, ConstInt) and arg.getint() <= size and lower_bound
 
-    def patch_trace(self, faildescr, bridge_addr):
-        # XXX make sure there is enough space at patch target
-        fcond = faildescr._arm_guard_cond
-        b = ARMv7InMemoryBuilder(faildescr._arm_guard_code, faildescr._arm_guard_size)
-        b.B(bridge_addr, fcond, some_reg=faildescr._arm_guard_reg)
+    def patch_trace(self, faildescr, bridge_addr, regalloc):
+        # The first instruction (word) is not overwritten, because it is the
+        # one that actually checks the condition
+        b = ARMv7InMemoryBuilder(faildescr._arm_guard_code,
+                                        self.guard_size-WORD)
+        b.B(bridge_addr, some_reg=r.lr)
 
     # regalloc support
     def regalloc_mov(self, prev_loc, loc):

Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py	(original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/helper/assembler.py	Sat Nov 20 18:57:08 2010
@@ -12,6 +12,8 @@
         self.mc.MOV_ri(res.value, 1, true_cond)
         self.mc.MOV_ri(res.value, 0, false_cond)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
     return f
 
@@ -41,6 +43,8 @@
             res = regalloc.force_allocate_reg(op.result, [arg0, arg1])
             rr_op(res.value, l0.value, l1.value)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
     return f
 
@@ -56,7 +60,10 @@
         regalloc.before_call()
         getattr(self.mc, opname)(fcond)
         regalloc.after_call(op.result)
+
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
     return f
 
@@ -87,5 +94,7 @@
         self.mc.MOV_ri(res.value, 1, cond=condition)
         self.mc.MOV_ri(res.value, 0, cond=inv)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
     return f

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	Sat Nov 20 18:57:08 2010
@@ -49,6 +49,8 @@
             res = regalloc.force_allocate_reg(op.result, forbidden_vars=[a0, a1])
             self.mc.ADD_rr(res.value, l0.value, l1.value, s=1)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
 
     def emit_op_int_sub(self, op, regalloc, fcond):
@@ -79,6 +81,8 @@
             self.mc.SUB_rr(res.value, l0.value, l1.value, s=1)
 
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
 
     def emit_op_int_mul(self, op, regalloc, fcond):
@@ -89,6 +93,7 @@
         res = regalloc.force_allocate_reg(op.result, [a0, a1])
         self.mc.MUL(res.value, reg1.value, reg2.value)
         regalloc.possibly_free_vars_for_op(op)
+        regalloc.possibly_free_var(op.result)
         return fcond
 
     #ref: http://blogs.arm.com/software-enablement/detecting-overflow-from-mul/
@@ -102,10 +107,12 @@
         self.mc.SMULL(res.value, r.ip.value, reg1.value, reg2.value, cond=fcond)
         self.mc.CMP_rr(r.ip.value, res.value, shifttype=shift.ASR, imm=31, cond=fcond)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         if guard.getopnum() == rop.GUARD_OVERFLOW:
-            return self._emit_guard(guard, regalloc, c.EQ)
-        else:
             return self._emit_guard(guard, regalloc, c.NE)
+        else:
+            return self._emit_guard(guard, regalloc, c.EQ)
 
     emit_op_int_floordiv = gen_emit_op_by_helper_call('DIV')
     emit_op_int_mod = gen_emit_op_by_helper_call('MOD')
@@ -150,6 +157,8 @@
 
         self.mc.MVN_rr(res.value, reg.value)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
 
     #XXX check for a better way of doing this
@@ -166,17 +175,19 @@
 
     _mixin_ = True
 
+    guard_size = ARMv7Builder.size_of_gen_load_int + 2*WORD
     def _emit_guard(self, op, regalloc, fcond):
         descr = op.getdescr()
         assert isinstance(descr, BasicFailDescr)
         if hasattr(op, 'getfailargs'):
             print 'Failargs: ', op.getfailargs()
+        self.mc.ensure_can_fit(self.guard_size)
+        self.mc.ADD_ri(r.pc.value, r.pc.value, self.guard_size, cond=fcond)
         descr._arm_guard_code = self.mc.curraddr()
-        memaddr = self._gen_path_to_exit_path(op, op.getfailargs(), regalloc, fcond)
+        memaddr = self._gen_path_to_exit_path(op, op.getfailargs(), regalloc)
         descr._failure_recovery_code = memaddr
-        descr._arm_guard_cond = fcond
-        descr._arm_guard_size = self.mc.curraddr() - descr._arm_guard_code
         regalloc.possibly_free_vars_for_op(op)
+        self.mc.NOP()
         return c.AL
 
     def emit_op_guard_true(self, op, regalloc, fcond):
@@ -184,14 +195,14 @@
         l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
         self.mc.CMP_ri(l0.value, 0)
         regalloc.possibly_free_var(l0)
-        return self._emit_guard(op, regalloc, c.EQ)
+        return self._emit_guard(op, regalloc, c.NE)
 
     def emit_op_guard_false(self, op, regalloc, fcond):
         a0 = op.getarg(0)
         l0 = regalloc.make_sure_var_in_reg(a0, imm_fine=False)
         self.mc.CMP_ri(l0.value, 0)
         regalloc.possibly_free_var(l0)
-        return self._emit_guard(op, regalloc, c.NE)
+        return self._emit_guard(op, regalloc, c.EQ)
 
     def emit_op_guard_value(self, op, regalloc, fcond):
         a0 = op.getarg(0)
@@ -204,16 +215,16 @@
         else:
             self.mc.CMP_rr(l0.value, l1.value)
         regalloc.possibly_free_vars_for_op(op)
-        return self._emit_guard(op, regalloc, c.NE)
+        return self._emit_guard(op, regalloc, c.EQ)
 
     emit_op_guard_nonnull = emit_op_guard_true
     emit_op_guard_isnull = emit_op_guard_false
 
     def emit_op_guard_no_overflow(self, op, regalloc, fcond):
-        return self._emit_guard(op, regalloc, c.VS)
+        return self._emit_guard(op, regalloc, c.VC)
 
     def emit_op_guard_overflow(self, op, regalloc, fcond):
-        return self._emit_guard(op, regalloc, c.VC)
+        return self._emit_guard(op, regalloc, c.VS)
 
 class OpAssembler(object):
 
@@ -301,6 +312,8 @@
         else:
             self.mc.MOV_rr(resloc.value, argloc.value)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         return fcond
 
 class FieldOpAssembler(object):
@@ -373,6 +386,8 @@
 
         self.mc.LDR_ri(res.value, base_loc.value, ofs)
         regalloc.possibly_free_var(op.getarg(0))
+        if op.result:
+            regalloc.possibly_free_var(op.result)
 
     def emit_op_setarrayitem_gc(self, op, regalloc, fcond):
         a0 = op.getarg(0)
@@ -443,6 +458,8 @@
         l0 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
         regalloc.possibly_free_vars_for_op(op)
         res = regalloc.force_allocate_reg(op.result)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                              self.cpu.translate_support_code)
         l1 = regalloc.make_sure_var_in_reg(ConstInt(ofs_length))
@@ -460,6 +477,8 @@
         res = regalloc.force_allocate_reg(op.result)
         regalloc.possibly_free_vars_for_op(op)
         regalloc.possibly_free_var(t)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                              self.cpu.translate_support_code)
@@ -480,6 +499,8 @@
         temp = regalloc.force_allocate_reg(t)
         regalloc.possibly_free_vars_for_op(op)
         regalloc.possibly_free_var(t)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                              self.cpu.translate_support_code)
@@ -499,6 +520,8 @@
         l0 = regalloc.make_sure_var_in_reg(op.getarg(0), imm_fine=False)
         regalloc.possibly_free_vars_for_op(op)
         res = regalloc.force_allocate_reg(op.result)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                              self.cpu.translate_support_code)
         l1 = regalloc.make_sure_var_in_reg(ConstInt(ofs_length))
@@ -516,6 +539,8 @@
         res = regalloc.force_allocate_reg(op.result)
         regalloc.possibly_free_vars_for_op(op)
         regalloc.possibly_free_var(t)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                              self.cpu.translate_support_code)
@@ -539,6 +564,8 @@
         temp = regalloc.force_allocate_reg(t)
         regalloc.possibly_free_vars_for_op(op)
         regalloc.possibly_free_var(t)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                              self.cpu.translate_support_code)
@@ -661,8 +688,10 @@
         self.mc.CMP_ri(l0.value, 0)
         regalloc.possibly_free_var(t)
         regalloc.possibly_free_vars_for_op(op)
+        if op.result:
+            regalloc.possibly_free_var(op.result)
 
-        self._emit_guard(guard_op, regalloc, c.LT)
+        self._emit_guard(guard_op, regalloc, c.GE)
         return fcond
 
     def emit_guard_call_may_force(self, op, guard_op, regalloc, fcond):
@@ -679,7 +708,7 @@
         self.mc.CMP_ri(l0.value, 0)
         regalloc.possibly_free_var(t)
 
-        self._emit_guard(guard_op, regalloc, c.LT)
+        self._emit_guard(guard_op, regalloc, c.GE)
         return fcond
 
     def _write_fail_index(self, fail_index, regalloc):



More information about the Pypy-commit mailing list