gcse.c (remove_reachable_equiv_notes): New.

* gcse.c (remove_reachable_equiv_notes): New.
	(replace_store_insn): Call it.  Update antic list.
	(store_killed_in_insn): Take REG_EQUAL notes into account.
	(build_store_vectors, delete_store): Add parameter to
	replace_store_insn call.

Co-Authored-By: Jeff Law <law@redhat.com>

From-SVN: r71412
This commit is contained in:
Zdenek Dvorak 2003-09-16 01:07:29 +02:00 committed by Jeff Law
parent b9397bb40b
commit d088acea7d
2 changed files with 137 additions and 9 deletions

View File

@ -1,3 +1,12 @@
2003-09-15 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
Jeff Law <law@redhat.com>
* gcse.c (remove_reachable_equiv_notes): New.
replace_store_insn): Call it. Update antic list.
(store_killed_in_insn): Take REG_EQUAL notes into account.
(build_store_vectors, delete_store): Add parameter to
replace_store_insn call.
2003-09-15 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.h (LEGITIMATE_PIC_OPERAND_P): Use

View File

@ -692,7 +692,8 @@ static bool store_killed_before (rtx, rtx, rtx, basic_block, int *);
static void build_store_vectors (void);
static void insert_insn_start_bb (rtx, basic_block);
static int insert_store (struct ls_expr *, edge);
static void replace_store_insn (rtx, rtx, basic_block);
static void remove_reachable_equiv_notes (basic_block, struct ls_expr *);
static void replace_store_insn (rtx, rtx, basic_block, struct ls_expr *);
static void delete_store (struct ls_expr *, basic_block);
static void free_store_memory (void);
static void store_motion (void);
@ -7254,7 +7255,7 @@ find_loads (rtx x, rtx store_pattern, int after)
static bool
store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after)
{
rtx reg, base;
rtx reg, base, note;
if (!INSN_P (insn))
return false;
@ -7305,10 +7306,26 @@ store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after)
return true;
}
}
return find_loads (SET_SRC (pat), x, after);
if (find_loads (SET_SRC (pat), x, after))
return true;
}
else
return find_loads (PATTERN (insn), x, after);
else if (find_loads (PATTERN (insn), x, after))
return true;
/* If this insn has a REG_EQUAL or REG_EQUIV note referencing a memory
location aliased with X, then this insn kills X. */
note = find_reg_equal_equiv_note (insn);
if (! note)
return false;
note = XEXP (note, 0);
/* However, if the note represents a must alias rather than a may
alias relationship, then it does not kill X. */
if (expr_equiv_p (note, x))
return false;
/* See if there are any aliased loads in the note. */
return find_loads (note, x, after);
}
/* Returns true if the expression X is loaded or clobbered on or after INSN
@ -7396,7 +7413,7 @@ build_store_vectors (void)
rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
if (gcse_file)
fprintf (gcse_file, "Removing redundant store:\n");
replace_store_insn (r, XEXP (st, 0), bb);
replace_store_insn (r, XEXP (st, 0), bb, ptr);
continue;
}
SET_BIT (ae_gen[bb->index], ptr->index);
@ -7551,13 +7568,87 @@ insert_store (struct ls_expr * expr, edge e)
return 1;
}
/* Remove any REG_EQUAL or REG_EQUIV notes containing a reference to the
memory location in SMEXPR set in basic block BB.
This could be rather expensive. */
static void
remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
{
edge *stack = xmalloc (sizeof (edge) * n_basic_blocks), act;
sbitmap visited = sbitmap_alloc (last_basic_block);
int stack_top = 0;
rtx last, insn, note;
rtx mem = smexpr->pattern;
sbitmap_zero (visited);
act = bb->succ;
while (1)
{
if (!act)
{
if (!stack_top)
{
free (stack);
sbitmap_free (visited);
return;
}
act = stack[--stack_top];
}
bb = act->dest;
if (bb == EXIT_BLOCK_PTR
|| TEST_BIT (visited, bb->index)
|| TEST_BIT (ae_kill[bb->index], smexpr->index))
{
act = act->succ_next;
continue;
}
SET_BIT (visited, bb->index);
if (TEST_BIT (st_antloc[bb->index], smexpr->index))
{
for (last = ANTIC_STORE_LIST (smexpr);
BLOCK_FOR_INSN (XEXP (last, 0)) != bb;
last = XEXP (last, 1))
continue;
last = XEXP (last, 0);
}
else
last = NEXT_INSN (bb->end);
for (insn = bb->head; insn != last; insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
note = find_reg_equal_equiv_note (insn);
if (!note || !expr_equiv_p (XEXP (note, 0), mem))
continue;
if (gcse_file)
fprintf (gcse_file, "STORE_MOTION drop REG_EQUAL note at insn %d:\n",
INSN_UID (insn));
remove_note (insn, note);
}
act = act->succ_next;
if (bb->succ)
{
if (act)
stack[stack_top++] = act;
act = bb->succ;
}
}
}
/* This routine will replace a store with a SET to a specified register. */
static void
replace_store_insn (rtx reg, rtx del, basic_block bb)
replace_store_insn (rtx reg, rtx del, basic_block bb, struct ls_expr *smexpr)
{
rtx insn;
rtx insn, mem, note, set, ptr;
mem = smexpr->pattern;
insn = gen_move_insn (reg, SET_SRC (single_set (del)));
insn = emit_insn_after (insn, del);
@ -7571,7 +7662,35 @@ replace_store_insn (rtx reg, rtx del, basic_block bb)
fprintf (gcse_file, "\n");
}
for (ptr = ANTIC_STORE_LIST (smexpr); ptr; ptr = XEXP (ptr, 1))
if (XEXP (ptr, 0) == del)
{
XEXP (ptr, 0) = insn;
break;
}
delete_insn (del);
/* Now we must handle REG_EQUAL notes whose contents is equal to the mem;
they are no longer accurate provided that they are reached by this
definition, so drop them. */
for (; insn != NEXT_INSN (bb->end); insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
set = single_set (insn);
if (!set)
continue;
if (expr_equiv_p (SET_DEST (set), mem))
return;
note = find_reg_equal_equiv_note (insn);
if (!note || !expr_equiv_p (XEXP (note, 0), mem))
continue;
if (gcse_file)
fprintf (gcse_file, "STORE_MOTION drop REG_EQUAL note at insn %d:\n",
INSN_UID (insn));
remove_note (insn, note);
}
remove_reachable_equiv_notes (bb, smexpr);
}
@ -7595,7 +7714,7 @@ delete_store (struct ls_expr * expr, basic_block bb)
{
/* We know there is only one since we deleted redundant
ones during the available computation. */
replace_store_insn (reg, del, bb);
replace_store_insn (reg, del, bb, expr);
break;
}
}