[pypy-commit] pypy default: Tentative: kill the usage of eax as a reserved register around LABEL and

arigo noreply at buildbot.pypy.org
Tue Dec 13 21:17:17 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r50472:3385f481f372
Date: 2011-12-13 18:47 +0100
http://bitbucket.org/pypy/pypy/changeset/3385f481f372/

Log:	Tentative: kill the usage of eax as a reserved register around LABEL
	and JUMPs. On x86-64, we have already r11 for that. On x86-32, too
	bad, we emit slightly-inefficient code that moves from %ebp-x to
	%ebp-y by generating "push (%ebp-x); pop (%ebp-y)". The hope is
	that we should win overall anyway, because 9b45755e2c2b should
	hopefully have removed most such moves.

diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py
--- a/pypy/jit/backend/llsupport/regalloc.py
+++ b/pypy/jit/backend/llsupport/regalloc.py
@@ -163,7 +163,7 @@
         if not we_are_translated() and self.box_types is not None:
             assert isinstance(v, TempBox) or v.type in self.box_types
 
-    def possibly_free_var(self, v, _hint_dont_reuse_quickly=False):
+    def possibly_free_var(self, v):
         """ If v is stored in a register and v is not used beyond the
             current position, then free it.  Must be called at some
             point for all variables that might be in registers.
@@ -173,10 +173,7 @@
             return
         if v not in self.longevity or self.longevity[v][1] <= self.position:
             if v in self.reg_bindings:
-                if _hint_dont_reuse_quickly:
-                    self.free_regs.insert(0, self.reg_bindings[v])
-                else:
-                    self.free_regs.append(self.reg_bindings[v])
+                self.free_regs.append(self.reg_bindings[v])
                 del self.reg_bindings[v]
             if self.frame_manager is not None:
                 self.frame_manager.mark_as_free(v)
diff --git a/pypy/jit/backend/x86/jump.py b/pypy/jit/backend/x86/jump.py
--- a/pypy/jit/backend/x86/jump.py
+++ b/pypy/jit/backend/x86/jump.py
@@ -66,6 +66,10 @@
 
 def _move(assembler, src, dst, tmpreg):
     if dst.is_memory_reference() and src.is_memory_reference():
+        if tmpreg is None:
+            assembler.regalloc_push(src)
+            assembler.regalloc_pop(dst)
+            return
         assembler.regalloc_mov(src, tmpreg)
         src = tmpreg
     assembler.regalloc_mov(src, dst)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -1387,13 +1387,6 @@
         assert isinstance(descr, TargetToken)
         arglocs = descr._x86_arglocs
         self.jump_target_descr = descr
-        # compute 'tmploc' to be all_regs[0] by spilling what is there
-        tmpbox1 = TempBox()
-        tmpbox2 = TempBox()
-        tmpreg = X86RegisterManager.all_regs[0]
-        self.rm.force_allocate_reg(tmpbox1, selected_reg=tmpreg)
-        xmmtmp = X86XMMRegisterManager.all_regs[0]
-        self.xrm.force_allocate_reg(tmpbox2, selected_reg=xmmtmp)
         # Part about non-floats
         src_locations1 = []
         dst_locations1 = []
@@ -1405,19 +1398,23 @@
             box = op.getarg(i)
             src_loc = self.loc(box)
             dst_loc = arglocs[i]
-            assert dst_loc != tmpreg and dst_loc != xmmtmp
             if box.type != FLOAT:
                 src_locations1.append(src_loc)
                 dst_locations1.append(dst_loc)
             else:
                 src_locations2.append(src_loc)
                 dst_locations2.append(dst_loc)
+        # Do we have a temp var?
+        if IS_X86_64:
+            tmpreg = X86_64_SCRATCH_REG
+            xmmtmp = X86_64_XMM_SCRATCH_REG
+        else:
+            tmpreg = None
+            xmmtmp = None
         # Do the remapping
         remap_frame_layout_mixed(assembler,
                                  src_locations1, dst_locations1, tmpreg,
                                  src_locations2, dst_locations2, xmmtmp)
-        self.rm.possibly_free_var(tmpbox1)
-        self.xrm.possibly_free_var(tmpbox2)
         self.possibly_free_vars_for_op(op)
         assembler.closing_jump(self.jump_target_descr)
 
@@ -1484,17 +1481,6 @@
             if self.last_real_usage.get(arg, -1) <= position:
                 self.force_spill_var(arg)
         #
-        # we need to make sure that the tmpreg and xmmtmp are free
-        tmpreg = X86RegisterManager.all_regs[0]
-        tmpvar = TempBox()
-        self.rm.force_allocate_reg(tmpvar, selected_reg=tmpreg)
-        self.rm.possibly_free_var(tmpvar, _hint_dont_reuse_quickly=True)
-        #
-        xmmtmp = X86XMMRegisterManager.all_regs[0]
-        tmpvar = TempBox()
-        self.xrm.force_allocate_reg(tmpvar, selected_reg=xmmtmp)
-        self.xrm.possibly_free_var(tmpvar, _hint_dont_reuse_quickly=True)
-        #
         # we need to make sure that no variable is stored in ebp
         for arg in inputargs:
             if self.loc(arg) is ebp:
@@ -1506,7 +1492,7 @@
             arg = inputargs[i]
             assert isinstance(arg, Box)
             loc = self.loc(arg)
-            assert not (loc is tmpreg or loc is xmmtmp or loc is ebp)
+            assert loc is not ebp
             arglocs[i] = loc
             if isinstance(loc, RegLoc):
                 self.fm.mark_as_free(arg)
diff --git a/pypy/jit/backend/x86/test/test_jump.py b/pypy/jit/backend/x86/test/test_jump.py
--- a/pypy/jit/backend/x86/test/test_jump.py
+++ b/pypy/jit/backend/x86/test/test_jump.py
@@ -71,6 +71,18 @@
                              ('mov', eax, s24),
                              ('mov', s12, edi)]
 
+def test_no_tmp_reg():
+    assembler = MockAssembler()
+    s8 = frame_pos(0, INT)
+    s12 = frame_pos(13, INT)
+    s20 = frame_pos(20, INT)
+    s24 = frame_pos(221, INT)
+    remap_frame_layout(assembler, [s8, eax, s12], [s20, s24, edi], None)
+    assert assembler.ops == [('push', s8),
+                             ('pop', s20),
+                             ('mov', eax, s24),
+                             ('mov', s12, edi)]
+
 def test_reordering():
     assembler = MockAssembler()
     s8 = frame_pos(8, INT)


More information about the pypy-commit mailing list