aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2011-10-07 12:20:17 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2011-10-07 12:20:17 +0000
commit764a2546bb1b7a4e3478042008ea75736de7c224 (patch)
tree75f1b4d01d5b4be1eae0851d70a65cea44fab5f8 /gcc/function.c
parent87aab9b24b6ef536f090e3c5acb7e68d14f141fe (diff)
downloadgcc-764a2546bb1b7a4e3478042008ea75736de7c224.zip
gcc-764a2546bb1b7a4e3478042008ea75736de7c224.tar.gz
gcc-764a2546bb1b7a4e3478042008ea75736de7c224.tar.bz2
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
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c74
1 files changed, 45 insertions, 29 deletions
diff --git a/gcc/function.c b/gcc/function.c
index ff63b94..85a0bb7 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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