Author: Armin Rigo <[email protected]>
Branch:
Changeset: r66952:f0beca98ab6f
Date: 2013-09-15 12:00 +0200
http://bitbucket.org/pypy/pypy/changeset/f0beca98ab6f/
Log: Reintroduce the hints for register location through a JUMP.
diff --git a/rpython/jit/backend/llsupport/regalloc.py
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -68,14 +68,27 @@
function(arg, node.val)
node = node.next
- def pop(self, size, tp):
+ def pop(self, size, tp, hint=-1):
if size == 2:
return self._pop_two(tp)
assert size == 1
if not self.master_node:
return None
node = self.master_node
- self.master_node = node.next
+ #
+ if hint >= 0:
+ prev_node = node
+ while prev_node.next:
+ if prev_node.next.val == hint:
+ node = prev_node.next
+ prev_node.next = node.next
+ break
+ prev_node = prev_node.next
+ else:
+ self.master_node = node.next
+ else:
+ self.master_node = node.next
+ #
return self.fm.frame_pos(node.val, tp)
def _candidate(self, node):
@@ -131,8 +144,7 @@
def __init__(self, start_free_depth=0, freelist=None):
self.bindings = {}
self.current_frame_depth = start_free_depth
- # we disable hints for now
- #self.hint_frame_locations = {}
+ self.hint_frame_pos = {}
self.freelist = LinkedList(self, freelist)
def get_frame_depth(self):
@@ -148,22 +160,16 @@
return self.bindings[box]
except KeyError:
pass
- # check if we have a hint for this box
- #if box in self.hint_frame_locations:
- # # if we do, try to reuse the location for this box
- # loc = self.hint_frame_locations[box]
- # if self.try_to_reuse_location(box, loc):
- # return loc
- ## no valid hint. make up a new free location
return self.get_new_loc(box)
def get_new_loc(self, box):
size = self.frame_size(box.type)
+ hint = self.hint_frame_pos.get(box, -1)
# frame_depth is rounded up to a multiple of 'size', assuming
# that 'size' is a power of two. The reason for doing so is to
# avoid obscure issues in jump.py with stack locations that try
# to move from position (6,7) to position (7,8).
- newloc = self.freelist.pop(size, box.type)
+ newloc = self.freelist.pop(size, box.type, hint)
if newloc is None:
#
index = self.get_frame_depth()
@@ -232,23 +238,6 @@
all[node.val] = 1
node = node.next
- def try_to_reuse_location(self, box, loc):
- xxx
- index = self.get_loc_index(loc)
- if index < 0:
- return False
- size = self.frame_size(box.type)
- for i in range(size):
- while (index + i) >= len(self.used):
- self.used.append(False)
- if self.used[index + i]:
- return False # already in use
- # good, we can reuse the location
- for i in range(size):
- self.used[index + i] = True
- self.bindings[box] = loc
- return True
-
@staticmethod
def _gather_gcroots(lst, var):
lst.append(var)
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py
b/rpython/jit/backend/llsupport/test/test_regalloc.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc.py
@@ -379,48 +379,23 @@
def test_hint_frame_locations_1(self):
- py.test.skip("xxx")
- b0, = newboxes(0)
- fm = TFrameManager()
- loc123 = FakeFramePos(123, INT)
- fm.hint_frame_locations[b0] = loc123
- assert fm.get_frame_depth() == 0
- loc = fm.loc(b0)
- assert loc == loc123
- assert fm.get_frame_depth() == 124
-
- def test_hint_frame_locations_2(self):
- py.test.skip("xxx")
- b0, b1, b2 = newboxes(0, 1, 2)
- longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)}
- fm = TFrameManager()
- asm = MockAsm()
- rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
- rm.force_allocate_reg(b0)
- rm.force_allocate_reg(b1)
- rm.force_allocate_reg(b2)
- rm.force_spill_var(b0)
- loc = rm.loc(b0)
- assert isinstance(loc, FakeFramePos)
- assert fm.get_loc_index(loc) == 0
- rm.position = 1
- assert fm.used == [True]
- rm.possibly_free_var(b0)
- assert fm.used == [False]
- #
- fm.hint_frame_locations[b1] = loc
- rm.force_spill_var(b1)
- loc1 = rm.loc(b1)
- assert loc1 == loc
- assert fm.used == [True]
- #
- fm.hint_frame_locations[b2] = loc
- rm.force_spill_var(b2)
- loc2 = rm.loc(b2)
- assert loc2 != loc1 # because it was not free
- assert fm.used == [True, True]
- #
- rm._check_invariants()
+ for hint_value in range(11):
+ b0, = newboxes(0)
+ fm = TFrameManager()
+ fm.hint_frame_pos[b0] = hint_value
+ blist = newboxes(*range(10))
+ for b1 in blist:
+ fm.loc(b1)
+ for b1 in blist:
+ fm.mark_as_free(b1)
+ assert fm.get_frame_depth() == 10
+ loc = fm.loc(b0)
+ if hint_value < 10:
+ expected = hint_value
+ else:
+ expected = 0
+ assert fm.get_loc_index(loc) == expected
+ assert fm.get_frame_depth() == 10
def test_linkedlist(self):
class Loc(object):
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
@@ -1197,7 +1197,6 @@
# optimization only: fill in the 'hint_frame_locations' dictionary
# of 'fm' based on the JUMP at the end of the loop, by looking
# at where we would like the boxes to be after the jump.
- return # XXX disabled for now
op = operations[-1]
if op.getopnum() != rop.JUMP:
return
@@ -1223,7 +1222,7 @@
if isinstance(box, Box):
loc = arglocs[i]
if isinstance(loc, FrameLoc):
- self.fm.hint_frame_locations[box] = loc
+ self.fm.hint_frame_pos[box] = self.fm.get_loc_index(loc)
def consider_jump(self, op):
assembler = self.assembler
@@ -1325,13 +1324,9 @@
# end of the same loop, i.e. if what we are compiling is a single
# loop that ends up jumping to this LABEL, then we can now provide
# the hints about the expected position of the spilled variables.
-
- # XXX we never compile code like that?
- # YYY of course, because compute_hint_frame_locations() is disabled.
- # re-enable this once we re-enable it!
- #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)
+ 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)
def consider_guard_not_forced_2(self, op):
self.rm.before_call(op.getfailargs(), save_all_regs=True)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit