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