[pypy-commit] pypy default: avoid pushing a register when moving values around if we have a free register to use
bivab
noreply at buildbot.pypy.org
Fri Mar 22 09:32:26 CET 2013
Author: David Schneider <david.schneider at picle.org>
Branch:
Changeset: r62644:33776a88f16c
Date: 2013-03-22 10:29 +0200
http://bitbucket.org/pypy/pypy/changeset/33776a88f16c/
Log: avoid pushing a register when moving values around if we have a free
register to use
diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -1036,6 +1036,7 @@
assert 0, 'unsupported case'
def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL):
+ helper = self._regalloc.get_free_reg()
if loc.is_reg():
assert prev_loc.type != FLOAT, 'trying to load from an \
incompatible location into a core register'
@@ -1044,24 +1045,24 @@
# unspill a core register
offset = prev_loc.value
is_imm = check_imm_arg(offset, size=0xFFF)
- if not is_imm:
- self.mc.PUSH([r.lr.value], cond=cond)
- self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.lr)
- if not is_imm:
- self.mc.POP([r.lr.value], cond=cond)
+ helper = r.lr if helper is None else helper
+ save_helper = not is_imm and helper is r.lr
elif loc.is_vfp_reg():
assert prev_loc.type == FLOAT, 'trying to load from an \
incompatible location into a float register'
# load spilled value into vfp reg
offset = prev_loc.value
is_imm = check_imm_arg(offset)
- if not is_imm:
- self.mc.PUSH([r.ip.value], cond=cond)
- self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.ip)
- if not is_imm:
- self.mc.POP([r.ip.value], cond=cond)
+ helper = r.ip if helper is None else helper
+ save_helper = not is_imm and helper is r.ip
else:
assert 0, 'unsupported case'
+ if save_helper:
+ self.mc.PUSH([helper.value], cond=cond)
+ self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=helper)
+ if save_helper:
+ self.mc.POP([helper.value], cond=cond)
+
def _mov_imm_float_to_loc(self, prev_loc, loc, cond=c.AL):
if loc.is_vfp_reg():
diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -166,6 +166,13 @@
selected_reg=selected_reg)
return reg
+ def get_free_reg():
+ free_regs = self.free_regs
+ for i in range(len(free_regs), -1, -1):
+ if free_regs[i] in self.save_around_call_regs:
+ continue
+ return free_regs[i]
+
class Regalloc(BaseRegalloc):
@@ -250,6 +257,8 @@
selected_reg)
else:
return self.rm.get_scratch_reg(type, forbidden_vars, selected_reg)
+ def get_free_reg(self):
+ return self.rm.get_free_reg()
def free_temp_vars(self):
self.rm.free_temp_vars()
diff --git a/rpython/jit/backend/arm/test/test_regalloc_mov.py b/rpython/jit/backend/arm/test/test_regalloc_mov.py
--- a/rpython/jit/backend/arm/test/test_regalloc_mov.py
+++ b/rpython/jit/backend/arm/test/test_regalloc_mov.py
@@ -64,11 +64,15 @@
self.instrs.append(i)
return i
+class MockRegalloc(object):
+ def get_free_reg(self):
+ return r('helper')
class BaseMovTest(object):
def setup_method(self, method):
self.builder = MockBuilder()
self.asm = instantiate(AssemblerARM)
+ self.asm._regalloc = MockRegalloc()
self.asm.mc = self.builder
def validate(self, expected):
@@ -170,10 +174,8 @@
s = stack(8191)
r6 = r(6)
expected = [
- mi('PUSH', [lr.value], cond=AL),
- mi('gen_load_int', lr.value, s.value, cond=AL),
- mi('LDR_rr', r6.value, fp.value, lr.value, cond=AL),
- mi('POP', [lr.value], cond=AL)]
+ mi('gen_load_int', 'helper', s.value, cond=AL),
+ mi('LDR_rr', r6.value, fp.value, 'helper', cond=AL)]
self.mov(s, r6, expected)
def test_mov_float_imm_to_vfp_reg(self):
@@ -195,7 +197,7 @@
def test_mov_vfp_reg_to_stack(self):
reg = vfp(7)
s = stack_float(3)
- expected = [mi('VSTR', reg.value, fp.value, imm=188, cond=AL)]
+ expected = [mi('VSTR', reg.value, fp.value, imm=192, cond=AL)]
self.mov(reg, s, expected)
def test_mov_vfp_reg_to_large_stackloc(self):
@@ -211,7 +213,7 @@
def test_mov_stack_to_vfp_reg(self):
reg = vfp(7)
s = stack_float(3)
- expected = [mi('VLDR', reg.value, fp.value, imm=188, cond=AL)]
+ expected = [mi('VLDR', reg.value, fp.value, imm=192, cond=AL)]
self.mov(s, reg, expected)
def test_mov_big_stackloc_to_vfp_reg(self):
@@ -420,10 +422,8 @@
def test_push_big_stack(self):
s = stack(1025)
- e = [mi('PUSH', [lr.value], cond=AL),
- mi('gen_load_int', lr.value, s.value, cond=AL),
- mi('LDR_rr', ip.value, fp.value, lr.value, cond=AL),
- mi('POP', [lr.value], cond=AL),
+ e = [mi('gen_load_int', 'helper', s.value, cond=AL),
+ mi('LDR_rr', ip.value, fp.value, 'helper', cond=AL),
mi('PUSH', [ip.value], cond=AL)
]
self.push(s, e)
@@ -436,7 +436,7 @@
def test_push_stack_float(self):
sf = stack_float(4)
e = [
- mi('VLDR', vfp_ip.value, fp.value, imm=192, cond=AL),
+ mi('VLDR', vfp_ip.value, fp.value, imm=196, cond=AL),
mi('VPUSH', [vfp_ip.value], cond=AL),
]
self.push(sf, e)
@@ -444,11 +444,9 @@
def test_push_large_stackfloat(self):
sf = stack_float(100)
e = [
- mi('PUSH', [ip.value], cond=AL),
- mi('gen_load_int', ip.value, sf.value, cond=AL),
- mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
- mi('VLDR', vfp_ip.value, ip.value, cond=AL),
- mi('POP', [ip.value], cond=AL),
+ mi('gen_load_int', 'helper', sf.value, cond=AL),
+ mi('ADD_rr', 'helper', fp.value, 'helper', cond=AL),
+ mi('VLDR', vfp_ip.value, 'helper', cond=AL),
mi('VPUSH', [vfp_ip.value], cond=AL),
]
self.push(sf, e)
More information about the pypy-commit
mailing list