re PR target/40657 (allocate local variables with fewer instructions)
PR target/40657 * config/arm/arm.c (thumb1_extra_regs_pushed): New function. (thumb1_expand_prologue, thumb1_output_function_prologue): Call it here to determine which regs to push and how much stack to reserve. PR target/40657 * gcc.target/arm/thumb-stackframe.c: New test. From-SVN: r158771
This commit is contained in:
parent
a502783080
commit
cb751cbd75
@ -1,3 +1,10 @@
|
||||
2010-04-27 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
PR target/40657
|
||||
* config/arm/arm.c (thumb1_extra_regs_pushed): New function.
|
||||
(thumb1_expand_prologue, thumb1_output_function_prologue): Call it
|
||||
here to determine which regs to push and how much stack to reserve.
|
||||
|
||||
2010-04-27 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
* doc/gimple.texi (gimple_statement_with_ops): Remove
|
||||
|
@ -19402,6 +19402,51 @@ thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to)
|
||||
}
|
||||
}
|
||||
|
||||
/* Given the stack offsets and register mask in OFFSETS, decide
|
||||
how many additional registers to push instead of subtracting
|
||||
a constant from SP. */
|
||||
static int
|
||||
thumb1_extra_regs_pushed (arm_stack_offsets *offsets)
|
||||
{
|
||||
HOST_WIDE_INT amount = offsets->outgoing_args - offsets->saved_regs;
|
||||
unsigned long live_regs_mask = offsets->saved_regs_mask;
|
||||
/* Extract a mask of the ones we can give to the Thumb's push instruction. */
|
||||
unsigned long l_mask = live_regs_mask & 0x40ff;
|
||||
/* Then count how many other high registers will need to be pushed. */
|
||||
unsigned long high_regs_pushed = bit_count (live_regs_mask & 0x0f00);
|
||||
int n_free;
|
||||
|
||||
/* If the stack frame size is 512 exactly, we can save one load
|
||||
instruction, which should make this a win even when optimizing
|
||||
for speed. */
|
||||
if (!optimize_size && amount != 512)
|
||||
return 0;
|
||||
|
||||
/* Can't do this if there are high registers to push, or if we
|
||||
are not going to do a push at all. */
|
||||
if (high_regs_pushed != 0 || l_mask == 0)
|
||||
return 0;
|
||||
|
||||
/* Don't do this if thumb1_expand_prologue wants to emit instructions
|
||||
between the push and the stack frame allocation. */
|
||||
if ((flag_pic && arm_pic_register != INVALID_REGNUM)
|
||||
|| (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0))
|
||||
return 0;
|
||||
|
||||
for (n_free = 0; n_free < 8 && !(live_regs_mask & 1); live_regs_mask >>= 1)
|
||||
n_free++;
|
||||
|
||||
if (n_free == 0)
|
||||
return 0;
|
||||
gcc_assert (amount / 4 * 4 == amount);
|
||||
|
||||
if (amount >= 512 && (amount - n_free * 4) < 512)
|
||||
return (amount - 508) / 4;
|
||||
if (amount <= n_free * 4)
|
||||
return amount / 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate the rest of a function's prologue. */
|
||||
void
|
||||
thumb1_expand_prologue (void)
|
||||
@ -19438,6 +19483,7 @@ thumb1_expand_prologue (void)
|
||||
stack_pointer_rtx);
|
||||
|
||||
amount = offsets->outgoing_args - offsets->saved_regs;
|
||||
amount -= 4 * thumb1_extra_regs_pushed (offsets);
|
||||
if (amount)
|
||||
{
|
||||
if (amount < 512)
|
||||
@ -19742,7 +19788,11 @@ thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
|
||||
register. */
|
||||
else if ((l_mask & 0xff) != 0
|
||||
|| (high_regs_pushed == 0 && l_mask))
|
||||
thumb_pushpop (f, l_mask, 1, &cfa_offset, l_mask);
|
||||
{
|
||||
unsigned long mask = l_mask;
|
||||
mask |= (1 << thumb1_extra_regs_pushed (offsets)) - 1;
|
||||
thumb_pushpop (f, mask, 1, &cfa_offset, mask);
|
||||
}
|
||||
|
||||
if (high_regs_pushed)
|
||||
{
|
||||
|
@ -1,3 +1,8 @@
|
||||
2010-04-27 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
PR target/40657
|
||||
* gcc.target/arm/thumb-stackframe.c: New test.
|
||||
|
||||
2010-04-27 Shujing Zhao <pearly.zhao@oracle.com>
|
||||
|
||||
* gcc.dg/pr32207.c: Fix typo in expected warning messages.
|
||||
|
13
gcc/testsuite/gcc.target/arm/thumb-stackframe.c
Normal file
13
gcc/testsuite/gcc.target/arm/thumb-stackframe.c
Normal file
@ -0,0 +1,13 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-mthumb -Os" } */
|
||||
/* { dg-require-effective-target arm_thumb1_ok } */
|
||||
|
||||
extern void bar(int*);
|
||||
int foo()
|
||||
{
|
||||
int x;
|
||||
bar(&x);
|
||||
return x;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "sub\[\\t \]*sp,\[\\t \]*sp," } } */
|
Loading…
Reference in New Issue
Block a user