[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