From 609e463e971c3e543a70305eb42b3bacf5f0b85f Mon Sep 17 00:00:00 2001 From: law Date: Mon, 15 Sep 2003 23:07:29 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71412 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 ++++ gcc/gcse.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 137 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e94bd5d3e9f..906b771ab13 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2003-09-15 Zdenek Dvorak + Jeff Law + + * 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 * config/xtensa/xtensa.h (LEGITIMATE_PIC_OPERAND_P): Use diff --git a/gcc/gcse.c b/gcc/gcse.c index 3ea5411e17a..f50c2d9a01e 100644 --- a/gcc/gcse.c +++ b/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; } } -- 2.11.0