aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2016-10-12 17:21:38 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2016-10-12 17:21:38 +0200
commitaab648a9fcf8c222ab43612915d11b093e11849d (patch)
treec04c19ce683616d0ce012f90a973edb86373e8a4
parent20a6ece021473dc7f182b751bcbdaa6ad9762375 (diff)
downloadgcc-aab648a9fcf8c222ab43612915d11b093e11849d.zip
gcc-aab648a9fcf8c222ab43612915d11b093e11849d.tar.gz
gcc-aab648a9fcf8c222ab43612915d11b093e11849d.tar.bz2
dce: Don't dead-code delete separately wrapped restores
If there is a separately wrapped register restore on some path that is dead (say, control goes into an endless loop after it), then we cannot delete that restore because that would confuse the DWARF CFI (if there is another path joining). This happens with gcc.dg/torture/pr53168.c, for example. * dce.c (delete_unmarked_insns): Don't delete instructions with a REG_CFA_RESTORE note. From-SVN: r241060
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/dce.c9
2 files changed, 14 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 323bf35..7793544 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2016-10-12 Segher Boessenkool <segher@kernel.crashing.org>
+ * dce.c (delete_unmarked_insns): Don't delete instructions with
+ a REG_CFA_RESTORE note.
+
+2016-10-12 Segher Boessenkool <segher@kernel.crashing.org>
+
* common.opt (-fshrink-wrap-separate): New flag.
* doc/invoke.texi: Document it.
* doc/tm.texi.in (Shrink-wrapping separate components): New subsection.
diff --git a/gcc/dce.c b/gcc/dce.c
index ea3fb00..d510287 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -587,6 +587,15 @@ delete_unmarked_insns (void)
if (!dbg_cnt (dce))
continue;
+ if (crtl->shrink_wrapped_separate
+ && find_reg_note (insn, REG_CFA_RESTORE, NULL))
+ {
+ if (dump_file)
+ fprintf (dump_file, "DCE: NOT deleting insn %d, it's a "
+ "callee-save restore\n", INSN_UID (insn));
+ continue;
+ }
+
if (dump_file)
fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));