aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrey Belevantsev <abel@ispras.ru>2011-03-26 14:40:51 +0300
committerAndrey Belevantsev <abel@gcc.gnu.org>2011-03-26 14:40:51 +0300
commit5d369d583699112c7339f1f5555bd592f6fed70c (patch)
treee2cf568813894a52b11c45de3a130c1125d79816 /gcc
parent51c7954daf0d223599ad0aeea64b63816ee1e354 (diff)
downloadgcc-5d369d583699112c7339f1f5555bd592f6fed70c.zip
gcc-5d369d583699112c7339f1f5555bd592f6fed70c.tar.gz
gcc-5d369d583699112c7339f1f5555bd592f6fed70c.tar.bz2
re PR rtl-optimization/48144 (ICE: in code_motion_path_driver, at sel-sched.c:6575 with -fselective-scheduling2 and custom flags)
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. gcc/testsuite PR rtl-optimization/48144 * gcc.dg/pr48144.c: New test. From-SVN: r171555
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/sel-sched-ir.c45
-rw-r--r--gcc/sel-sched-ir.h2
-rw-r--r--gcc/sel-sched.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr48144.c16
6 files changed, 61 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a8fd3f9..181caf7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index b88dad1b..61f3ffb 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -1564,6 +1564,20 @@ free_history_vect (VEC (expr_history_def, heap) **pvect)
*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
@@ -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)
{
- 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))
@@ -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));
- /* 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);
+ 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);
}
@@ -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,
- and return it. */
+ and return it, merging history expressions. */
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;
- expr_t expr;
+ expr_t expr, expr2;
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);
+ 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));
}
diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h
index 1f3dec4..5516da9 100644
--- a/gcc/sel-sched-ir.h
+++ b/gcc/sel-sched-ir.h
@@ -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 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);
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index e26ddac..9179249 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -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))
- 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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 28ab5b9..e8f0e34 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/pr48144.c b/gcc/testsuite/gcc.dg/pr48144.c
new file mode 100644
index 0000000..030202d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr48144.c
@@ -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);
+}