[pypy-commit] pypy regalloc: 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)
plan_rich
noreply at buildbot.pypy.org
Thu Jun 18 13:03:56 CEST 2015
Author: Richard Plangger <rich at 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)
More information about the pypy-commit
mailing list