diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/df-problems.c | 47 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr51505.c | 19 |
4 files changed, 75 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc61564c3a3..5b70bf36a78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-01-19 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/51505 + * df-problems.c (df_kill_notes): New parameter live. Update comment. + Remove REG_EQUAL/REG_EQUIV notes referring to dead registers. + (df_note_bb_compute): Update the call to df_kill_notes. + 2012-01-18 Aldy Hernandez <aldyh@redhat.com> * trans-mem.c (requires_barrier): Remove call to is_global_var. diff --git a/gcc/df-problems.c b/gcc/df-problems.c index 89284541394..f9b0bc1d872 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -2748,10 +2748,12 @@ df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED) /* Remove all of the REG_DEAD or REG_UNUSED notes from INSN and add - them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES. */ + them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES. Remove also + REG_EQUAL/REG_EQUIV notes referring to dead pseudos using LIVE + as the bitmap of currently live registers. */ static void -df_kill_notes (rtx insn) +df_kill_notes (rtx insn, bitmap live) { rtx *pprev = ®_NOTES (insn); rtx link = *pprev; @@ -2798,6 +2800,45 @@ df_kill_notes (rtx insn) } break; + case REG_EQUAL: + case REG_EQUIV: + { + /* Remove the notes that refer to dead registers. As we have at most + one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note + so we need to purge the complete EQ_USES vector when removing + the note using df_notes_rescan. */ + df_ref *use_rec; + bool deleted = false; + + for (use_rec = DF_INSN_EQ_USES (insn); *use_rec; use_rec++) + { + df_ref use = *use_rec; + if (DF_REF_REGNO (use) > FIRST_PSEUDO_REGISTER + && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE) + && ! bitmap_bit_p (live, DF_REF_REGNO (use))) + { + deleted = true; + break; + } + } + if (deleted) + { + rtx next; +#ifdef REG_DEAD_DEBUGGING + df_print_note ("deleting: ", insn, link); +#endif + next = XEXP (link, 1); + free_EXPR_LIST_node (link); + *pprev = link = next; + df_notes_rescan (insn); + } + else + { + pprev = &XEXP (link, 1); + link = *pprev; + } + break; + } default: pprev = &XEXP (link, 1); link = *pprev; @@ -3299,7 +3340,7 @@ df_note_bb_compute (unsigned int bb_index, debug_insn = DEBUG_INSN_P (insn); bitmap_clear (do_not_gen); - df_kill_notes (insn); + df_kill_notes (insn, live); /* Process the defs. */ if (CALL_P (insn)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1d982ecebe9..a0d5a199013 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-01-19 Andrey Belevantsev <abel@ispras.ru> + + PR rtl-optimization/51505 + * gcc.dg/pr51505.c: New test. + 2012-01-18 Paul Thomas <pault@gcc.gnu.org> PR fortran/51634 diff --git a/gcc/testsuite/gcc.dg/pr51505.c b/gcc/testsuite/gcc.dg/pr51505.c new file mode 100644 index 00000000000..dbcd3226d7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr51505.c @@ -0,0 +1,19 @@ +/* PR rtl-optimization/51505 */ +/* { dg-do compile } */ +/* { dg-options "-O --param max-cse-insns=1" } */ +struct S +{ +char a[256]; +}; + +int bar(struct S, char[16]); + +void foo () +{ + struct S u, s1, s2; + char e[256]; + char i; + e[i] = ~s1.a[i] & s2.a[i]; + if (bar(u, e)) + __builtin_abort (); +} |