Commit 5d369d58 by Andrey Belevantsev Committed by Andrey Belevantsev

re PR rtl-optimization/48144 (ICE: in code_motion_path_driver, at…

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
parent 51c7954d
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> 2011-03-26 Alan Modra <amodra@gmail.com>
* config/rs6000/predicates.md (word_offset_memref_op): Handle * config/rs6000/predicates.md (word_offset_memref_op): Handle
......
...@@ -1564,6 +1564,20 @@ free_history_vect (VEC (expr_history_def, heap) **pvect) ...@@ -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. */ /* Compare two vinsns as rhses if possible and as vinsns otherwise. */
bool bool
...@@ -1796,9 +1810,6 @@ update_speculative_bits (expr_t to, expr_t from, insn_t split_point) ...@@ -1796,9 +1810,6 @@ update_speculative_bits (expr_t to, expr_t from, insn_t split_point)
void void
merge_expr_data (expr_t to, expr_t from, insn_t split_point) 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 /* For now, we just set the spec of resulting expr to be minimum of the specs
of merged exprs. */ of merged exprs. */
if (EXPR_SPEC (to) > EXPR_SPEC (from)) if (EXPR_SPEC (to) > EXPR_SPEC (from))
...@@ -1822,20 +1833,12 @@ merge_expr_data (expr_t to, expr_t from, insn_t split_point) ...@@ -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 (to) = MIN (EXPR_ORIG_SCHED_CYCLE (to),
EXPR_ORIG_SCHED_CYCLE (from)); 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_SUBSTITUTED (to) |= EXPR_WAS_SUBSTITUTED (from);
EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from); EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from);
EXPR_CANT_MOVE (to) |= EXPR_CANT_MOVE (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_target_availability (to, from, split_point);
update_speculative_bits (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) ...@@ -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));
} }
......
...@@ -1565,7 +1565,7 @@ extern void av_set_leave_one_nonspec (av_set_t *); ...@@ -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 expr_t av_set_element (av_set_t, int);
extern void av_set_substract_cond_branches (av_set_t *); 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_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);
......
...@@ -6481,7 +6481,7 @@ code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path, ...@@ -6481,7 +6481,7 @@ code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path,
/* Filter the orig_ops set. */ /* Filter the orig_ops set. */
if (AV_SET_VALID_P (insn)) 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 no more original ops, return immediately. */
if (!orig_ops) if (!orig_ops)
......
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> 2011-03-26 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/discr27.ad[sb]: New test. * gnat.dg/discr27.ad[sb]: New test.
......
/* { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment