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

Reply via email to