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:
parent
87aab9b24b
commit
764a2546bb
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue