[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