aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2011-01-25 17:22:34 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-01-25 17:22:34 +0100
commit147a0bcfc784a28e4ef09e32b23703e0ecc8bd55 (patch)
tree6a328ab7d4f4bb2cbfff4134c3f6a1f217336905 /gcc/config
parente3bb089d5f7f4d615c3cf71acacbb89a89287a8e (diff)
downloadgcc-147a0bcfc784a28e4ef09e32b23703e0ecc8bd55.zip
gcc-147a0bcfc784a28e4ef09e32b23703e0ecc8bd55.tar.gz
gcc-147a0bcfc784a28e4ef09e32b23703e0ecc8bd55.tar.bz2
re PR target/45701 (Fail to prefer using r3 for padding a push/pop multiple to 8-byte alignment)
PR target/45701 * config/arm/arm.c (any_sibcall_uses_r3): New function. (arm_get_frame_offsets): Use it. 2011-01-25 Yao Qi <yao@codesourcery.com> PR target/45701 * gcc.target/arm/pr45701-1.c: New test. * gcc.target/arm/pr45701-2.c: New test. * gcc.target/arm/pr45701-3.c: New test. From-SVN: r169240
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 3e75d7c..be09282 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1,6 +1,6 @@
/* Output routines for GCC for ARM.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
@@ -15188,6 +15188,31 @@ thumb_force_lr_save (void)
}
+/* Return true if r3 is used by any of the tail call insns in the
+ current function. */
+
+static bool
+any_sibcall_uses_r3 (void)
+{
+ edge_iterator ei;
+ edge e;
+
+ if (!crtl->tail_call_emit)
+ return false;
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
+ if (e->flags & EDGE_SIBCALL)
+ {
+ rtx call = BB_END (e->src);
+ if (!CALL_P (call))
+ call = prev_nonnote_nondebug_insn (call);
+ gcc_assert (CALL_P (call) && SIBLING_CALL_P (call));
+ if (find_regno_fusage (call, USE, 3))
+ return true;
+ }
+ return false;
+}
+
+
/* Compute the distance from register FROM to register TO.
These can be the arg pointer (26), the soft frame pointer (25),
the stack pointer (13) or the hard frame pointer (11).
@@ -15352,7 +15377,7 @@ arm_get_frame_offsets (void)
/* If it is safe to use r3, then do so. This sometimes
generates better code on Thumb-2 by avoiding the need to
use 32-bit push/pop instructions. */
- if (!crtl->tail_call_emit
+ if (! any_sibcall_uses_r3 ()
&& arm_size_return_regs () <= 12
&& (offsets->saved_regs_mask & (1 << 3)) == 0)
{