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:
parent
b9397bb40b
commit
d088acea7d
@ -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
|
||||
|
137
gcc/gcse.c
137
gcc/gcse.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user