Commit 01037aeb by Eric Botcazou Committed by Eric Botcazou

arm.c (arm_r3_live_at_start_p): New predicate.

	* config/arm/arm.c (arm_r3_live_at_start_p): New predicate.
	(arm_compute_static_chain_stack_bytes): Use it.  Tidy up.
	(arm_expand_prologue): Likewise.

From-SVN: r199752
parent a5aef1da
2013-06-06 Eric Botcazou <ebotcazou@adacore.com>
* config/arm/arm.c (arm_r3_live_at_start_p): New predicate.
(arm_compute_static_chain_stack_bytes): Use it. Tidy up.
(arm_expand_prologue): Likewise.
2013-06-06 Teresa Johnson <tejohnson@google.com> 2013-06-06 Teresa Johnson <tejohnson@google.com>
PR c++/53743 PR c++/53743
......
...@@ -16178,25 +16178,34 @@ arm_compute_save_reg0_reg12_mask (void) ...@@ -16178,25 +16178,34 @@ arm_compute_save_reg0_reg12_mask (void)
return save_reg_mask; return save_reg_mask;
} }
/* Return true if r3 is live at the start of the function. */
static bool
arm_r3_live_at_start_p (void)
{
/* Just look at cfg info, which is still close enough to correct at this
point. This gives false positives for broken functions that might use
uninitialized data that happens to be allocated in r3, but who cares? */
return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR), 3);
}
/* Compute the number of bytes used to store the static chain register on the /* Compute the number of bytes used to store the static chain register on the
stack, above the stack frame. We need to know this accurately to get the stack, above the stack frame. We need to know this accurately to get the
alignment of the rest of the stack frame correct. */ alignment of the rest of the stack frame correct. */
static int arm_compute_static_chain_stack_bytes (void) static int
arm_compute_static_chain_stack_bytes (void)
{ {
unsigned long func_type = arm_current_func_type (); /* See the defining assertion in arm_expand_prologue. */
int static_chain_stack_bytes = 0; if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM
&& IS_NESTED (arm_current_func_type ())
if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM && && arm_r3_live_at_start_p ()
IS_NESTED (func_type) && && crtl->args.pretend_args_size == 0)
df_regs_ever_live_p (3) && crtl->args.pretend_args_size == 0) return 4;
static_chain_stack_bytes = 4;
return static_chain_stack_bytes; return 0;
} }
/* Compute a bit mask of which registers need to be /* Compute a bit mask of which registers need to be
saved on the stack for the current function. saved on the stack for the current function.
This is used by arm_get_frame_offsets, which may add extra registers. */ This is used by arm_get_frame_offsets, which may add extra registers. */
...@@ -18151,16 +18160,16 @@ arm_expand_prologue (void) ...@@ -18151,16 +18160,16 @@ arm_expand_prologue (void)
} }
else if (IS_NESTED (func_type)) else if (IS_NESTED (func_type))
{ {
/* The Static chain register is the same as the IP register /* The static chain register is the same as the IP register
used as a scratch register during stack frame creation. used as a scratch register during stack frame creation.
To get around this need to find somewhere to store IP To get around this need to find somewhere to store IP
whilst the frame is being created. We try the following whilst the frame is being created. We try the following
places in order: places in order:
1. The last argument register. 1. The last argument register r3.
2. A slot on the stack above the frame. (This only 2. A slot on the stack above the frame. (This only
works if the function is not a varargs function). works if the function is not a varargs function).
3. Register r3, after pushing the argument registers 3. Register r3 again, after pushing the argument registers
onto the stack. onto the stack.
Note - we only need to tell the dwarf2 backend about the SP Note - we only need to tell the dwarf2 backend about the SP
...@@ -18168,7 +18177,7 @@ arm_expand_prologue (void) ...@@ -18168,7 +18177,7 @@ arm_expand_prologue (void)
doesn't need to be unwound, as it doesn't contain a value doesn't need to be unwound, as it doesn't contain a value
inherited from the caller. */ inherited from the caller. */
if (df_regs_ever_live_p (3) == false) if (!arm_r3_live_at_start_p ())
insn = emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx); insn = emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
else if (args_to_push == 0) else if (args_to_push == 0)
{ {
...@@ -18309,8 +18318,7 @@ arm_expand_prologue (void) ...@@ -18309,8 +18318,7 @@ arm_expand_prologue (void)
if (IS_NESTED (func_type)) if (IS_NESTED (func_type))
{ {
/* Recover the static chain register. */ /* Recover the static chain register. */
if (!df_regs_ever_live_p (3) if (!arm_r3_live_at_start_p () || saved_pretend_args)
|| saved_pretend_args)
insn = gen_rtx_REG (SImode, 3); insn = gen_rtx_REG (SImode, 3);
else /* if (crtl->args.pretend_args_size == 0) */ else /* if (crtl->args.pretend_args_size == 0) */
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment