static int set_phi_alternative_reg PARAMS ((rtx, int, int, void *));
static void calculate_global_regs_live PARAMS ((sbitmap, sbitmap, int));
static void propagate_block_delete_insn PARAMS ((basic_block, rtx));
-static rtx propagate_block_delete_libcall PARAMS ((basic_block, rtx, rtx));
+static rtx propagate_block_delete_libcall PARAMS ((rtx, rtx));
static int insn_dead_p PARAMS ((struct propagate_block_info *,
rtx, int, rtx));
static int libcall_dead_p PARAMS ((struct propagate_block_info *,
static void invalidate_mems_from_set PARAMS ((struct propagate_block_info *,
rtx));
static void delete_dead_jumptables PARAMS ((void));
+static void clear_log_links PARAMS ((sbitmap));
\f
void
{
/* Recompute insn->block mapping, since the initial mapping is
set before we delete unreachable blocks. */
- compute_bb_for_insn (max_uid);
-
if (BLOCK_FOR_INSN (cfun->x_clobber_return_insn) != NULL)
warning ("control reaches end of non-void function");
}
int flags;
{
#ifdef ELIMINABLE_REGS
- register int i;
- static struct {int from, to; } eliminables[] = ELIMINABLE_REGS;
+ int i;
+ static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
#endif
/* Record which registers will be eliminated. We use this in
/* Always remove no-op moves. Do this before other processing so
that we don't have to keep re-scanning them. */
delete_noop_moves (f);
+ purge_all_dead_edges (false);
/* Some targets can emit simpler epilogues if they know that sp was
not ever modified during the function. After reload, of course,
tmp = INITIALIZE_REG_SET (tmp_head);
+ timevar_push ((extent == UPDATE_LIFE_LOCAL || blocks)
+ ? TV_LIFE_UPDATE : TV_LIFE);
+
/* Changes to the CFG are only allowed when
doing a global update for the entire CFG. */
if ((prop_flags & PROP_ALLOW_CFG_CHANGES)
&& (extent == UPDATE_LIFE_LOCAL || blocks))
abort ();
+ /* Clear log links in case we are asked to (re)compute them. */
+ if (prop_flags & PROP_LOG_LINKS)
+ clear_log_links (blocks);
+
/* For a global update, we go through the relaxation process again. */
if (extent != UPDATE_LIFE_LOCAL)
{
}
});
}
+ timevar_pop ((extent == UPDATE_LIFE_LOCAL || blocks)
+ ? TV_LIFE_UPDATE : TV_LIFE);
}
/* Free the variables allocated by find_basic_blocks.
free_basic_block_vars (keep_head_end_p)
int keep_head_end_p;
{
- if (basic_block_for_insn)
- {
- VARRAY_FREE (basic_block_for_insn);
- basic_block_for_insn = NULL;
- }
-
if (! keep_head_end_p)
{
if (basic_block_info)
next = NEXT_INSN (insn);
if (INSN_P (insn) && noop_move_p (insn))
{
- /* Do not call flow_delete_insn here to not confuse backward
- pointers of LIBCALL block. */
+ rtx note;
+
+ /* If we're about to remove the first insn of a libcall
+ then move the libcall note to the next real insn and
+ update the retval note. */
+ if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ && XEXP (note, 0) != insn)
+ {
+ rtx new_libcall_insn = next_real_insn (insn);
+ rtx retval_note = find_reg_note (XEXP (note, 0),
+ REG_RETVAL, NULL_RTX);
+ REG_NOTES (new_libcall_insn)
+ = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0),
+ REG_NOTES (new_libcall_insn));
+ XEXP (retval_note, 0) = new_libcall_insn;
+ }
+
+ /* Do not call delete_insn here since that may change
+ the basic block boundaries which upsets some callers. */
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;
- if (insn == bb->end)
- purge_dead_edges (bb);
}
}
}
{
next = NEXT_INSN (insn);
if (GET_CODE (insn) == CODE_LABEL
- && LABEL_NUSES (insn) == 0
+ && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
&& GET_CODE (next) == JUMP_INSN
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
- flow_delete_insn (NEXT_INSN (insn));
- flow_delete_insn (insn);
+ delete_insn (NEXT_INSN (insn));
+ delete_insn (insn);
next = NEXT_INSN (next);
}
}
void
allocate_bb_life_data ()
{
- register int i;
+ int i;
for (i = 0; i < n_basic_blocks; i++)
{
rtx insn;
{
rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
+ bool purge = false;
/* If the insn referred to a label, and that label was attached to
an ADDR_VEC, it's safe to delete the ADDR_VEC. In fact, it's
for (i = 0; i < len; i++)
LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
- flow_delete_insn (next);
+ delete_insn (next);
}
}
if (bb->end == insn)
- {
- bb->end = PREV_INSN (insn);
- purge_dead_edges (bb);
- }
- flow_delete_insn (insn);
+ purge = true;
+ delete_insn (insn);
+ if (purge)
+ purge_dead_edges (bb);
}
/* Delete dead libcalls for propagate_block. Return the insn
before the libcall. */
static rtx
-propagate_block_delete_libcall (bb, insn, note)
- basic_block bb;
+propagate_block_delete_libcall ( insn, note)
rtx insn, note;
{
rtx first = XEXP (note, 0);
rtx before = PREV_INSN (first);
- if (insn == bb->end)
- bb->end = before;
-
- flow_delete_insn_chain (first, insn);
+ delete_insn_chain (first, insn);
return before;
}
pbi->cc0_live = 0;
if (libcall_is_dead)
- prev = propagate_block_delete_libcall (pbi->bb, insn, note);
+ prev = propagate_block_delete_libcall ( insn, note);
else
propagate_block_delete_insn (pbi->bb, insn);
a following memory address. */
#ifdef AUTO_INC_DEC
{
- register rtx x = single_set (insn);
+ rtx x = single_set (insn);
/* Does this instruction increment or decrement a register? */
if ((flags & PROP_AUTOINC)
if (GET_CODE (insn) == CALL_INSN)
{
- register int i;
+ int i;
rtx note, cond;
cond = NULL_RTX;
if (! insn_is_dead && GET_CODE (insn) == CALL_INSN)
{
- register int i;
+ int i;
rtx note, cond;
cond = NULL_RTX;
if (flags & PROP_REG_INFO)
{
- register int i;
+ int i;
/* Process the regs live at the end of the block.
Mark them as not local to any one basic block. */
enum rtx_code code = GET_CODE (x);
#ifdef AUTO_INC_DEC
- /* If flow is invoked after reload, we must take existing AUTO_INC
- expresions into account. */
- if (reload_completed)
+ /* As flow is invoked after combine, we must take existing AUTO_INC
+ expressions into account. */
+ for (; notes; notes = XEXP (notes, 1))
{
- for (; notes; notes = XEXP (notes, 1))
+ if (REG_NOTE_KIND (notes) == REG_INC)
{
- if (REG_NOTE_KIND (notes) == REG_INC)
- {
- int regno = REGNO (XEXP (notes, 0));
-
- /* Don't delete insns to set global regs. */
- if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
- || REGNO_REG_SET_P (pbi->reg_live, regno))
- return 0;
- }
+ int regno = REGNO (XEXP (notes, 0));
+
+ /* Don't delete insns to set global regs. */
+ if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
+ || REGNO_REG_SET_P (pbi->reg_live, regno))
+ return 0;
}
}
#endif
if (x)
{
- register rtx r = SET_SRC (x);
+ rtx r = SET_SRC (x);
if (GET_CODE (r) == REG)
{
rtx call = XEXP (note, 0);
rtx call_pat;
- register int i;
+ int i;
/* Find the call insn. */
while (call != insn && GET_CODE (call) != CALL_INSN)
invalidate_mems_from_set (pbi, XEXP (note, 0));
}
-/* EXP is a REG. Remove any dependant entries from pbi->mem_set_list. */
+/* EXP is a REG. Remove any dependent entries from pbi->mem_set_list. */
static void
invalidate_mems_from_set (pbi, exp)
case PARALLEL:
{
- register int i;
+ int i;
+
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
{
rtx sub = XVECEXP (x, 0, i);
if (flags & (PROP_LOG_LINKS | PROP_REG_INFO
| PROP_DEATH_NOTES | PROP_AUTOINC))
{
- register rtx y;
- register int blocknum = pbi->bb->index;
+ rtx y;
+ int blocknum = pbi->bb->index;
y = NULL_RTX;
if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
insns = get_insns ();
end_sequence ();
- if (basic_block_for_insn)
- for (temp = insns; temp; temp = NEXT_INSN (temp))
- set_block_for_insn (temp, pbi->bb);
-
/* If we can't make the auto-inc, or can't make the
replacement into Y, exit. There's no point in making
the change below if we can't do the auto-inc and doing
{
/* Keep track of which basic block each reg appears in. */
- register int blocknum = pbi->bb->index;
+ int blocknum = pbi->bb->index;
if (REG_BASIC_BLOCK (regno_first) == REG_BLOCK_UNKNOWN)
REG_BASIC_BLOCK (regno_first) = blocknum;
else if (REG_BASIC_BLOCK (regno_first) != blocknum)
struct propagate_block_info *pbi;
rtx x, cond, insn;
{
- register RTX_CODE code;
- register int regno;
+ RTX_CODE code;
+ int regno;
int flags = pbi->flags;
retry:
case SET:
{
- register rtx testreg = SET_DEST (x);
+ rtx testreg = SET_DEST (x);
int mark_dest = 0;
/* If storing into MEM, don't show it as being used. But do
/* Recursively scan the operands of this expression. */
{
- register const char * const fmt = GET_RTX_FORMAT (code);
- register int i;
+ const char * const fmt = GET_RTX_FORMAT (code);
+ int i;
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
}
else if (fmt[i] == 'E')
{
- register int j;
+ int j;
for (j = 0; j < XVECLEN (x, i); j++)
mark_used_regs (pbi, XVECEXP (x, i, j), cond, insn);
}
rtx insn, reg;
HOST_WIDE_INT amount;
{
- register rtx use;
+ rtx use;
/* Nonzero if we can try to make a pre-increment or pre-decrement.
For example, addl $4,r1; movl (r1),... can become movl +(r1),... */
rtx
find_use_as_address (x, reg, plusconst)
- register rtx x;
+ rtx x;
rtx reg;
HOST_WIDE_INT plusconst;
{
enum rtx_code code = GET_CODE (x);
const char * const fmt = GET_RTX_FORMAT (code);
- register int i;
- register rtx value = 0;
- register rtx tem;
+ int i;
+ rtx value = 0;
+ rtx tem;
if (code == MEM && XEXP (x, 0) == reg && plusconst == 0)
return x;
}
else if (fmt[i] == 'E')
{
- register int j;
+ int j;
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
{
tem = find_use_as_address (XVECEXP (x, i, j), reg, plusconst);
return count;
}
-/* Clear LOG_LINKS fields of insns in a chain.
- Also clear the global_live_at_{start,end} fields of the basic block
- structures. */
+/* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
+ if blocks is NULL. */
-void
-clear_log_links (insns)
- rtx insns;
+static void
+clear_log_links (blocks)
+ sbitmap blocks;
{
- rtx i;
- int b;
-
- for (i = insns; i; i = NEXT_INSN (i))
- if (INSN_P (i))
- LOG_LINKS (i) = 0;
+ rtx insn;
+ int i;
- for (b = 0; b < n_basic_blocks; b++)
+ if (!blocks)
{
- basic_block bb = BASIC_BLOCK (b);
-
- bb->global_live_at_start = NULL;
- bb->global_live_at_end = NULL;
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ free_INSN_LIST_list (&LOG_LINKS (insn));
}
+ else
+ EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
+ {
+ basic_block bb = BASIC_BLOCK (i);
- ENTRY_BLOCK_PTR->global_live_at_end = NULL;
- EXIT_BLOCK_PTR->global_live_at_start = NULL;
+ for (insn = bb->head; insn != NEXT_INSN (bb->end);
+ insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ free_INSN_LIST_list (&LOG_LINKS (insn));
+ });
}
/* Given a register bitmap, turn on the bits in a HARD_REG_SET that