[pypy-commit] pypy s390x-backend: finished implementation to allocate a register pair (even/odd), added test case to ensure the spilling is done correctly
plan_rich
noreply at buildbot.pypy.org
Tue Nov 17 08:37:09 EST 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80730:0b2023218277
Date: 2015-11-17 14:37 +0100
http://bitbucket.org/pypy/pypy/changeset/0b2023218277/
Log: finished implementation to allocate a register pair (even/odd),
added test case to ensure the spilling is done correctly
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
@@ -193,7 +193,7 @@
# a candidate?
odd = even
even = REGS[even.value-1]
- if even in r.MANAGED_REGS:
+ if even in r.MANAGED_REGS and even not in self.free_regs:
# yes even might be a candidate
candidates.append(even)
i -= 1
@@ -209,11 +209,17 @@
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
+ reg2 = None
+ if reg.is_even():
+ reg2 = REGS[reg.value+1]
+ else:
+ reg2 = REGS[reg.value-1]
+ if reg2 not in r.MANAGED_REGS:
+ continue
+ 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]
@@ -221,12 +227,16 @@
if reg.is_even():
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]
return reg, rmfree
else:
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)
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
@@ -138,6 +138,61 @@
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
- pass
+
+
+ @py.test.mark.parametrize('value', [2,3,15,2**16,-2**5])
+ def test_double_evenodd_pair_extensive(self, value):
+ instrs = []
+ failargs = []
+ values = []
+ j = 0
+ mapping = (('int_floordiv',lambda x,y: x // y),
+ ('int_mod', lambda x,y: x % y),
+ ('int_mul_ovf', lambda x,y: x * y))
+ for i in range(20):
+ name, func = mapping[j]
+ instrs.append("i{d} = {i}(i0, {d})".format(d=i+1, i=name))
+ values.append((name, func(value, i+1)))
+ failargs.append("i" + str(i+1))
+ j += 1
+ if j >= len(mapping):
+ j = 0
+ code = """
+ [i0]
+ {instrs}
+ i99 = int_add(i0, 1)
+ i100 = int_eq(i0,i99)
+ guard_true(i100) [{failargs}] # will always fail!!
+ finish(i0, descr=faildescr)
+ """.format(instrs=('\n' +' '*8).join(instrs), failargs=','.join(failargs))
+ # 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, value)
+ fail = self.cpu.get_latest_descr(deadframe)
+ for i,(name, v) in enumerate(values):
+ assert self.cpu.get_int_value(deadframe, i) == v
+
+ @py.test.mark.parametrize('v1,v2', [
+ (-32,3),
+ ])
+ def test_int_mul_no_overflow(self, v1, v2):
+ try:
+ result = v1*v2
+ except OverflowError:
+ py.test.skip("this test is not made to check the overflow!")
+ code = """
+ [i0]
+ i1 = int_mul_ovf(i0,{v})
+ finish(i1, descr=faildescr)
+ """.format(v=v2)
+ 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, v1)
+ fail = self.cpu.get_latest_descr(deadframe)
+ assert self.cpu.get_int_value(deadframe, 0) == result
+
More information about the pypy-commit
mailing list