flow.c (last_mem_set): Delete variable.

* flow.c (last_mem_set): Delete variable.  References removed.
        (mem_set_list): New variable.
        (life_analysis): Initialize and finalize alias analysis.
        (propagate_block); Initialize mem_set_list.  Clear for CALL_INSNs.
        (insn_dead_p): For a store to memory, search the entire mem_set_list
        for a match.
        (mark_set_1): Kill entries on the mem_set_list for aliased writes or
        changes to their addresses.  Add new entries to the mem_set_list for
        memory writes writes.
        (mark_used_regs): Kill entries on the mem_set_list which may be
        referenced by a load operation.

Co-Authored-By: Jeffrey A Law <law@cygnus.com>

From-SVN: r24734
This commit is contained in:
Christian Bruel 1999-01-17 20:01:26 -07:00 committed by Jeff Law
parent 586fd93912
commit db3a887b31
2 changed files with 86 additions and 18 deletions

View File

@ -1,3 +1,18 @@
Mon Jan 18 03:52:56 1999 Christian Bruel <Christian.Bruel@st.com>
Jeffrey A Law (law@cygnus.com)
* flow.c (last_mem_set): Delete variable. References removed.
(mem_set_list): New variable.
(life_analysis): Initialize and finalize alias analysis.
(propagate_block); Initialize mem_set_list. Clear for CALL_INSNs.
(insn_dead_p): For a store to memory, search the entire mem_set_list
for a match.
(mark_set_1): Kill entries on the mem_set_list for aliased writes or
changes to their addresses. Add new entries to the mem_set_list for
memory writes writes.
(mark_used_regs): Kill entries on the mem_set_list which may be
referenced by a load operation.
Mon Jan 18 01:01:02 1999 Jeffrey A Law (law@cygnus.com) Mon Jan 18 01:01:02 1999 Jeffrey A Law (law@cygnus.com)
* alias.c (base_alias_check): Add missing return for differing * alias.c (base_alias_check): Add missing return for differing

View File

