[pypy-commit] pypy arm64: call_may_force
fijal
pypy.commits at gmail.com
Sat Jun 22 08:16:39 EDT 2019
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: arm64
Changeset: r96840:5142be166d5c
Date: 2019-06-22 12:08 +0000
http://bitbucket.org/pypy/pypy/changeset/5142be166d5c/
Log: call_may_force
diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py
--- a/rpython/jit/backend/aarch64/assembler.py
+++ b/rpython/jit/backend/aarch64/assembler.py
@@ -791,11 +791,22 @@
guard_num = guard_op.getopnum()
arglocs, fcond = guard_operations[guard_num](regalloc, guard_op, op)
if arglocs is not None:
- asm_guard_operations[guard_num](self, guard_op, fcond, arglocs)
+ asm_guard_operations[guard_num](self, op, guard_op, fcond, arglocs)
regalloc.next_instruction() # advance one more
if guard_op.is_guard(): # can be also cond_call
regalloc.possibly_free_vars(guard_op.getfailargs())
regalloc.possibly_free_vars_for_op(guard_op)
+ elif rop.is_call_may_force(op.getopnum()):
+ guard_op = operations[i + 1] # has to exist
+ guard_num = guard_op.getopnum()
+ assert guard_num in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2)
+ arglocs, fcond = guard_operations[guard_num](regalloc, guard_op, op)
+ if arglocs is not None:
+ asm_guard_operations[guard_num](self, op, guard_op, fcond, arglocs)
+ # fcond is abused here to pass the number of args
+ regalloc.next_instruction() # advance one more
+ regalloc.possibly_free_vars(guard_op.getfailargs())
+ regalloc.possibly_free_vars_for_op(guard_op)
else:
arglocs = regalloc_operations[opnum](regalloc, op)
if arglocs is not None:
diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py
--- a/rpython/jit/backend/aarch64/opassembler.py
+++ b/rpython/jit/backend/aarch64/opassembler.py
@@ -481,11 +481,11 @@
else:
self.mc.BRK()
- def emit_guard_op_guard_true(self, guard_op, fcond, arglocs):
+ def emit_guard_op_guard_true(self, op, guard_op, fcond, arglocs):
self._emit_guard(guard_op, fcond, arglocs)
emit_guard_op_guard_no_overflow = emit_guard_op_guard_true
- def emit_guard_op_guard_false(self, guard_op, fcond, arglocs):
+ def emit_guard_op_guard_false(self, op, guard_op, fcond, arglocs):
self._emit_guard(guard_op, c.get_opposite_of(fcond), arglocs)
emit_guard_op_guard_overflow = emit_guard_op_guard_false
@@ -647,7 +647,7 @@
def emit_op_cond_call_value_i(self, op, arglocs):
self._emit_op_cond_call(op, arglocs, c.NE)
- def emit_guard_op_cond_call(self, op, fcond, arglocs):
+ def emit_guard_op_cond_call(self, prevop, op, fcond, arglocs):
self._emit_op_cond_call(op, arglocs, c.get_opposite_of(fcond))
def _write_barrier_fastpath(self, mc, descr, arglocs, array=False, is_frame=False):
@@ -804,9 +804,31 @@
else:
cb.emit_no_collect()
+ def emit_guard_op_guard_not_forced(self, op, guard_op, fcond, arglocs):
+ # arglocs is call locs + guard_locs, split them
+ assert fcond == op.numargs() + 3
+ call_args = arglocs[:fcond]
+ guard_locs = arglocs[fcond:]
+ self._store_force_index(guard_op)
+ self._emit_call(op, call_args)
+ ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
+ self.mc.LDR_ri(r.ip0.value, r.fp.value, ofs)
+ self.mc.CMP_ri(r.ip0.value, 0)
+ self._emit_guard(guard_op, c.EQ, guard_locs)
+
+ def _store_force_index(self, guard_op):
+ faildescr = guard_op.getdescr()
+ faildescrindex = self.get_gcref_from_faildescr(faildescr)
+ ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr')
+ self.load_from_gc_table(r.ip0.value, faildescrindex)
+ self.store_reg(self.mc, r.ip0, r.fp, ofs)
+
def emit_op_label(self, op, arglocs):
pass
+ def emit_op_force_token(self, op, arglocs):
+ self.mc.MOV_rr(arglocs[0].value, r.fp.value)
+
def emit_op_jump(self, op, arglocs):
target_token = op.getdescr()
assert isinstance(target_token, TargetToken)
diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py
--- a/rpython/jit/backend/aarch64/regalloc.py
+++ b/rpython/jit/backend/aarch64/regalloc.py
@@ -634,6 +634,11 @@
else:
return self.rm.after_call(v)
+ def prepare_guard_op_guard_not_forced(self, op, prev_op):
+ arglocs = self._prepare_call(prev_op, save_all_regs=True)
+ guard_locs = self._guard_impl(op)
+ return arglocs + guard_locs, len(arglocs)
+
def prepare_op_label(self, op):
descr = op.getdescr()
assert isinstance(descr, TargetToken)
@@ -720,6 +725,11 @@
locs = self._prepare_op_cond_call(op, True)
return locs, fcond
+ def prepare_op_force_token(self, op):
+ # XXX regular reg
+ res_loc = self.force_allocate_reg(op)
+ return [res_loc]
+
def prepare_op_finish(self, op):
# the frame is in fp, but we have to point where in the frame is
# the potential argument to FINISH
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -2506,6 +2506,7 @@
def test_force_operations_returning_void(self):
values = []
def maybe_force(token, flag):
+ print "CALLED WITH " + str(flag)
if flag:
deadframe = self.cpu.force(token)
values.append(self.cpu.get_latest_descr(deadframe))
More information about the pypy-commit
mailing list