Author: Richard Plangger <planri...@gmail.com>
Branch: s390x-backend
Changeset: r81759:97bc3df81867
Date: 2016-01-14 12:26 +0100
http://bitbucket.org/pypy/pypy/changeset/97bc3df81867/

Log:    rewritten the last step of force_allocate_register, it could have
        taken (odd, even) instead of (even, odd) adding 1 word more space to
        the stack to remap_frame_layout (if it needs stack space to break
        the cycle)

diff --git a/rpython/jit/backend/test/test_random.py 
b/rpython/jit/backend/test/test_random.py
--- a/rpython/jit/backend/test/test_random.py
+++ b/rpython/jit/backend/test/test_random.py
@@ -786,11 +786,14 @@
                 arguments.append(box.getfloatstorage())
             else:
                 assert 0, box.type
+        #import pdb; pdb.set_trace()
         deadframe = cpu.execute_token(self.runjitcelltoken(), *arguments)
         fail = cpu.get_latest_descr(deadframe)
+        print("exited at %s" % (fail, ))
         do_assert(fail is self.should_fail_by.getdescr(),
                   "Got %r, expected %r" % (fail,
                                            self.should_fail_by.getdescr()))
+        values = []
         for i, v in enumerate(self.get_fail_args()):
             if v not in self.expected:
                 assert v.getopnum() == rop.SAME_AS_I   # special case
@@ -805,6 +808,8 @@
                                                        self.expected[v],
                                                        i)
                 )
+            values.append(value)
+        #import pdb; pdb.set_trace()
         exc = cpu.grab_exc_value(deadframe)
         if (self.guard_op is not None and
             self.guard_op.is_guard_exception()):
@@ -839,6 +844,7 @@
             _fail_box.set_forwarded(None)
         # generate the branch: a sequence of operations that ends in a FINISH
         subloop = DummyLoop([])
+        subloop.inputargs = op.getfailargs()[:]
         self.subloops.append(subloop)   # keep around for debugging
         if guard_op.is_guard_exception():
             subloop.operations.append(exc_handling(guard_op))
diff --git a/rpython/jit/backend/test/zll_stress.py 
b/rpython/jit/backend/test/zll_stress.py
--- a/rpython/jit/backend/test/zll_stress.py
+++ b/rpython/jit/backend/test/zll_stress.py
@@ -19,4 +19,5 @@
     r = Random()
     r.jumpahead(piece*99999999)
     for i in range(piece*per_piece, (piece+1)*per_piece):
+        print("got", i, r.getstate())
         check_random_function(cpu, LLtypeOperationBuilder, r, i, 
total_iterations)
diff --git a/rpython/jit/backend/zarch/callbuilder.py 
b/rpython/jit/backend/zarch/callbuilder.py
--- a/rpython/jit/backend/zarch/callbuilder.py
+++ b/rpython/jit/backend/zarch/callbuilder.py
@@ -82,6 +82,11 @@
         if self.is_call_release_gil:
             self.subtracted_to_sp += 8*WORD
             base -= 8*WORD
+        # one additional owrd for remap frame layout
+        # regalloc_push will overwrite -8(r.SP) and destroy
+        # a parameter if we would not reserve that space
+        base -= WORD
+        self.subtracted_to_sp += WORD
         for idx,i in enumerate(stack_params):
             loc = arglocs[i]
             offset = base + 8 * idx
@@ -100,6 +105,7 @@
                     self.asm.regalloc_mov(loc, src)
                 self.mc.STG(src, l.addr(offset, r.SP))
 
+
         # We must also copy fnloc into FNREG
         non_float_locs.append(self.fnloc)
         non_float_regs.append(r.RETURN)
@@ -113,6 +119,7 @@
         remap_frame_layout(self.asm, non_float_locs, non_float_regs,
                            r.SCRATCH)
 
+
     def push_gcmap(self):
         # we push *now* the gcmap, describing the status of GC registers
         # after the rearrangements done just before, ignoring the return
diff --git a/rpython/jit/backend/zarch/regalloc.py 
b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -208,14 +208,16 @@
                 del self.free_regs[i]
                 i = self.free_regs.index(odd)
                 del self.free_regs[i]
+                assert even.is_even() and odd.is_odd()
                 return even, odd
             else:
                 # an odd free register, maybe the even one is
                 # a candidate?
                 odd = even
-                even = REGS[even.value-1]
+                even = REGS[odd.value-1]
                 if even in r.MANAGED_REGS and even not in self.free_regs:
                     # yes even might be a candidate
+                    # this means that odd is free, but not even
                     candidates.append(even)
             i -= 1
 
@@ -244,44 +246,55 @@
             if candidate is not None:
                 # well, we got away with a single spill :)
                 reg = self.reg_bindings[candidate]
-                self.force_spill_var(candidate)
+                self._sync_var(candidate)
+                del self.reg_bindings[candidate]
                 if reg.is_even():
+                    assert var is not candidate
                     self.reg_bindings[var] = reg
                     rmfree = REGS[reg.value+1]
-                    rmidx = self.free_regs.index(reg)
-                    del self.free_regs[rmidx]
                     self.reg_bindings[var2] = rmfree
-                    rmidx = self.free_regs.index(rmfree)
-                    del self.free_regs[rmidx]
+                    self.free_regs = [fr for fr in self.free_regs if fr is not 
rmfree]
                     return reg, rmfree
                 else:
+                    assert var2 is not candidate
                     self.reg_bindings[var2] = reg
-                    rmidx = self.free_regs.index(reg)
-                    del self.free_regs[rmidx]
                     rmfree = REGS[reg.value-1]
                     self.reg_bindings[var] = rmfree
-                    rmidx = self.free_regs.index(rmfree)
-                    del self.free_regs[rmidx]
+                    self.free_regs = [fr for fr in self.free_regs if fr is not 
rmfree]
                     return rmfree, reg
 
         # there is no candidate pair that only would
         # require one spill, thus we need to spill two!
+        # this is a rare case!
+        reverse_mapping = { reg : var for var, reg in 
self.reg_bindings.items() }
         # always take the first
         for i, reg in enumerate(r.MANAGED_REGS):
+            if i % 2 == 1:
+                continue
             if i+1 < len(r.MANAGED_REGS):
                 reg2 = r.MANAGED_REGS[i+1]
-                try:
-                    even = self._spill_var(var, forbidden_vars, reg)
-                    odd = self._spill_var(var2, forbidden_vars, reg2)
-                except NoVariableToSpill:
-                    # woops, this is in efficient
+                assert reg.is_even() and reg2.is_odd()
+                ovar = reverse_mapping[reg]
+                ovar2 = reverse_mapping[reg2]
+                if ovar in forbidden_vars or ovar2 in forbidden_vars:
+                    # blocked, try other register pair
                     continue
+                even = reg
+                odd = reg2
+                self._sync_var(ovar)
+                self._sync_var(ovar2)
+                del self.reg_bindings[ovar]
+                del self.reg_bindings[ovar2]
+                # both are not added to free_regs! no need to do so
                 self.reg_bindings[var] = even
                 self.reg_bindings[var2] = odd
                 break
         else:
             # no break! this is bad. really bad
             raise NoVariableToSpill()
+
+        reverse_mapping = None
+
         return even, odd
 
     def force_result_in_even_reg(self, result_v, loc, forbidden_vars=[]):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to