diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/sel-sched.c | 52 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr53701.c | 59 |
4 files changed, 104 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a00c31..618cba0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-08-09 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/53701 + * sel-sched.c (vinsn_vec_has_expr_p): Clarify function comment. + Process not only expr's vinsns but all old vinsns from expr's + history of changes. + (update_and_record_unavailable_insns): Clarify comment. + 2012-08-09 Bernd Schmidt <bernds@codesourcery.com> * reload.c (find_valid_class_1): New static function. diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 3099b92..f0c6eaf 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -3564,29 +3564,41 @@ process_use_exprs (av_set_t *av_ptr) return NULL; } -/* Lookup EXPR in VINSN_VEC and return TRUE if found. */ +/* Lookup EXPR in VINSN_VEC and return TRUE if found. Also check patterns from + EXPR's history of changes. */ static bool vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr) { - vinsn_t vinsn; + vinsn_t vinsn, expr_vinsn; int n; + unsigned i; - FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) - if (VINSN_SEPARABLE_P (vinsn)) - { - if (vinsn_equal_p (vinsn, EXPR_VINSN (expr))) - return true; - } - else - { - /* For non-separable instructions, the blocking insn can have - another pattern due to substitution, and we can't choose - different register as in the above case. Check all registers - being written instead. */ - if (bitmap_intersect_p (VINSN_REG_SETS (vinsn), - VINSN_REG_SETS (EXPR_VINSN (expr)))) - return true; - } + /* Start with checking expr itself and then proceed with all the old forms + of expr taken from its history vector. */ + for (i = 0, expr_vinsn = EXPR_VINSN (expr); + expr_vinsn; + expr_vinsn = (i < VEC_length (expr_history_def, + EXPR_HISTORY_OF_CHANGES (expr)) + ? VEC_index (expr_history_def, + EXPR_HISTORY_OF_CHANGES (expr), + i++)->old_expr_vinsn + : NULL)) + FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) + if (VINSN_SEPARABLE_P (vinsn)) + { + if (vinsn_equal_p (vinsn, expr_vinsn)) + return true; + } + else + { + /* For non-separable instructions, the blocking insn can have + another pattern due to substitution, and we can't choose + different register as in the above case. Check all registers + being written instead. */ + if (bitmap_intersect_p (VINSN_REG_SETS (vinsn), + VINSN_REG_SETS (expr_vinsn))) + return true; + } return false; } @@ -5694,8 +5706,8 @@ update_and_record_unavailable_insns (basic_block book_block) || EXPR_TARGET_AVAILABLE (new_expr) != EXPR_TARGET_AVAILABLE (cur_expr)) /* Unfortunately, the below code could be also fired up on - separable insns. - FIXME: add an example of how this could happen. */ + separable insns, e.g. when moving insns through the new + speculation check as in PR 53701. */ vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7dcf7d7..1ac24cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-08-09 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/53701 + * gcc.dg/pr53701.c: New test. + 2012-08-09 Bernd Schmidt <bernds@codesourcery.com> * gcc.c-torture/compile/20120727-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr53701.c b/gcc/testsuite/gcc.dg/pr53701.c new file mode 100644 index 0000000..2c85223 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr53701.c @@ -0,0 +1,59 @@ +/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O3 -fselective-scheduling2 -fsel-sched-pipelining" } */ +typedef unsigned short int uint16_t; +typedef unsigned long int uintptr_t; +typedef struct GFX_VTABLE +{ + int color_depth; + unsigned char *line[]; +} +BITMAP; +extern int _drawing_mode; +extern BITMAP *_drawing_pattern; +extern int _drawing_y_anchor; +extern unsigned int _drawing_x_mask; +extern unsigned int _drawing_y_mask; +extern uintptr_t bmp_write_line (BITMAP *, int); + void +_linear_hline15 (BITMAP * dst, int dx1, int dy, int dx2, int color) +{ + int w; + if (_drawing_mode == 0) + { + int x, curw; + unsigned short *sline = + (unsigned short *) (_drawing_pattern-> + line[((dy) - + _drawing_y_anchor) & _drawing_y_mask]); + unsigned short *s; + unsigned short *d = + ((unsigned short *) (bmp_write_line (dst, dy)) + (dx1)); + s = ((unsigned short *) (sline) + (x)); + if (_drawing_mode == 2) + { + } + else if (_drawing_mode == 3) + { + do + { + w -= curw; + do + { + unsigned long c = (*(s)); + if (!((unsigned long) (c) == 0x7C1F)) + { + (*((uint16_t *) ((uintptr_t) (d))) = ((color))); + } + ((s)++); + } + while (--curw > 0); + s = sline; + curw = + (((w) < + ((int) _drawing_x_mask + + 1)) ? (w) : ((int) _drawing_x_mask + 1)); + } + while (curw > 0); + } + } +} |