Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit