[pypy-svn] r64971 - pypy/branch/pyjitpl5/pypy/jit/backend/x86

arigo at codespeak.net arigo at codespeak.net
Sat May 2 12:43:47 CEST 2009


Author: arigo
Date: Sat May  2 12:43:47 2009
New Revision: 64971

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
Log:
Fix test_random by "fixing" consider_jump().  Actually, this is a
rewrite, making consider_jump() much simpler than the code that was
there until r64970.  At least it's bug-free (hopefully).  We can then go
on optimizing it again.


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	Sat May  2 12:43:47 2009
@@ -319,6 +319,12 @@
 
     regalloc_store = regalloc_load
 
+    def regalloc_push(self, loc):
+        self.mc.PUSH(loc)
+
+    def regalloc_pop(self, loc):
+        self.mc.POP(loc)
+
     def regalloc_perform(self, op, arglocs, resloc):
         genop_list[op.opnum](self, op, arglocs, resloc)
 

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	Sat May  2 12:43:47 2009
@@ -1103,78 +1103,35 @@
     consider_unicodegetitem = consider_strgetitem
 
     def consider_jump(self, op, ignored):
-        later_loads = []
-        reloaded = []
-        middle_busy_regs = []
+        # This is a simplified version of the code that was there until r64970.
+        # At least it's bug-free (hopefully).  We can then go on optimizing
+        # it again.
+        later_pops = []     # pops that will be performed in reverse order
+        extra_on_stack = 0
+        loop = op.jump_target
         for i in range(len(op.args)):
             arg = op.args[i]
-            loop = op.jump_target
+            src = self.loc(arg)
             res = loop.arglocs[i]
-            if not (isinstance(arg, Const) or (arg in self.loop_consts
-                                               and self.loop_consts[arg] == i)):
-                if arg in self.reg_bindings:
-                    if not isinstance(res, REG):
-                        self.Store(arg, self.loc(arg), loop.arglocs[i])
-                        # XXX ^^^^^^ this can overwrite random stuff
-                    elif res is self.reg_bindings[arg]:
-                        middle_busy_regs.append(res)
-                    else:
-                        # register, but wrong
-                        # we're going to need it (otherwise it'll be dead), so
-                        # we spill it and reload
-                        # if our register is free, easy
-                        for v, reg in self.reg_bindings.items():
-                            if reg is res:
-                                self.Store(arg, self.loc(arg),
-                                           self.stack_loc(arg))
-                                later_loads.append((arg, self.stack_loc(arg),
-                                                    res))
-                                break
-                        else:
-                            self.Load(arg, self.loc(arg), res)
-                else:
-                    if arg not in self.stack_bindings:
-                        # we can load it correctly, because we don't care
-                        # any more about the previous var staying there
-                        assert False  # XXX (arigo) what is this case???
-                                      # XXX it's not hit by any test...
-                        assert not isinstance(res, REG)
-                        self.Store(arg, self.loc(arg), res)
-                    else:
-                        assert arg not in self.dirty_stack
-                        if isinstance(res, REG):
-                            later_loads.append((arg, self.loc(arg), res))
-                        else:
-                            arg0 = self.loc(arg)
-                            assert isinstance(arg0, MODRM)
-                            assert isinstance(res, MODRM)
-                            if arg0.position != res.position:
-                                reloaded.append((arg, self.loc(arg), res))
-            elif isinstance(arg, Const):
-                later_loads.append((arg, self.loc(arg), res))
-        if reloaded:
-            # XXX performance
-            free_reg = None
-            for reg in REGS:
-                if reg not in middle_busy_regs:
-                    free_reg = reg
-                    break
-            if free_reg is None:
-                # a very rare case
-                v = self.reg_bindings.keys()[0]
-                free_reg = self.reg_bindings[v]
-                self.Store(v, self.loc(v), self.stack_loc(v))
-                later_loads.insert(0, (v, self.stack_loc(v), self.loc(v)))
-            # XXX this is wrong, we can easily overwrite stuff that is on
-            #     stack, we need to do this in a correct order to avoid that
-            for v, from_l, to_l in reloaded:
-                self.Load(v, from_l, free_reg)
-                self.Store(v, free_reg, to_l)
-            # XXX ^^^^^^^^^^^^^^^^^^^^^^^^^^^ BORKEN
+            if src is res:
+                continue      # nothing needed to copy in this case
+            if (isinstance(src, MODRM) and
+                isinstance(res, MODRM) and
+                src.position == res.position):
+                continue      # already at the correct stack position
+            # write the code that moves the correct value into 'res', in two
+            # steps: generate a pair PUSH (immediately) / POP (later)
+            if isinstance(src, MODRM):
+                src = stack_pos(src.position + extra_on_stack)
+            if isinstance(res, MODRM):
+                res = stack_pos(res.position + extra_on_stack)
+            self.assembler.regalloc_push(src)
+            later_pops.append(res)
+            extra_on_stack += 1
+            #
         self.eventually_free_vars(op.args)
-        for v, from_l, to_l in later_loads:
-            self.Load(v, from_l, to_l)
-        # XXX ^^^^^ broken: the stack locations in from_l are overwritten above
+        for i in range(len(later_pops)-1, -1, -1):
+            self.assembler.regalloc_pop(later_pops[i])
         self.PerformDiscard(op, [])
 
     def not_implemented_op(self, op, ignored):



More information about the Pypy-commit mailing list