From: abel Date: Sat, 26 Mar 2011 11:40:51 +0000 (+0000) Subject: PR rtl-optimization/48144 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=c53624fbd348540040a860e4903d35c9bedeb79d 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171555 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8fd3f9642b..181caf7d3d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-03-26 Andrey Belevantsev + + 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 * config/rs6000/predicates.md (word_offset_memref_op): Handle diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index b88dad1b3f6..61f3ffba40d 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 1f3dec48cc9..5516da9391f 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 e26ddac8fab..9179249ab1a 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 28ab5b98f68..e8f0e3477db 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-03-26 Andrey Belevantsev + + PR rtl-optimization/48144 + * gcc.dg/pr48144.c: New test. + 2011-03-26 Eric Botcazou * 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 00000000000..030202d064b --- /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); +}