(remember, we are walking backward). This can be computed as current
pbi->insn_num - reg_deaths[regno].
At the end of processing each basic block, the remaining live registers
- are inspected and liferanges are increased same way so liverange of global
+ are inspected and live ranges are increased same way so liverange of global
registers are computed correctly.
The array is maintained clear for dead registers, so it can be safely reused
}
n_basic_blocks = 0;
last_basic_block = 0;
+ n_edges = 0;
+
+ label_to_block_map = NULL;
ENTRY_BLOCK_PTR->aux = NULL;
ENTRY_BLOCK_PTR->global_live_at_end = NULL;
}
else
{
- rtx note;
/* Any regs live at the time of a call instruction must not go
in a register clobbered by calls. Find all regs now live and
record this for them. */
/* Record uses. */
if (! insn_is_dead)
mark_used_regs (pbi, PATTERN (insn), NULL_RTX, insn);
- if ((flags & PROP_EQUAL_NOTES)
- && ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX))
- || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX))))
- mark_used_regs (pbi, XEXP (note, 0), NULL_RTX, insn);
/* Sometimes we may have inserted something before INSN (such as a move)
when we make an auto-inc. So ensure we will scan those insns. */
/* Identify the successor blocks. */
bb_true = EDGE_SUCC (bb, 0)->dest;
- if (EDGE_COUNT (bb->succs) > 1)
+ if (!single_succ_p (bb))
{
bb_false = EDGE_SUCC (bb, 1)->dest;
(TREE_TYPE (current_function_decl))))
&& (flags & PROP_SCAN_DEAD_STORES)
&& (EDGE_COUNT (bb->succs) == 0
- || (EDGE_COUNT (bb->succs) == 1
- && EDGE_SUCC (bb, 0)->dest == EXIT_BLOCK_PTR
+ || (single_succ_p (bb)
+ && single_succ (bb) == EXIT_BLOCK_PTR
&& ! current_function_calls_eh_return)))
{
rtx insn, set;
return 0;
}
-/* EXP is a REG. Remove any dependent entries from pbi->mem_set_list. */
+/* EXP is a REG or MEM. Remove any dependent entries from
+ pbi->mem_set_list. */
static void
invalidate_mems_from_set (struct propagate_block_info *pbi, rtx exp)
while (temp)
{
next = XEXP (temp, 1);
- if (reg_overlap_mentioned_p (exp, XEXP (temp, 0)))
+ if ((REG_P (exp) && reg_overlap_mentioned_p (exp, XEXP (temp, 0)))
+ /* When we get an EXP that is a mem here, we want to check if EXP
+ overlaps the *address* of any of the mems in the list (i.e. not
+ whether the mems actually overlap; that's done elsewhere). */
+ || (MEM_P (exp)
+ && reg_overlap_mentioned_p (exp, XEXP (XEXP (temp, 0), 0))))
{
/* Splice this entry out of the list. */
if (prev)
break;
}
- /* If this set is a MEM, then it kills any aliased writes.
+ /* If this set is a MEM, then it kills any aliased writes and any
+ other MEMs which use it.
If this set is a REG, then it kills any MEMs which use the reg. */
if (optimize && (flags & PROP_SCAN_DEAD_STORES))
{
- if (REG_P (reg))
+ if (REG_P (reg) || MEM_P (reg))
invalidate_mems_from_set (pbi, reg);
/* If the memory reference had embedded side effects (autoincrement
recompute_reg_usage (void)
{
allocate_reg_life_data ();
- /* distribute_notes in combiner fails to convert some of the REG_UNUSED notes
- to REG_DEAD notes. This causes CHECK_DEAD_NOTES in sched1 to abort. To
- solve this update the DEATH_NOTES here. */
+ /* distribute_notes in combiner fails to convert some of the
+ REG_UNUSED notes to REG_DEAD notes. This causes CHECK_DEAD_NOTES
+ in sched1 to die. To solve this update the DEATH_NOTES
+ here. */
update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO | PROP_DEATH_NOTES);
}