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:
parent
586fd93912
commit
db3a887b31
|
@ -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)
|
||||
|
||||
* alias.c (base_alias_check): Add missing return for differing
|
||||
|
|
85
gcc/flow.c
85
gcc/flow.c
|
@ -246,10 +246,10 @@ static int loop_depth;
|
|||
|
||||
static int cc0_live;
|
||||
|
||||
/* During propagate_block, this contains the last MEM stored into. It
|
||||
is used to eliminate consecutive stores to the same location. */
|
||||
/* During propagate_block, this contains a list of all the MEMs we are
|
||||
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
|
||||
in updating regs_ever_live. */
|
||||
|
@ -1147,7 +1147,11 @@ life_analysis (f, nregs, file)
|
|||
SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
|
||||
#endif
|
||||
|
||||
/* We want alias analysis information for local dead store elimination. */
|
||||
init_alias_analysis ();
|
||||
life_analysis_1 (f, nregs);
|
||||
end_alias_analysis ();
|
||||
|
||||
if (file)
|
||||
dump_flow_info (file);
|
||||
|
||||
|
@ -1739,7 +1743,7 @@ propagate_block (old, first, last, final, significant, bnum)
|
|||
live = ALLOCA_REG_SET ();
|
||||
|
||||
cc0_live = 0;
|
||||
last_mem_set = 0;
|
||||
mem_set_list = NULL_RTX;
|
||||
|
||||
/* Include any notes at the end of the block in the scan.
|
||||
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);
|
||||
|
||||
/* Calls also clobber memory. */
|
||||
last_mem_set = 0;
|
||||
mem_set_list = NULL_RTX;
|
||||
}
|
||||
|
||||
/* Update OLD for the registers used or set. */
|
||||
|
@ -2041,9 +2045,21 @@ insn_dead_p (x, needed, call_ok, notes)
|
|||
return ! cc0_live;
|
||||
#endif
|
||||
|
||||
if (GET_CODE (r) == MEM && last_mem_set && ! MEM_VOLATILE_P (r)
|
||||
&& rtx_equal_p (r, last_mem_set))
|
||||
if (GET_CODE (r) == MEM && ! MEM_VOLATILE_P (r))
|
||||
{
|
||||
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
|
||||
|| GET_CODE (r) == ZERO_EXTRACT)
|
||||
|
@ -2290,21 +2306,39 @@ mark_set_1 (needed, dead, x, insn, significant)
|
|||
|| GET_CODE (reg) == STRICT_LOW_PART)
|
||||
reg = XEXP (reg, 0);
|
||||
|
||||
/* If we are writing into memory or into a register mentioned in the
|
||||
address of the last thing stored into memory, show we don't know
|
||||
what the last store was. If we are writing memory, save the address
|
||||
unless it is volatile. */
|
||||
/* If this set is a MEM, then it kills any aliased writes.
|
||||
If this set is a REG, then it kills any MEMs which use the reg. */
|
||||
if (GET_CODE (reg) == MEM
|
||||
|| GET_CODE (reg) == REG)
|
||||
{
|
||||
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
|
||||
&& last_mem_set != 0 && reg_overlap_mentioned_p (reg, last_mem_set)))
|
||||
last_mem_set = 0;
|
||||
&& 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)
|
||||
/* 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
|
||||
stores though SP; none of them should be redundant anyway. */
|
||||
&& ! 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
|
||||
&& (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. */
|
||||
if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
|
||||
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
|
||||
; /* needn't clear last_mem_set */
|
||||
; /* needn't clear the memory set list */
|
||||
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
|
||||
if (final)
|
||||
|
|
Loading…
Reference in New Issue