@ -246,10 +246,10 @@ static int loop_depth;
static int cc0_live; static int cc0_live;
/* During propagate_block, this contains the last MEM stored into. It /* During propagate_block, this contains a list of all the MEMs we are
is used to eliminate consecutive stores to the same location. */ tracking for dead store elimination. */
static rtx last_mem_set; static rtx mem_set_list;
/* Set of registers that may be eliminable. These are handled specially /* Set of registers that may be eliminable. These are handled specially
in updating regs_ever_live. */ in updating regs_ever_live. */
@ -1147,7 +1147,11 @@ life_analysis (f, nregs, file)
SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM); SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
#endif #endif
/* We want alias analysis information for local dead store elimination. */
init_alias_analysis ();
life_analysis_1 (f, nregs); life_analysis_1 (f, nregs);
end_alias_analysis ();
if (file) if (file)
dump_flow_info (file); dump_flow_info (file);
@ -1739,7 +1743,7 @@ propagate_block (old, first, last, final, significant, bnum)
live = ALLOCA_REG_SET (); live = ALLOCA_REG_SET ();
cc0_live = 0; cc0_live = 0;
last_mem_set = 0; mem_set_list = NULL_RTX;
/* Include any notes at the end of the block in the scan. /* Include any notes at the end of the block in the scan.
This is in case the block ends with a call to setjmp. */ This is in case the block ends with a call to setjmp. */
@ -1963,7 +1967,7 @@ propagate_block (old, first, last, final, significant, bnum)
final, insn); final, insn);
/* Calls also clobber memory. */ /* Calls also clobber memory. */
last_mem_set = 0; mem_set_list = NULL_RTX;
} }
/* Update OLD for the registers used or set. */ /* Update OLD for the registers used or set. */
@ -2041,9 +2045,21 @@ insn_dead_p (x, needed, call_ok, notes)
return ! cc0_live; return ! cc0_live;
#endif #endif
if (GET_CODE (r) == MEM && last_mem_set && ! MEM_VOLATILE_P (r) if (GET_CODE (r) == MEM && ! MEM_VOLATILE_P (r))
&& rtx_equal_p (r, last_mem_set)) {
return 1; rtx temp;
/* Walk the set of memory locations we are currently tracking
and see if one is an identical match to this memory location.
If so, this memory write is dead (remember, we're walking
backwards from the end of the block to the start. */
temp = mem_set_list;
while (temp)
{
if (rtx_equal_p (XEXP (temp, 0), r))
return 1;
temp = XEXP (temp, 1);
}
}
while (GET_CODE (r) == SUBREG || GET_CODE (r) == STRICT_LOW_PART while (GET_CODE (r) == SUBREG || GET_CODE (r) == STRICT_LOW_PART
|| GET_CODE (r) == ZERO_EXTRACT) || GET_CODE (r) == ZERO_EXTRACT)
@ -2290,21 +2306,39 @@ mark_set_1 (needed, dead, x, insn, significant)
|| GET_CODE (reg) == STRICT_LOW_PART) || GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0); reg = XEXP (reg, 0);
/* If we are writing into memory or into a register mentioned in the /* If this set is a MEM, then it kills any aliased writes.
address of the last thing stored into memory, show we don't know If this set is a REG, then it kills any MEMs which use the reg. */
what the last store was. If we are writing memory, save the address
unless it is volatile. */
if (GET_CODE (reg) == MEM if (GET_CODE (reg) == MEM
|| (GET_CODE (reg) == REG || GET_CODE (reg) == REG)
&& last_mem_set != 0 && reg_overlap_mentioned_p (reg, last_mem_set))) {
last_mem_set = 0; rtx temp = mem_set_list;
rtx prev = NULL_RTX;
while (temp)
{
if ((GET_CODE (reg) == MEM
&& output_dependence (XEXP (temp, 0), reg))
|| (GET_CODE (reg) == REG
&& reg_overlap_mentioned_p (reg, XEXP (temp, 0))))
{
/* Splice this entry out of the list. */
if (prev)
XEXP (prev, 1) = XEXP (temp, 1);
else
mem_set_list = XEXP (temp, 1);
}
else
prev = temp;
temp = XEXP (temp, 1);
}
}
if (GET_CODE (reg) == MEM && ! side_effects_p (reg) if (GET_CODE (reg) == MEM && ! side_effects_p (reg)
/* There are no REG_INC notes for SP, so we can't assume we'll see /* There are no REG_INC notes for SP, so we can't assume we'll see
everything that invalidates it. To be safe, don't eliminate any everything that invalidates it. To be safe, don't eliminate any
stores though SP; none of them should be redundant anyway. */ stores though SP; none of them should be redundant anyway. */
&& ! reg_mentioned_p (stack_pointer_rtx, reg)) && ! reg_mentioned_p (stack_pointer_rtx, reg))
last_mem_set = reg; mem_set_list = gen_rtx_EXPR_LIST (VOIDmode, reg, mem_set_list);
if (GET_CODE (reg) == REG if (GET_CODE (reg) == REG
&& (regno = REGNO (reg), regno != FRAME_POINTER_REGNUM) && (regno = REGNO (reg), regno != FRAME_POINTER_REGNUM)
@ -2699,9 +2733,28 @@ mark_used_regs (needed, live, x, final, insn)
something that can be stored into. */ something that can be stored into. */
if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))) && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
; /* needn't clear last_mem_set */ ; /* needn't clear the memory set list */
else else
last_mem_set = 0; {
rtx temp = mem_set_list;
rtx prev = NULL_RTX;
while (temp)
{
if (anti_dependence (XEXP (temp, 0), GET_MODE (x),
x, rtx_addr_varies_p))
{
/* Splice temp out of the list. */
if (prev)
XEXP (prev, 1) = XEXP (temp, 1);
else
mem_set_list = XEXP (temp, 1);
}
else
prev = temp;
temp = XEXP (temp, 1);
}
}
#ifdef AUTO_INC_DEC #ifdef AUTO_INC_DEC
if (final) if (final)