function.c (frame_required_for_rtx): Remove function.

* function.c (frame_required_for_rtx): Remove function.
	(requires_stack_frame_p): New arg set_up_by_prologue.  All callers
	changed.  Compute a set of mentioned registers and compare against
	the new arg rather than calling frame_required_for_rtx.
	(thread_prologue_and_epilogue_insns): Compute the set_up_by_prologue
	reg set.  Convert the unconverted_simple_returns mechanism to store
	jump insns rather than their basic blocks.  Also check the
	orig_entry_edge destination for new blocks.

From-SVN: r179654
This commit is contained in:
Bernd Schmidt 2011-10-07 12:20:17 +00:00 committed by Bernd Schmidt
parent 87aab9b24b
commit 764a2546bb
2 changed files with 56 additions and 29 deletions

View File

@ -1,3 +1,14 @@
2011-10-07 Bernd Schmidt <bernds@codesourcery.com>
* function.c (frame_required_for_rtx): Remove function.
(requires_stack_frame_p): New arg set_up_by_prologue. All callers
changed. Compute a set of mentioned registers and compare against
the new arg rather than calling frame_required_for_rtx.
(thread_prologue_and_epilogue_insns): Compute the set_up_by_prologue
reg set. Convert the unconverted_simple_returns mechanism to store
jump insns rather than their basic blocks. Also check the
orig_entry_edge destination for new blocks.
2011-10-07 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/50650

View File

@ -5303,25 +5303,15 @@ record_hard_reg_uses (rtx *px, void *data)
for_each_rtx (px, record_hard_reg_uses_1, data);
}
/* A subroutine of requires_stack_frame_p, called via for_each_rtx.
Return 1 if we found an rtx that forces a prologue, zero otherwise. */
static int
frame_required_for_rtx (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
rtx x = *loc;
if (x == stack_pointer_rtx || x == hard_frame_pointer_rtx
|| x == arg_pointer_rtx || x == pic_offset_table_rtx)
return 1;
return 0;
}
/* Return true if INSN requires the stack frame to be set up.
PROLOGUE_USED contains the hard registers used in the function
prologue. */
prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the
prologue to set up for the function. */
static bool
requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used)
requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used,
HARD_REG_SET set_up_by_prologue)
{
df_ref *def_rec;
df_ref *df_rec;
HARD_REG_SET hardregs;
unsigned regno;
@ -5329,13 +5319,11 @@ requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used)
return false;
if (CALL_P (insn))
return !SIBLING_CALL_P (insn);
if (for_each_rtx (&PATTERN (insn), frame_required_for_rtx, NULL))
return true;
CLEAR_HARD_REG_SET (hardregs);
for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
for (df_rec = DF_INSN_DEFS (insn); *df_rec; df_rec++)
{
rtx dreg = DF_REF_REG (*def_rec);
rtx dreg = DF_REF_REG (*df_rec);
if (!REG_P (dreg))
continue;
@ -5350,6 +5338,20 @@ requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used)
if (TEST_HARD_REG_BIT (hardregs, regno)
&& df_regs_ever_live_p (regno))
return true;
for (df_rec = DF_INSN_USES (insn); *df_rec; df_rec++)
{
rtx reg = DF_REF_REG (*df_rec);
if (!REG_P (reg))
continue;
add_to_hard_reg_set (&hardregs, GET_MODE (reg),
REGNO (reg));
}
if (hard_reg_set_intersect_p (hardregs, set_up_by_prologue))
return true;
return false;
}
#endif
@ -5455,7 +5457,7 @@ thread_prologue_and_epilogue_insns (void)
basic_block last_bb;
bool last_bb_active ATTRIBUTE_UNUSED;
#ifdef HAVE_simple_return
VEC (basic_block, heap) *unconverted_simple_returns = NULL;
VEC (rtx, heap) *unconverted_simple_returns = NULL;
basic_block simple_return_block_hot = NULL;
basic_block simple_return_block_cold = NULL;
bool nonempty_prologue;
@ -5575,6 +5577,7 @@ thread_prologue_and_epilogue_insns (void)
&& nonempty_prologue && !crtl->calls_eh_return)
{
HARD_REG_SET prologue_clobbered, prologue_used, live_on_edge;
HARD_REG_SET set_up_by_prologue;
rtx p_insn;
VEC(basic_block, heap) *vec;
@ -5610,6 +5613,16 @@ thread_prologue_and_epilogue_insns (void)
vec = VEC_alloc (basic_block, heap, n_basic_blocks);
CLEAR_HARD_REG_SET (set_up_by_prologue);
add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
if (frame_pointer_needed)
add_to_hard_reg_set (&set_up_by_prologue, Pmode,
HARD_FRAME_POINTER_REGNUM);
if (pic_offset_table_rtx)
add_to_hard_reg_set (&set_up_by_prologue, Pmode,
PIC_OFFSET_TABLE_REGNUM);
FOR_EACH_BB (bb)
{
rtx insn;
@ -5628,7 +5641,8 @@ thread_prologue_and_epilogue_insns (void)
}
else
FOR_BB_INSNS (bb, insn)
if (requires_stack_frame_p (insn, prologue_used))
if (requires_stack_frame_p (insn, prologue_used,
set_up_by_prologue))
{
bitmap_set_bit (&bb_flags, bb->index);
VEC_quick_push (basic_block, vec, bb);
@ -5872,8 +5886,8 @@ thread_prologue_and_epilogue_insns (void)
{
#ifdef HAVE_simple_return
if (simple_p)
VEC_safe_push (basic_block, heap,
unconverted_simple_returns, bb);
VEC_safe_push (rtx, heap,
unconverted_simple_returns, jump);
#endif
continue;
}
@ -5891,8 +5905,8 @@ thread_prologue_and_epilogue_insns (void)
{
#ifdef HAVE_simple_return
if (simple_p)
VEC_safe_push (basic_block, heap,
unconverted_simple_returns, bb);
VEC_safe_push (rtx, heap,
unconverted_simple_returns, jump);
#endif
continue;
}
@ -6022,6 +6036,7 @@ epilogue_done:
blocks = sbitmap_alloc (last_basic_block);
sbitmap_zero (blocks);
SET_BIT (blocks, entry_edge->dest->index);
SET_BIT (blocks, orig_entry_edge->dest->index);
find_many_sub_basic_blocks (blocks);
sbitmap_free (blocks);
@ -6040,10 +6055,10 @@ epilogue_done:
convert to conditional simple_returns, but couldn't for some
reason, create a block to hold a simple_return insn and redirect
those remaining edges. */
if (!VEC_empty (basic_block, unconverted_simple_returns))
if (!VEC_empty (rtx, unconverted_simple_returns))
{
basic_block exit_pred = EXIT_BLOCK_PTR->prev_bb;
basic_block src_bb;
rtx jump;
int i;
gcc_assert (entry_edge != orig_entry_edge);
@ -6061,8 +6076,9 @@ epilogue_done:
simple_return_block_cold = e->dest;
}
FOR_EACH_VEC_ELT (basic_block, unconverted_simple_returns, i, src_bb)
FOR_EACH_VEC_ELT (rtx, unconverted_simple_returns, i, jump)
{
basic_block src_bb = BLOCK_FOR_INSN (jump);
edge e = find_edge (src_bb, last_bb);
basic_block *pdest_bb;
@ -6087,7 +6103,7 @@ epilogue_done:
}
redirect_edge_and_branch_force (e, *pdest_bb);
}
VEC_free (basic_block, heap, unconverted_simple_returns);
VEC_free (rtx, heap, unconverted_simple_returns);
}
#endif