Author: Richard Plangger <r...@pasra.at>
Branch: regalloc
Changeset: r78174:be630ecb8639
Date: 2015-06-18 13:04 +0200
http://bitbucket.org/pypy/pypy/changeset/be630ecb8639/

Log:    added logic to put every variable into the register depending on how
        far away the next usage is (less distance is more likely to end up
        in a register)

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
@@ -9,7 +9,7 @@
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.backend.llsupport.regalloc import (FrameManager, BaseRegalloc,
      RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op,
-     valid_addressing_size)
+     valid_addressing_size, next_var_usage)
 from rpython.jit.backend.x86 import rx86
 from rpython.jit.backend.x86.arch import (WORD, JITFRAME_FIXED_SIZE, IS_X86_32,
     IS_X86_64, DEFAULT_FRAME_BYTES)
@@ -27,6 +27,7 @@
 from rpython.rlib import rgc
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.rarithmetic import r_longlong, r_uint
+from rpython.rlib.rbisect import bisect_right
 from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 from rpython.rtyper.lltypesystem import lltype, rffi, rstr
 from rpython.rtyper.lltypesystem.lloperation import llop
@@ -1342,6 +1343,11 @@
         #self.rm.force_allocate_frame_reg(op.result)
         self.assembler.force_token(self.rm.force_allocate_reg(op.result))
 
+    def freecount(self, type):
+        if type == FLOAT:
+            return len(self.xrm.free_regs)
+        return len(self.rm.free_regs)
+
     def consider_label(self, op):
         descr = op.getdescr()
         assert isinstance(descr, TargetToken)
@@ -1365,6 +1371,8 @@
                 self.assembler.mc.MOV(loc2, ebp)
         self.rm.bindings_to_frame_reg.clear()
         #
+        relocate_index = []
+        relocate = []
         for i in range(len(inputargs)):
             arg = inputargs[i]
             assert isinstance(arg, Box)
@@ -1373,6 +1381,41 @@
             arglocs[i] = loc
             if isinstance(loc, RegLoc):
                 self.fm.mark_as_free(arg)
+            else:
+                # on first enter, try to put as many locations into registers
+                # as possible. They are sorted by the next variable use.
+                # Descending and are poped in reverse order later
+                pos = next_var_usage(self.longevity[arg], self.rm.position)
+                i = bisect_right(relocate_index, pos, len(relocate_index))
+                if i >= position:
+                    relocate_index.insert(i, pos)
+                    relocate.insert(i, (arg, argidx))
+        #
+        forbidden = {}
+        relocate_exit = []
+        while len(relocate) > 0:
+            arg, argidx = relocate.pop()
+            if self.freecount(arg.type) <= 0:
+                continue
+
+            if self.last_real_usage.get(arg, -1) >= position:
+                loc = self.make_sure_var_in_reg(arg, forbidden)
+                forbidden[arg] = None
+                arglocs[argidx] = loc
+                self.fm.mark_as_free(arg)
+            else:
+                relocate_exit.insert(0, arg)
+
+        # there might be still registers available
+        while len(relocate_exit) > 0:
+            arg, argidx = relocate_exit.pop()
+            if self.freecount(arg.type) <= 0:
+                continue
+
+            loc = self.make_sure_var_in_reg(arg, forbidden)
+            forbidden[arg] = None
+            arglocs[argidx] = loc
+            self.fm.mark_as_free(arg)
         #
         # if we are too close to the start of the loop, the label's target may
         # get overridden by redirect_call_assembler().  (rare case)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to