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
This commit is contained in:
Jakub Jelinek 2011-01-25 17:22:34 +01:00
parent e3bb089d5f
commit 147a0bcfc7
6 changed files with 117 additions and 2 deletions

View file

@ -1,3 +1,9 @@
2011-01-25 Jakub Jelinek <jakub@redhat.com>
PR target/45701
* config/arm/arm.c (any_sibcall_uses_r3): New function.
(arm_get_frame_offsets): Use it.
2011-01-25 Sebastian Pop <sebastian.pop@amd.com>
Jakub Jelinek <jakub@redhat.com>

View file

@ -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)
{

View file

@ -1,3 +1,10 @@
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.
2011-01-25 Sebastian Pop <sebastian.pop@amd.com>
Jakub Jelinek <jakub@redhat.com>

View file

@ -0,0 +1,24 @@
/* { dg-do compile } */
/* { dg-options "-march=armv7-a -mthumb -Os" } */
/* { dg-final { scan-assembler "push\t\{r3" } } */
/* { dg-final { scan-assembler-not "r8" } } */
extern int hist_verify;
extern char *pre_process_line (char*);
extern char* str_cpy (char*, char*);
extern int str_len (char*);
extern char* x_malloc (int);
#define savestring(x) (char *)str_cpy (x_malloc (1 + str_len (x)), (x))
char *
history_expand_line_internal (char* line)
{
char *new_line;
int old_verify;
old_verify = hist_verify;
hist_verify = 0;
new_line = pre_process_line (line);
hist_verify = old_verify;
return (new_line == line) ? savestring (line) : new_line;
}

View file

@ -0,0 +1,26 @@
/* { dg-do compile } */
/* { dg-options "-march=armv7-a -mthumb -Os" } */
/* { dg-final { scan-assembler "push\t\{r3" } } */
/* { dg-final { scan-assembler-not "r8" } } */
extern int hist_verify;
extern char *pre_process_line (char*);
extern char* savestring1 (char*, char*);
extern char* str_cpy (char*, char*);
extern int str_len (char*);
extern char* x_malloc (int);
#define savestring(x) (char *)str_cpy (x_malloc (1 + str_len (x)), (x))
char *
history_expand_line_internal (char* line)
{
char *new_line;
int old_verify;
old_verify = hist_verify;
hist_verify = 0;
new_line = pre_process_line (line);
hist_verify = old_verify;
/* Two tail calls here, but r3 is not used to pass values. */
return (new_line == line) ? savestring (line) : savestring1 (new_line, line);
}

View file

@ -0,0 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-march=armv7-a -mthumb -Os" } */
/* { dg-final { scan-assembler "push\t.*r8" } } */
/* { dg-final { scan-assembler-not "push\t*r3" } } */
extern int hist_verify;
extern char *pre_process_line (char*);
extern char* savestring1 (char*, char*, int, int);
extern char* str_cpy (char*, char*);
extern int str_len (char*);
extern char* x_malloc (int);
#define savestring(x) (char *)str_cpy (x_malloc (1 + str_len (x)), (x))
char *
history_expand_line_internal (char* line)
{
char *new_line;
int old_verify;
old_verify = hist_verify;
hist_verify = 0;
new_line = pre_process_line (line);
hist_verify = old_verify;
/* Two tail calls here, but r3 is used to pass values. */
return (new_line == line) ? savestring (line) :
savestring1 (new_line, line, 0, old_verify+1);
}