OSDN Git Service

* gcse.c (remove_reachable_equiv_notes): New.
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Sep 2003 23:07:29 +0000 (23:07 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Sep 2003 23:07:29 +0000 (23:07 +0000)
(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
gcc/gcse.c

index e94bd5d..906b771 100644 (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
index 3ea5411..f50c2d9 100644 (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;
        }
     }