Author: Armin Rigo <ar...@tunes.org>
Branch: emit-call-x86
Changeset: r64332:4508172468aa
Date: 2013-05-19 18:20 +0200
http://bitbucket.org/pypy/pypy/changeset/4508172468aa/

Log:    Attempt to fix issues with a call_release_gil with a non-immediate
        function. Add some other optimizations.

diff --git a/rpython/jit/backend/x86/callbuilder.py 
b/rpython/jit/backend/x86/callbuilder.py
--- a/rpython/jit/backend/x86/callbuilder.py
+++ b/rpython/jit/backend/x86/callbuilder.py
@@ -6,7 +6,7 @@
 from rpython.jit.backend.x86.regloc import (eax, ecx, edx, ebx, esp, ebp, esi,
     xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, r8, r9, r10, r11, edi,
     r12, r13, r14, r15, X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG,
-    RegLoc, RawEspLoc, imm)
+    RegLoc, RawEspLoc, imm, ImmedLoc)
 from rpython.jit.backend.x86.jump import remap_frame_layout
 
 
@@ -43,10 +43,16 @@
 
 
     def __init__(self, assembler, fnloc, arglocs, resloc=eax):
+        # Avoid tons of issues with a non-immediate fnloc by sticking it
+        # as an extra argument if needed
+        self.fnloc_is_immediate = isinstance(fnloc, ImmedLoc)
+        if self.fnloc_is_immediate:
+            self.fnloc = fnloc
+            self.arglocs = arglocs
+        else:
+            self.arglocs = arglocs + [fnloc]
         self.asm = assembler
         self.mc = assembler.mc
-        self.fnloc = fnloc
-        self.arglocs = arglocs
         self.resloc = resloc
         self.current_esp = 0
 
@@ -256,14 +262,13 @@
                     self.mc.MOVSD(xmm0, loc)
                     self.mc.MOVSD_sx(p, xmm0.value)
                 else:
-                    if self.fnloc is eax:
-                        tmp = ecx
-                    else:
-                        tmp = eax
-                    self.mc.MOV(tmp, loc)
-                    self.mc.MOV_sr(p, tmp.value)
+                    self.mc.MOV(eax, loc)
+                    self.mc.MOV_sr(p, eax.value)
             p += loc.get_width()
         self.total_stack_used_by_arguments = p
+        #
+        if not self.fnloc_is_immediate:    # the last "argument" pushed above
+            self.fnloc = RawEspLoc(p - WORD, INT)
 
 
     def _fix_stdcall(self, callconv):
@@ -374,19 +379,27 @@
         # them in precisely the final registers.  Here we look around for
         # unused registers that may be more likely usable.
         from rpython.jit.backend.x86.regalloc import X86_64_RegisterManager
+        from rpython.jit.backend.x86.regalloc import X86_64_XMMRegisterManager
         self.already_used = {}
         for loc in self.arglocs:
             self.already_used[loc] = None
         #
         lst = X86_64_RegisterManager.save_around_call_regs[:]
         self._permute_to_prefer_unused_registers(lst)
+        # <optimization>
+        extra = []
+        for reg in self.asm._regalloc.rm.free_regs:
+            if (reg not in self.already_used and
+                    reg in self._ALL_CALLEE_SAVE_GPR):
+                extra.append(reg)
+        lst = extra + lst
+        # </optimization>
         self.ARGUMENTS_GPR = lst[:len(self.ARGUMENTS_GPR)]
         self.DONT_MOVE_GPR = self._ALL_CALLEE_SAVE_GPR
         #
-        lst = [xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7]
+        lst = X86_64_XMMRegisterManager.save_around_call_regs[:]
         self._permute_to_prefer_unused_registers(lst)
-        assert len(lst) == len(self.ARGUMENTS_XMM)
-        self.ARGUMENTS_XMM = lst
+        self.ARGUMENTS_XMM = lst[:len(self.ARGUMENTS_XMM)]
 
     def prepare_arguments(self):
         src_locs = []
@@ -425,6 +438,9 @@
                 src_locs.append(loc)
                 dst_locs.append(tgt)
 
+        if not self.fnloc_is_immediate:
+            self.fnloc = dst_locs[-1]     # the last "argument" prepared above
+
         if not we_are_translated():  # assert that we got the right stack depth
             floats = 0
             for i in range(len(arglocs)):
@@ -457,12 +473,6 @@
                     src = X86_64_SCRATCH_REG
                 self.mc.MOVD(dst, src)
         # Finally remap the arguments in the main regs
-        # If x is a register and is in dst_locs, then oups, it needs to
-        # be moved away:
-        if self.fnloc in dst_locs:
-            src_locs.append(self.fnloc)
-            dst_locs.append(r10)
-            self.fnloc = r10
         remap_frame_layout(self.asm, src_locs, dst_locs, X86_64_SCRATCH_REG)
 
 
@@ -535,6 +545,9 @@
             self.mc.MOVSD_xs(CallBuilder64.ARGUMENTS_XMM[i].value, n * WORD)
             n += 1
         assert n == self.n_saved_regs
+        #
+        if isinstance(self.fnloc, RegLoc):    # fix this register
+            self.fnloc = CallBuilder64.ARGUMENTS_GPR[n_gpr - 1]
 
 
 if IS_X86_32:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to