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