Author: Armin Rigo <ar...@tunes.org>
Branch: optimize-cond-call
Changeset: r79440:a0f8d5a277f9
Date: 2015-09-04 18:59 +0200
http://bitbucket.org/pypy/pypy/changeset/a0f8d5a277f9/

Log:    arm: getting there

diff --git a/rpython/jit/backend/arm/opassembler.py 
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -240,7 +240,8 @@
             assert l1.is_vfp_reg()
             self.mc.VCMP(l0.value, l1.value)
             self.mc.VMRS(cond=fcond)
-        fcond = self._emit_guard(op, failargs, c.EQ, save_exc=False)
+        self.guard_success_cc = c.EQ
+        fcond = self._emit_guard(op, failargs, save_exc=False)
         return fcond
 
     emit_op_guard_nonnull = emit_op_guard_true
@@ -251,13 +252,15 @@
 
     def emit_op_guard_class(self, op, arglocs, regalloc, fcond):
         self._cmp_guard_class(op, arglocs, regalloc, fcond)
-        self._emit_guard(op, arglocs[3:], c.EQ, save_exc=False)
+        self.guard_success_cc = c.EQ
+        self._emit_guard(op, arglocs[3:], save_exc=False)
         return fcond
 
     def emit_op_guard_nonnull_class(self, op, arglocs, regalloc, fcond):
         self.mc.CMP_ri(arglocs[0].value, 1)
         self._cmp_guard_class(op, arglocs, regalloc, c.HS)
-        self._emit_guard(op, arglocs[3:], c.EQ, save_exc=False)
+        self.guard_success_cc = c.EQ
+        self._emit_guard(op, arglocs[3:], save_exc=False)
         return fcond
 
     def _cmp_guard_class(self, op, locs, regalloc, fcond):
@@ -281,11 +284,13 @@
         self._check_frame_depth_debug(self.mc)
         return fcond
 
-    def cond_call(self, op, gcmap, cond_loc, call_loc, fcond):
+    def emit_op_cond_call(self, op, arglocs, regalloc, fcond):
+        [call_loc] = arglocs
+        gcmap = regalloc.get_gcmap([call_loc])
+
         assert call_loc is r.r4
-        self.mc.TST_rr(cond_loc.value, cond_loc.value)
         jmp_adr = self.mc.currpos()
-        self.mc.BKPT()  # patched later
+        self.mc.BKPT()  # patched later: the conditional jump
         #
         self.push_gcmap(self.mc, gcmap, store=True)
         #
@@ -303,8 +308,13 @@
         self.mc.BL(cond_call_adr)
         self.pop_gcmap(self.mc)
         # never any result value
+        cond = c.get_opposite_of(self.guard_success_cc)
+        self.guard_success_cc = c.cond_none
         pmc = OverwritingBuilder(self.mc, jmp_adr, WORD)
-        pmc.B_offs(self.mc.currpos(), c.EQ)  # equivalent to 0 as result of 
TST above
+        pmc.B_offs(self.mc.currpos(), cond)
+        # might be overridden again to skip over the following
+        # guard_no_exception too
+        self.previous_cond_call_jcond = jmp_adr, cond
         return fcond
 
     def emit_op_jump(self, op, arglocs, regalloc, fcond):
@@ -400,8 +410,15 @@
         failargs = arglocs[1:]
         self.mc.LDR_ri(loc.value, loc.value)
         self.mc.CMP_ri(loc.value, 0)
-        cond = self._emit_guard(op, failargs, c.EQ, save_exc=True)
-        return cond
+        self.guard_success_cc = c.EQ
+        fcond = self._emit_guard(op, failargs, save_exc=True)
+        # If the previous operation was a COND_CALL, overwrite its conditional
+        # jump to jump over this GUARD_NO_EXCEPTION as well, if we can
+        if self._find_nearby_operation(-1).getopnum() == rop.COND_CALL:
+            jmp_adr, prev_cond = self.previous_cond_call_jcond
+            pmc = OverwritingBuilder(self.mc, jmp_adr, WORD)
+            pmc.B_offs(self.mc.currpos(), prev_cond)
+        return fcond
 
     def emit_op_guard_exception(self, op, arglocs, regalloc, fcond):
         loc, loc1, resloc, pos_exc_value, pos_exception = arglocs[:5]
@@ -410,7 +427,8 @@
         self.mc.LDR_ri(r.ip.value, loc1.value)
 
         self.mc.CMP_rr(r.ip.value, loc.value)
-        self._emit_guard(op, failargs, c.EQ, save_exc=True)
+        self.guard_success_cc = c.EQ
+        self._emit_guard(op, failargs, save_exc=True)
         self._store_and_reset_exception(self.mc, resloc)
         return fcond
 
@@ -934,16 +952,14 @@
     def imm(self, v):
         return imm(v)
 
-    def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc,
-                                  fcond):
+    def emit_op_call_assembler(self, op, arglocs, regalloc, fcond):
         if len(arglocs) == 4:
             [argloc, vloc, result_loc, tmploc] = arglocs
         else:
             [argloc, result_loc, tmploc] = arglocs
             vloc = imm(0)
-        self.call_assembler(op, guard_op, argloc, vloc, result_loc, tmploc)
-        self._emit_guard_may_force(guard_op,
-                        regalloc._prepare_guard(guard_op))
+        self._store_force_index(self._find_nearby_operation(+1))
+        self.call_assembler(op, argloc, vloc, result_loc, tmploc)
         return fcond
 
     def _call_assembler_emit_call(self, addr, argloc, resloc):
@@ -1017,41 +1033,36 @@
         mc.B(target)
         mc.copy_to_raw_memory(oldadr)
 
-    def emit_guard_call_may_force(self, op, guard_op, arglocs, regalloc,
-                                                                    fcond):
-        self._store_force_index(guard_op)
-        numargs = op.numargs()
-        callargs = arglocs[:numargs + 3]  # extract the arguments to the call
-        guardargs = arglocs[len(callargs):]
-        #
-        self._emit_call(op, callargs, fcond=fcond)
-        self._emit_guard_may_force(guard_op, guardargs)
-        return fcond
-
-    def _emit_guard_may_force(self, guard_op, arglocs):
+    def emit_op_guard_not_forced(self, op, arglocs, regalloc, fcond):
         ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
         self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs)
         self.mc.CMP_ri(r.ip.value, 0)
-        self._emit_guard(guard_op, arglocs, c.EQ,
-                                   save_exc=True, is_guard_not_forced=True)
+        self.guard_success_cc = c.EQ
+        self._emit_guard(op, arglocs, save_exc=True, is_guard_not_forced=True)
 
-    def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc,
-                                                                    fcond):
-        numargs = op.numargs()
-        callargs = arglocs[:numargs + 3]     # extract the arguments to the 
call
-        guardargs = arglocs[len(callargs):]  # extrat the arguments for the 
guard
-        self._store_force_index(guard_op)
-        self._emit_call(op, callargs, is_call_release_gil=True)
-        self._emit_guard_may_force(guard_op, guardargs)
+    def emit_op_call_may_force(self, op, arglocs, regalloc, fcond):
+        self._store_force_index(self._find_nearby_operation(+1))
+        self._emit_call(op, arglocs, fcond=fcond)
+        return fcond
+
+    def emit_op_call_release_gil(self, op, arglocs, regalloc, fcond):
+        self._store_force_index(self._find_nearby_operation(+1))
+        self._emit_call(op, arglocs, is_call_release_gil=True)
         return fcond
 
     def _store_force_index(self, guard_op):
+        assert (guard_op.getopnum() == rop.GUARD_NOT_FORCED or
+                guard_op.getopnum() == rop.GUARD_NOT_FORCED_2)
         faildescr = guard_op.getdescr()
         ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr')
         value = rffi.cast(lltype.Signed, cast_instance_to_gcref(faildescr))
         self.mc.gen_load_int(r.ip.value, value)
         self.store_reg(self.mc, r.ip, r.fp, ofs)
 
+    def _find_nearby_operation(self, delta):
+        regalloc = self._regalloc
+        return regalloc.operations[regalloc.rm.position + delta]
+
     def emit_op_call_malloc_gc(self, op, arglocs, regalloc, fcond):
         self.emit_op_call(op, arglocs, regalloc, fcond)
         self.propagate_memoryerror_if_r0_is_null()
diff --git a/rpython/jit/backend/arm/regalloc.py 
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -524,7 +524,9 @@
     prepare_op_int_invert = prepare_unary_op
 
     def prepare_op_call(self, op, fcond):
-        effectinfo = op.getdescr().get_extra_info()
+        calldescr = op.getdescr()
+        assert calldescr is not None
+        effectinfo = calldescr.get_extra_info()
         if effectinfo is not None:
             oopspecindex = effectinfo.oopspecindex
             if oopspecindex in (EffectInfo.OS_LLONG_ADD,
@@ -576,13 +578,12 @@
 
     def _call(self, op, arglocs, force_store=[], save_all_regs=False):
         # spill variables that need to be saved around calls
-        self.vfprm.before_call(save_all_regs=save_all_regs)
+        self.vfprm.before_call(force_store, save_all_regs=save_all_regs)
         if not save_all_regs:
             gcrootmap = self.cpu.gc_ll_descr.gcrootmap
             if gcrootmap and gcrootmap.is_shadow_stack:
                 save_all_regs = 2
-        self.rm.before_call(save_all_regs=save_all_regs)
-        self.before_call_called = True
+        self.rm.before_call(force_store, save_all_regs=save_all_regs)
         resloc = None
         if op.result:
             resloc = self.after_call(op.result)
@@ -1173,9 +1174,8 @@
             arg = op.getarg(i)
             self.make_sure_var_in_reg(arg, args_so_far, selected_reg=reg)
             args_so_far.append(arg)
-        loc_cond = self.make_sure_var_in_reg(op.getarg(0), args_so_far)
-        gcmap = self.get_gcmap([tmpreg])
-        self.assembler.cond_call(op, gcmap, loc_cond, tmpreg, fcond)
+        self.load_condition_into_cc(op.getarg(0))
+        return [tmpreg]
 
     def prepare_op_force_token(self, op, fcond):
         # XXX for now we return a regular reg
@@ -1229,15 +1229,13 @@
         self.assembler.store_force_descr(op, fail_locs[1:], fail_locs[0].value)
         self.possibly_free_vars(op.getfailargs())
 
-    def prepare_guard_call_may_force(self, op, guard_op, fcond):
-        args = self._prepare_call(op, save_all_regs=True)
-        return self._prepare_guard(guard_op, args)
+    def prepare_op_call_may_force(self, op, fcond):
+        return self._prepare_call(op, save_all_regs=True)
 
-    def prepare_guard_call_release_gil(self, op, guard_op, fcond):
-        args = self._prepare_call(op, save_all_regs=True, first_arg_index=2)
-        return self._prepare_guard(guard_op, args)
+    def prepare_op_call_release_gil(self, op, fcond):
+        return self._prepare_call(op, save_all_regs=True, first_arg_index=2)
 
-    def prepare_guard_call_assembler(self, op, guard_op, fcond):
+    def prepare_op_call_assembler(self, op, fcond):
         locs = self.locs_for_call_assembler(op, guard_op)
         tmploc = self.get_scratch_reg(INT, selected_reg=r.r0)
         resloc = self._call(op, locs + [tmploc], save_all_regs=True)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to