diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-01-25 17:22:34 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-01-25 17:22:34 +0100 |
commit | 147a0bcfc784a28e4ef09e32b23703e0ecc8bd55 (patch) | |
tree | 6a328ab7d4f4bb2cbfff4134c3f6a1f217336905 /gcc/config | |
parent | e3bb089d5f7f4d615c3cf71acacbb89a89287a8e (diff) | |
download | gcc-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.c | 29 |
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) { |