OSDN Git Service

PR rtl-optimization/48144
authorabel <abel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 26 Mar 2011 11:40:51 +0000 (11:40 +0000)
committerabel <abel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 26 Mar 2011 11:40:51 +0000 (11:40 +0000)
    * sel-sched-ir.c (merge_history_vect): Factor out from ...
    (merge_expr_data): ... here.
    (av_set_intersect): Rename to av_set_code_motion_filter.
    Update all callers.  Call merge_history_vect when an expression
    is found in both sets.
    * sel-sched-ir.h (av_set_code_motion_filter): Add prototype.

    gcc/testsuite
    PR rtl-optimization/48144
    * gcc.dg/pr48144.c: New test.

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

gcc/ChangeLog
gcc/sel-sched-ir.c
gcc/sel-sched-ir.h
gcc/sel-sched.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr48144.c [new file with mode: 0644]

index a8fd3f9..181caf7 100644 (file)
@@ -1,3 +1,13 @@
+2011-03-26  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR rtl-optimization/48144
+       * sel-sched-ir.c (merge_history_vect): Factor out from ...
+       (merge_expr_data): ... here.
+       (av_set_intersect): Rename to av_set_code_motion_filter.
+       Update all callers.  Call merge_history_vect when an expression
+       is found in both sets.
+       * sel-sched-ir.h (av_set_code_motion_filter): Add prototype.
+
 2011-03-26  Alan Modra  <amodra@gmail.com>
 
        * config/rs6000/predicates.md (word_offset_memref_op): Handle
 2011-03-26  Alan Modra  <amodra@gmail.com>
 
        * config/rs6000/predicates.md (word_offset_memref_op): Handle
index b88dad1..61f3ffb 100644 (file)
@@ -1564,6 +1564,20 @@ free_history_vect (VEC (expr_history_def, heap) **pvect)
   *pvect = NULL;
 }
 
   *pvect = NULL;
 }
 
+/* Merge vector FROM to PVECT.  */
+static void
+merge_history_vect (VEC (expr_history_def, heap) **pvect,
+                   VEC (expr_history_def, heap) *from)
+{
+  expr_history_def *phist;
+  int i;
+
+  /* We keep this vector sorted.  */
+  for (i = 0; VEC_iterate (expr_history_def, from, i, phist); i++)
+    insert_in_history_vect (pvect, phist->uid, phist->type,
+                            phist->old_expr_vinsn, phist->new_expr_vinsn,
+                            phist->spec_ds);
+}
 
 /* Compare two vinsns as rhses if possible and as vinsns otherwise.  */
 bool
 
 /* Compare two vinsns as rhses if possible and as vinsns otherwise.  */
 bool
@@ -1796,9 +1810,6 @@ update_speculative_bits (expr_t to, expr_t from, insn_t split_point)
 void
 merge_expr_data (expr_t to, expr_t from, insn_t split_point)
 {
 void
 merge_expr_data (expr_t to, expr_t from, insn_t split_point)
 {
-  int i;
-  expr_history_def *phist;
-
   /* For now, we just set the spec of resulting expr to be minimum of the specs
      of merged exprs.  */
   if (EXPR_SPEC (to) > EXPR_SPEC (from))
   /* For now, we just set the spec of resulting expr to be minimum of the specs
      of merged exprs.  */
   if (EXPR_SPEC (to) > EXPR_SPEC (from))
@@ -1822,20 +1833,12 @@ merge_expr_data (expr_t to, expr_t from, insn_t split_point)
   EXPR_ORIG_SCHED_CYCLE (to) = MIN (EXPR_ORIG_SCHED_CYCLE (to),
                                     EXPR_ORIG_SCHED_CYCLE (from));
 
   EXPR_ORIG_SCHED_CYCLE (to) = MIN (EXPR_ORIG_SCHED_CYCLE (to),
                                     EXPR_ORIG_SCHED_CYCLE (from));
 
-  /* We keep this vector sorted.  */
-  for (i = 0;
-       VEC_iterate (expr_history_def, EXPR_HISTORY_OF_CHANGES (from),
-                    i, phist);
-       i++)
-    insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to),
-                            phist->uid, phist->type,
-                            phist->old_expr_vinsn, phist->new_expr_vinsn,
-                            phist->spec_ds);
-
   EXPR_WAS_SUBSTITUTED (to) |= EXPR_WAS_SUBSTITUTED (from);
   EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from);
   EXPR_CANT_MOVE (to) |= EXPR_CANT_MOVE (from);
 
   EXPR_WAS_SUBSTITUTED (to) |= EXPR_WAS_SUBSTITUTED (from);
   EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from);
   EXPR_CANT_MOVE (to) |= EXPR_CANT_MOVE (from);
 
+  merge_history_vect (&EXPR_HISTORY_OF_CHANGES (to),
+                     EXPR_HISTORY_OF_CHANGES (from));
   update_target_availability (to, from, split_point);
   update_speculative_bits (to, from, split_point);
 }
   update_target_availability (to, from, split_point);
   update_speculative_bits (to, from, split_point);
 }
@@ -2328,16 +2331,24 @@ av_set_split_usefulness (av_set_t av, int prob, int all_prob)
 }
 
 /* Leave in AVP only those expressions, which are present in AV,
 }
 
 /* Leave in AVP only those expressions, which are present in AV,
-   and return it.  */
+   and return it, merging history expressions.  */
 void
 void
-av_set_intersect (av_set_t *avp, av_set_t av)
+av_set_code_motion_filter (av_set_t *avp, av_set_t av)
 {
   av_set_iterator i;
 {
   av_set_iterator i;
-  expr_t expr;
+  expr_t expr, expr2;
 
   FOR_EACH_EXPR_1 (expr, i, avp)
 
   FOR_EACH_EXPR_1 (expr, i, avp)
-    if (av_set_lookup (av, EXPR_VINSN (expr)) == NULL)
+    if ((expr2 = av_set_lookup (av, EXPR_VINSN (expr))) == NULL)
       av_set_iter_remove (&i);
       av_set_iter_remove (&i);
+    else
+      /* When updating av sets in bookkeeping blocks, we can add more insns
+        there which will be transformed but the upper av sets will not
+        reflect those transformations.  We then fail to undo those
+        when searching for such insns.  So merge the history saved
+        in the av set of the block we are processing.  */
+      merge_history_vect (&EXPR_HISTORY_OF_CHANGES (expr),
+                         EXPR_HISTORY_OF_CHANGES (expr2));
 }
 
 \f
 }
 
 \f
index 1f3dec4..5516da9 100644 (file)
@@ -1565,7 +1565,7 @@ extern void av_set_leave_one_nonspec (av_set_t *);
 extern expr_t av_set_element (av_set_t, int);
 extern void av_set_substract_cond_branches (av_set_t *);
 extern void av_set_split_usefulness (av_set_t, int, int);
 extern expr_t av_set_element (av_set_t, int);
 extern void av_set_substract_cond_branches (av_set_t *);
 extern void av_set_split_usefulness (av_set_t, int, int);
-extern void av_set_intersect (av_set_t *, av_set_t);
+extern void av_set_code_motion_filter (av_set_t *, av_set_t);
 
 extern void sel_save_haifa_priorities (void);
 
 
 extern void sel_save_haifa_priorities (void);
 
index e26ddac..9179249 100644 (file)
@@ -6481,7 +6481,7 @@ code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path,
 
   /* Filter the orig_ops set.  */
   if (AV_SET_VALID_P (insn))
 
   /* Filter the orig_ops set.  */
   if (AV_SET_VALID_P (insn))
-    av_set_intersect (&orig_ops, AV_SET (insn));
+    av_set_code_motion_filter (&orig_ops, AV_SET (insn));
 
   /* If no more original ops, return immediately.  */
   if (!orig_ops)
 
   /* If no more original ops, return immediately.  */
   if (!orig_ops)
index 28ab5b9..e8f0e34 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-26  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR rtl-optimization/48144
+       * gcc.dg/pr48144.c: New test.
+
 2011-03-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/discr27.ad[sb]: New test.
 2011-03-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/discr27.ad[sb]: New test.
diff --git a/gcc/testsuite/gcc.dg/pr48144.c b/gcc/testsuite/gcc.dg/pr48144.c
new file mode 100644 (file)
index 0000000..030202d
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O -frerun-cse-after-loop -fschedule-insns2 -fselective-scheduling2 -fno-tree-ch -funroll-loops --param=max-sched-extend-regions-iters=2 --param=max-sched-region-blocks=15" } */
+extern void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);
+
+void bar (void *, void *, void *);
+
+void foo
+  (void *p, char *data, unsigned data_len)
+{
+  int buffer[8];
+  int buf2[8];
+  unsigned i;
+  for (i = 0; i + 8 <= data_len; i += 8)
+    bar (p, buffer, data + i);
+  memcpy (buf2, data + i, data_len);
+}