aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-01-19 14:21:04 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-01-19 14:21:04 +0100
commit015337d35b4b3d5688162d24866b58a16a152f56 (patch)
treef9945e294d3a755495e9d717f36d83f5bf2e5f47 /gcc
parente2c768b6440a76c5850ce9fcf5e4e7c395f750db (diff)
downloadgcc-015337d35b4b3d5688162d24866b58a16a152f56.zip
gcc-015337d35b4b3d5688162d24866b58a16a152f56.tar.gz
gcc-015337d35b4b3d5688162d24866b58a16a152f56.tar.bz2
re PR debug/65779 (undefined local symbol on powerpc [regression])
PR debug/65779 * shrink-wrap.c: Include valtrack.h. (move_insn_for_shrink_wrap): Add DEBUG argument. If MAY_HAVE_DEBUG_INSNS, call dead_debug_add on DEBUG_INSNs in between insn and where it will be moved to. Call dead_debug_insert_temp. (prepare_shrink_wrap): Adjust caller. Call dead_debug_local_init first and dead_debug_local_finish at the end. For uses and defs bitmap, handle all regs in between REGNO and END_REGNO, not just the first one. * gcc.dg/pr65779.c: New test. From-SVN: r232558
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/shrink-wrap.c40
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr65779.c42
4 files changed, 96 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fbf3e76..dfc2174 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2016-01-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/65779
+ * shrink-wrap.c: Include valtrack.h.
+ (move_insn_for_shrink_wrap): Add DEBUG argument. If
+ MAY_HAVE_DEBUG_INSNS, call dead_debug_add on DEBUG_INSNs
+ in between insn and where it will be moved to. Call
+ dead_debug_insert_temp.
+ (prepare_shrink_wrap): Adjust caller. Call dead_debug_local_init
+ first and dead_debug_local_finish at the end.
+ For uses and defs bitmap, handle all regs in between REGNO and
+ END_REGNO, not just the first one.
+
2016-01-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/69352
diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c
index 84abd6b..fe79519 100644
--- a/gcc/shrink-wrap.c
+++ b/gcc/shrink-wrap.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "shrink-wrap.h"
#include "regcprop.h"
#include "rtl-iter.h"
+#include "valtrack.h"
/* Return true if INSN requires the stack frame to be set up.
@@ -149,7 +150,8 @@ static bool
move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
const HARD_REG_SET uses,
const HARD_REG_SET defs,
- bool *split_p)
+ bool *split_p,
+ struct dead_debug_local *debug)
{
rtx set, src, dest;
bitmap live_out, live_in, bb_uses, bb_defs;
@@ -158,6 +160,8 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
unsigned int end_sregno = FIRST_PSEUDO_REGISTER;
basic_block next_block;
edge live_edge;
+ rtx_insn *dinsn;
+ df_ref def;
/* Look for a simple register assignment. We don't use single_set here
because we can't deal with any CLOBBERs, USEs, or REG_UNUSED secondary
@@ -302,6 +306,20 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
move it as far as we can. */
do
{
+ if (MAY_HAVE_DEBUG_INSNS)
+ {
+ FOR_BB_INSNS_REVERSE (bb, dinsn)
+ if (DEBUG_INSN_P (dinsn))
+ {
+ df_ref use;
+ FOR_EACH_INSN_USE (use, dinsn)
+ if (refers_to_regno_p (dregno, end_dregno,
+ DF_REF_REG (use), (rtx *) NULL))
+ dead_debug_add (debug, use, DF_REF_REGNO (use));
+ }
+ else if (dinsn == insn)
+ break;
+ }
live_out = df_get_live_out (bb);
live_in = df_get_live_in (next_block);
bb = next_block;
@@ -384,6 +402,12 @@ move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
SET_REGNO_REG_SET (bb_uses, i);
}
+ /* Insert debug temps for dead REGs used in subsequent debug insns. */
+ if (debug->used && !bitmap_empty_p (debug->used))
+ FOR_EACH_INSN_DEF (def, insn)
+ dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn,
+ DEBUG_TEMP_BEFORE_WITH_VALUE);
+
emit_insn_after (PATTERN (insn), bb_note (bb));
delete_insn (insn);
return true;
@@ -404,6 +428,8 @@ prepare_shrink_wrap (basic_block entry_block)
HARD_REG_SET uses, defs;
df_ref def, use;
bool split_p = false;
+ unsigned int i;
+ struct dead_debug_local debug;
if (JUMP_P (BB_END (entry_block)))
{
@@ -414,19 +440,22 @@ prepare_shrink_wrap (basic_block entry_block)
copyprop_hardreg_forward_bb_without_debug_insn (entry_block);
}
+ dead_debug_local_init (&debug, NULL, NULL);
CLEAR_HARD_REG_SET (uses);
CLEAR_HARD_REG_SET (defs);
+
FOR_BB_INSNS_REVERSE_SAFE (entry_block, insn, curr)
if (NONDEBUG_INSN_P (insn)
&& !move_insn_for_shrink_wrap (entry_block, insn, uses, defs,
- &split_p))
+ &split_p, &debug))
{
/* Add all defined registers to DEFs. */
FOR_EACH_INSN_DEF (def, insn)
{
x = DF_REF_REG (def);
if (REG_P (x) && HARD_REGISTER_P (x))
- SET_HARD_REG_BIT (defs, REGNO (x));
+ for (i = REGNO (x); i < END_REGNO (x); i++)
+ SET_HARD_REG_BIT (defs, i);
}
/* Add all used registers to USESs. */
@@ -434,9 +463,12 @@ prepare_shrink_wrap (basic_block entry_block)
{
x = DF_REF_REG (use);
if (REG_P (x) && HARD_REGISTER_P (x))
- SET_HARD_REG_BIT (uses, REGNO (x));
+ for (i = REGNO (x); i < END_REGNO (x); i++)
+ SET_HARD_REG_BIT (uses, i);
}
}
+
+ dead_debug_local_finish (&debug, NULL);
}
/* Return whether basic block PRO can get the prologue. It can not if it
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2a60659..c0dfcf1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/65779
+ * gcc.dg/pr65779.c: New test.
+
2016-01-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/69352
diff --git a/gcc/testsuite/gcc.dg/pr65779.c b/gcc/testsuite/gcc.dg/pr65779.c
new file mode 100644
index 0000000..7d5c522
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr65779.c
@@ -0,0 +1,42 @@
+/* PR debug/65779 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+unsigned long
+foo (unsigned long x, unsigned char *y, unsigned int z)
+{
+ unsigned long a = x & 0xffff;
+ unsigned long b = (x >> 16) & 0xffff;
+ int k;
+ if (y == 0) return 1L;
+ while (z > 0)
+ {
+ k = z < 5552 ? z : 5552;
+ z -= k;
+ while (k >= 16)
+ {
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ a += *y++; b += a;
+ k -= 16;
+ }
+ if (k != 0)
+ do { a += *y++; b += a; } while (--k);
+ a %= 65521L;
+ b %= 65521L;
+ }
+ return (b << 16) | a;
+}