Author: Richard Plangger <[email protected]>
Branch: s390x-backend
Changeset: r80729:5df254e363c4
Date: 2015-11-17 11:41 +0100
http://bitbucket.org/pypy/pypy/changeset/5df254e363c4/
Log: added test to stress register pair allocation (even odd) as it is
needed for division, some invariant is failing still
diff --git a/rpython/jit/backend/zarch/helper/regalloc.py
b/rpython/jit/backend/zarch/helper/regalloc.py
--- a/rpython/jit/backend/zarch/helper/regalloc.py
+++ b/rpython/jit/backend/zarch/helper/regalloc.py
@@ -62,6 +62,7 @@
l1 = self.ensure_reg(a1)
self.rm.force_result_in_reg(op, a0)
self.free_op_vars()
+ self.rm._check_invariants()
return [lr, lq, l1]
def prepare_int_mod(self, op):
diff --git a/rpython/jit/backend/zarch/opassembler.py
b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -56,13 +56,12 @@
mc.BRC(c.ANY, l.imm(mc.BRC_byte_count + bc_set_overflow)) # no
overflow happened
# set overflow!
- mc.XGR(r.SCRATCH, r.SCRATCH)
mc.IPM(r.SCRATCH)
+ # set bit 34 & 35 -> indicates overflow
mc.OILH(r.SCRATCH, l.imm(0x3000)) # sets OF
mc.SPM(r.SCRATCH)
# no overflow happended
- # import pdb; pdb.set_trace()
emit_int_floordiv = gen_emit_pool_or_rr_evenodd('DSG','DSGR')
emit_uint_floordiv = gen_emit_pool_or_rr_evenodd('DLG','DLGR')
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
@@ -1,6 +1,6 @@
from rpython.jit.backend.llsupport.regalloc import (RegisterManager,
FrameManager,
TempVar,
compute_vars_longevity,
- BaseRegalloc)
+ BaseRegalloc,
NoVariableToSpill)
from rpython.jit.backend.llsupport.jump import remap_frame_layout_mixed
from rpython.jit.backend.zarch.arch import WORD
from rpython.jit.codewriter import longlong
@@ -170,32 +170,88 @@
even, odd = None, None
REGS = r.registers
i = len(self.free_regs)-1
+ candidates = []
while i >= 0:
even = self.free_regs[i]
if even.is_even():
+ # found an even registers that is actually free
odd = REGS[even.value+1]
- print even, "is even", odd
if odd not in self.free_regs:
- print odd, "is NOT free"
+ # sadly odd is not free, but for spilling
+ # we found a candidate
+ candidates.append(odd)
+ i -= 1
continue
- print odd, "is free"
self.reg_bindings[var] = even
self.reg_bindings[var2] = odd
del self.free_regs[i]
i = self.free_regs.index(odd)
del self.free_regs[i]
return even, odd
+ else:
+ # an odd free register, maybe the even one is
+ # a candidate?
+ odd = even
+ even = REGS[even.value-1]
+ if even in r.MANAGED_REGS:
+ # yes even might be a candidate
+ candidates.append(even)
i -= 1
- import pdb; pdb.set_trace()
- xxx
- loc = self._spill_var(v, forbidden_vars, selected_reg,
- need_lower_byte=need_lower_byte)
- prev_loc = self.reg_bindings.get(v, None)
- if prev_loc is not None:
- self.free_regs.append(prev_loc)
- self.reg_bindings[v] = loc
- return loc
+ if len(candidates) != 0:
+ cur_max_age = -1
+ candidate = None
+ # pseudo step to find best spilling candidate
+ # similar to _pick_variable_to_spill, but tailored
+ # to take the even/odd register allocation in consideration
+ for next in self.reg_bindings:
+ if next in forbidden_vars:
+ continue
+ reg = self.reg_bindings[next]
+ if reg in candidates:
+ pass
+ max_age = self.longevity[next][1]
+ if cur_max_age < max_age:
+ cur_max_age = max_age
+ candidate = next
+ if candidate is not None:
+ # well, we got away with a single spill :)
+ reg = self.reg_bindings[candidate]
+ self.force_spill_var(candidate)
+ if reg.is_even():
+ self.reg_bindings[var] = reg
+ rmfree = REGS[reg.value+1]
+ self.reg_bindings[var2] = rmfree
+ rmidx = self.free_regs.index(rmfree)
+ del self.free_regs[rmidx]
+ return reg, rmfree
+ else:
+ self.reg_bindings[var2] = reg
+ rmfree = REGS[reg.value-1]
+ self.reg_bindings[var] = rmfree
+ rmidx = self.free_regs.index(rmfree)
+ del self.free_regs[rmidx]
+ return rmfree, reg
+
+ # there is no candidate pair that only would
+ # require one spill, thus we need to spill two!
+ # always take the first
+ for i, reg in enumerate(r.MANAGED_REGS):
+ 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
+ continue
+ self.reg_bindings[var] = even
+ self.reg_bindings[var2] = odd
+ break
+ else:
+ # no break! this is bad. really bad
+ raise NoVariableToSpill()
+ return even, odd
def force_result_in_even_reg(self, result_v, loc, forbidden_vars=[]):
diff --git a/rpython/jit/backend/zarch/test/test_runner.py
b/rpython/jit/backend/zarch/test/test_runner.py
--- a/rpython/jit/backend/zarch/test/test_runner.py
+++ b/rpython/jit/backend/zarch/test/test_runner.py
@@ -106,7 +106,6 @@
loop = parse(code, namespace={"faildescr": BasicFinalDescr(1)})
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- #import pdb; pdb.set_trace()
deadframe = self.cpu.execute_token(looptoken, value)
fail = self.cpu.get_latest_descr(deadframe)
res = self.cpu.get_int_value(deadframe, 0)
@@ -116,8 +115,28 @@
assert res == 0
def test_double_evenodd_pair(self):
- # TODO
- pass
+ code = """
+ [i0]
+ i1 = int_floordiv(i0, 2)
+ i2 = int_floordiv(i0, 3)
+ i3 = int_floordiv(i0, 4)
+ i4 = int_floordiv(i0, 5)
+ i5 = int_floordiv(i0, 6)
+ i6 = int_floordiv(i0, 7)
+ i7 = int_floordiv(i0, 8)
+ i8 = int_le(i1, 0)
+ guard_true(i8) [i1,i2,i3,i4,i5,i6,i7]
+ finish(i0, descr=faildescr)
+ """
+ # the guard forces 3 spills because after 4 divisions
+ # all even slots of the managed registers are full
+ loop = parse(code, namespace={'faildescr': BasicFinalDescr(1)})
+ looptoken = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+ deadframe = self.cpu.execute_token(looptoken, 100)
+ fail = self.cpu.get_latest_descr(deadframe)
+ for i in range(2,9):
+ assert self.cpu.get_int_value(deadframe, i-2) == 100//i
def test_double_evenodd_pair_spill(self):
# TODO
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit