OSDN Git Service

* gcse.c (reg_clear_last_set): New function.
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Dec 2003 10:02:28 +0000 (10:02 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Dec 2003 10:02:28 +0000 (10:02 +0000)
(reg_set_info): If data is non-null, treat it as an sbitmap of
registers, set the bit for the register being set.
(compute_store_table): Allocate last_set_in with xcalloc.  Do not
memset this array on each iteration.  Pass reg_set_in_block[bb->index]
to note_stores while computing last_set_in instead of scanning
last_set_in after the first pass through the insns.
Clear last_set_in using reg_clear_last_set instead of explicitly
rescanning after each insn.  If checking is enabled, assert that
last_set_in is completely zeroed after each bb has been processed.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74224 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gcse.c

index 1ea9b2c..1a51101 100644 (file)
@@ -1,3 +1,16 @@
+2003-12-03  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gcse.c (reg_clear_last_set): New function.
+       (reg_set_info): If data is non-null, treat it as an sbitmap of
+       registers, set the bit for the register being set.
+       (compute_store_table): Allocate last_set_in with xcalloc.  Do not
+       memset this array on each iteration.  Pass reg_set_in_block[bb->index]
+       to note_stores while computing last_set_in instead of scanning
+       last_set_in after the first pass through the insns.
+       Clear last_set_in using reg_clear_last_set instead of explicitly
+       rescanning after each insn.  If checking is enabled, assert that
+       last_set_in is completely zeroed after each bb has been processed.
+
 2003-12-02  Geoffrey Keating  <geoffk@geoffk.org>
 
        * df.c (df_uses_record) <MEM>: The argument of a MEM is read-only,
index 73f293b..4481dc7 100644 (file)
@@ -679,6 +679,7 @@ static void compute_ld_motion_mems (void);
 static void trim_ld_motion_mems (void);
 static void update_ld_motion_stores (struct expr *);
 static void reg_set_info (rtx, rtx, void *);
+static void reg_clear_last_set (rtx, rtx, void *);
 static bool store_ops_ok (rtx, int *);
 static rtx extract_mentioned_regs (rtx);
 static rtx extract_mentioned_regs_helper (rtx, rtx);
@@ -6921,17 +6922,41 @@ static sbitmap * st_antloc;
 /* Global holding the number of store expressions we are dealing with.  */
 static int num_stores;
 
-/* Checks to set if we need to mark a register set. Called from note_stores.  */
+/* Checks to set if we need to mark a register set.  Called from
+   note_stores.  */
 
 static void
 reg_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED,
-             void *data ATTRIBUTE_UNUSED)
+             void *data)
 {
+  sbitmap bb_reg = data;
+
   if (GET_CODE (dest) == SUBREG)
     dest = SUBREG_REG (dest);
 
   if (GET_CODE (dest) == REG)
-    regvec[REGNO (dest)] = INSN_UID (compute_store_table_current_insn);
+    {
+      regvec[REGNO (dest)] = INSN_UID (compute_store_table_current_insn);
+      if (bb_reg)
+       SET_BIT (bb_reg, REGNO (dest));
+    }
+}
+
+/* Clear any mark that says that this insn sets dest.  Called from
+   note_stores.  */
+
+static void
+reg_clear_last_set (rtx dest, rtx setter ATTRIBUTE_UNUSED,
+             void *data)
+{
+  int *dead_vec = data;
+
+  if (GET_CODE (dest) == SUBREG)
+    dest = SUBREG_REG (dest);
+
+  if (GET_CODE (dest) == REG &&
+      dead_vec[REGNO (dest)] == INSN_UID (compute_store_table_current_insn))
+    dead_vec[REGNO (dest)] = 0;
 }
 
 /* Return zero if some of the registers in list X are killed
@@ -7165,14 +7190,13 @@ compute_store_table (void)
                                                       max_gcse_regno);
   sbitmap_vector_zero (reg_set_in_block, last_basic_block);
   pre_ldst_mems = 0;
-  last_set_in = xmalloc (sizeof (int) * max_gcse_regno);
+  last_set_in = xcalloc (max_gcse_regno, sizeof (int));
   already_set = xmalloc (sizeof (int) * max_gcse_regno);
 
   /* Find all the stores we care about.  */
   FOR_EACH_BB (bb)
     {
       /* First compute the registers set in this block.  */
-      memset (last_set_in, 0, sizeof (int) * max_gcse_regno);
       regvec = last_set_in;
 
       for (insn = bb->head;
@@ -7194,19 +7218,17 @@ compute_store_table (void)
              for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
                if (clobbers_all
                    || TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
-                 last_set_in[regno] = INSN_UID (insn);
+                 {
+                   last_set_in[regno] = INSN_UID (insn);
+                   SET_BIT (reg_set_in_block[bb->index], regno);
+                 }
            }
 
          pat = PATTERN (insn);
          compute_store_table_current_insn = insn;
-         note_stores (pat, reg_set_info, NULL);
+         note_stores (pat, reg_set_info, reg_set_in_block[bb->index]);
        }
 
-      /* Record the set registers.  */
-      for (regno = 0; regno < max_gcse_regno; regno++)
-       if (last_set_in[regno])
-         SET_BIT (reg_set_in_block[bb->index], regno);
-
       /* Now find the stores.  */
       memset (already_set, 0, sizeof (int) * max_gcse_regno);
       regvec = already_set;
@@ -7239,11 +7261,32 @@ compute_store_table (void)
          find_moveable_store (insn, already_set, last_set_in);
 
          /* Unmark regs that are no longer set.  */
-         for (regno = 0; regno < max_gcse_regno; regno++)
-           if (last_set_in[regno] == INSN_UID (insn))
-             last_set_in[regno] = 0;
+         compute_store_table_current_insn = insn;
+         note_stores (pat, reg_clear_last_set, last_set_in);
+         if (GET_CODE (insn) == CALL_INSN)
+           {
+             bool clobbers_all = false;
+#ifdef NON_SAVING_SETJMP
+             if (NON_SAVING_SETJMP
+                 && find_reg_note (insn, REG_SETJMP, NULL_RTX))
+               clobbers_all = true;
+#endif
+
+             for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+               if ((clobbers_all
+                    || TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+                   && last_set_in[regno] == INSN_UID (insn))
+                 last_set_in[regno] = 0;
+           }
        }
 
+#ifdef ENABLE_CHECKING
+      /* last_set_in should now be all-zero.  */
+      for (regno = 0; regno < max_gcse_regno; regno++)
+       if (last_set_in[regno] != 0)
+         abort ();
+#endif
+
       /* Clear temporary marks.  */
       for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
        {