gcse.c (replace_one_set): New function.
authorMostafa Hagog <mustafa@il.ibm.com>
Thu, 4 Sep 2003 02:10:32 +0000 (02:10 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 4 Sep 2003 02:10:32 +0000 (19:10 -0700)
        * gcse.c (replace_one_set): New function.
        (pre_insert_copy_insn): Change the order of copying
        to make copy propagation discover additional PRE opportunities.

From-SVN: r71047

gcc/ChangeLog
gcc/gcse.c

index d432719285392de9bcf3ccaa1c25979817f38761..bd7880186cf21b989c6bbf63103a6f35a3c372d6 100644 (file)
@@ -1,3 +1,9 @@
+2003-09-03  Mostafa Hagog  <mustafa@il.ibm.com>
+
+       * gcse.c (replace_one_set): New function.
+       (pre_insert_copy_insn): Change the order of copying
+       to make copy propagation discover additional PRE opportunities.
+
 2003-09-03  Roger Sayle  <roger@eyesopen.com>
 
        PR optimization/11700.
index c7cd4857408eac63cd8d495b8f559fe140207c01..97796637e548ebbd7058e24533a48fe1f3902e8e 100644 (file)
@@ -559,6 +559,7 @@ static void alloc_reg_set_mem (int);
 static void free_reg_set_mem (void);
 static int get_bitmap_width (int, int, int);
 static void record_one_set (int, rtx);
+static void replace_one_set (int, rtx, rtx);
 static void record_set_info (rtx, rtx, void *);
 static void compute_sets (rtx);
 static void hash_scan_insn (rtx, struct hash_table *, int);
@@ -1176,6 +1177,24 @@ free_reg_set_mem (void)
   obstack_free (&reg_set_obstack, NULL);
 }
 
+/* An OLD_INSN that used to set REGNO was replaced by NEW_INSN.
+   Update the corresponding `reg_set_table' entry accordingly.
+   We assume that NEW_INSN is not already recorded in reg_set_table[regno].  */
+
+static void
+replace_one_set (int regno, rtx old_insn, rtx new_insn)
+{
+  struct reg_set *reg_info;
+  if (regno >= reg_set_table_size)
+    return;
+  for (reg_info = reg_set_table[regno]; reg_info; reg_info = reg_info->next)
+    if (reg_info->insn == old_insn)
+      {
+        reg_info->insn = new_insn;
+        break;
+      }
+}
+
 /* Record REGNO in the reg_set table.  */
 
 static void
@@ -5327,7 +5346,14 @@ pre_edge_insert (struct edge_list *edge_list, struct expr **index_map)
   return did_insert;
 }
 
-/* Copy the result of INSN to REG.  INDX is the expression number.  */
+/* Copy the result of INSN to REG.  INDX is the expression number.
+   Given "old_reg <- expr" (INSN), instead of adding after it
+     reaching_reg <- old_reg
+   it's better to do the following:
+     reaching_reg <- expr
+     old_reg      <- reaching_reg
+   because this way copy propagation can discover additional PRE
+   opportunuties.  */
 
 static void
 pre_insert_copy_insn (struct expr *expr, rtx insn)
@@ -5337,14 +5363,25 @@ pre_insert_copy_insn (struct expr *expr, rtx insn)
   int indx = expr->bitmap_index;
   rtx set = single_set (insn);
   rtx new_insn;
+  rtx new_set;
+  rtx old_reg;
 
   if (!set)
     abort ();
 
-  new_insn = emit_insn_after (gen_move_insn (reg, copy_rtx (SET_DEST (set))), insn);
+  old_reg = SET_DEST (set);
+  new_insn = emit_insn_after (gen_move_insn (old_reg,
+                                             reg),
+                              insn);
+  new_set = single_set (new_insn);
+
+  if (!new_set)
+    abort();
+  SET_DEST (set) = reg;
 
   /* Keep register set table up to date.  */
-  record_one_set (regno, new_insn);
+  replace_one_set (REGNO (old_reg), insn, new_insn);
+  record_one_set (regno, insn);
 
   gcse_create_count++;