[pypy-commit] pypy regalloc-playground: adds hints for target registers of jumps as well

cfbolz pypy.commits at gmail.com
Fri Sep 8 03:07:35 EDT 2017


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: regalloc-playground
Changeset: r92348:baece8cd15d9
Date: 2017-09-07 14:17 +0200
http://bitbucket.org/pypy/pypy/changeset/baece8cd15d9/

Log:	adds hints for target registers of jumps as well

diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -156,6 +156,7 @@
         # to be read/used by the assembler too
         self.jump_target_descr = None
         self.final_jump_op = None
+        self.final_jump_op_position = -1
 
     def _prepare(self, inputargs, operations, allgcrefs):
         from rpython.jit.backend.x86.reghint import X86RegisterHints
@@ -1318,19 +1319,20 @@
         if op.getopnum() != rop.JUMP:
             return
         self.final_jump_op = op
+        self.final_jump_op_position = len(operations) - 1
         descr = op.getdescr()
         assert isinstance(descr, TargetToken)
         if descr._ll_loop_code != 0:
             # if the target LABEL was already compiled, i.e. if it belongs
             # to some already-compiled piece of code
-            self._compute_hint_frame_locations_from_descr(descr)
+            self._compute_hint_locations_from_descr(descr)
         #else:
         #   The loop ends in a JUMP going back to a LABEL in the same loop.
         #   We cannot fill 'hint_frame_pos' immediately, but we can
         #   wait until the corresponding consider_label() to know where the
         #   we would like the boxes to be after the jump.
 
-    def _compute_hint_frame_locations_from_descr(self, descr):
+    def _compute_hint_locations_from_descr(self, descr):
         arglocs = descr._x86_arglocs
         jump_op = self.final_jump_op
         assert len(arglocs) == jump_op.numargs()
@@ -1340,6 +1342,11 @@
                 loc = arglocs[i]
                 if isinstance(loc, FrameLoc):
                     self.fm.hint_frame_pos[box] = self.fm.get_loc_index(loc)
+                else:
+                    assert isinstance(loc, RegLoc)
+                    self.longevity.fixed_register(
+                            self.final_jump_op_position,
+                            loc, box)
 
     def consider_jump(self, op):
         assembler = self.assembler
@@ -1447,7 +1454,7 @@
         # the hints about the expected position of the spilled variables.
         jump_op = self.final_jump_op
         if jump_op is not None and jump_op.getdescr() is descr:
-            self._compute_hint_frame_locations_from_descr(descr)
+            self._compute_hint_locations_from_descr(descr)
 
     def consider_guard_not_forced_2(self, op):
         self.rm.before_call(op.getfailargs(), save_all_regs=True)
diff --git a/rpython/jit/backend/x86/test/test_regalloc.py b/rpython/jit/backend/x86/test/test_regalloc.py
--- a/rpython/jit/backend/x86/test/test_regalloc.py
+++ b/rpython/jit/backend/x86/test/test_regalloc.py
@@ -51,6 +51,13 @@
     def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap):
         self._log("malloc_cond", size, "ecx") # always uses edx and ecx
 
+    def label(self):
+        self._log("label")
+        return Assembler386.label(self)
+
+    def closing_jump(self, jump_target_descr):
+        self._log("jump")
+        return Assembler386.closing_jump(self, jump_target_descr)
 
 class TestCheckRegistersExplicitly(test_regalloc_integration.BaseTestRegalloc):
     def setup_class(cls):
@@ -254,6 +261,41 @@
         # edx for any of the integer results
         assert len(self.filter_log_moves()) == 2
 
+    def test_jump_hinting(self):
+        ops = '''
+        [i0]
+        i1 = int_add(i0, 1)
+        i10 = int_add(i1, 1)
+        i2 = int_add(i1, 1)
+        i3 = int_lt(i2, 20)
+        guard_true(i3) [i1, i10]
+        label(i2, descr=targettoken)
+        i4 = int_add(i2, 1)
+        i11 = int_add(i4, 1)
+        i5 = int_add(i4, 1)
+        i6 = int_lt(i5, 20)
+        guard_true(i6) [i4, i11]
+        jump(i5, descr=targettoken)
+        '''
+        self.interpret(ops, [0], run=False)
+        assert len(self.filter_log_moves()) == 1
+
+    @pytest.mark.skip("later")
+    def test_jump_different_args2(self):
+        ops = '''
+        [i0, i4, i6]
+        i1 = int_add(i0, i6)
+        i2 = int_lt(i1, 20)
+        guard_true(i2) [i1]
+        label(i4, i1, i6, descr=targettoken)
+        i3 = int_add(i4, i6)
+        i7 = int_lt(i3, 20)
+        guard_true(i7) [i3]
+        jump(i1, i3, i6, descr=targettoken)
+        '''
+        self.interpret(ops, [0], run=False)
+
+
     def test_flowcontext(self):
         # real index manipulation for a slicing operation done when translating
         # on top of pypy


More information about the pypy-commit mailing list