aboutsummaryrefslogtreecommitdiff
path: root/gcc/dce.c
diff options
context:
space:
mode:
authorKenneth Zadeck <zadeck@naturalbridge.com>2008-05-09 12:14:57 +0000
committerKenneth Zadeck <zadeck@gcc.gnu.org>2008-05-09 12:14:57 +0000
commit5ba5ab9bdb7eab6099e969e9b8e098eba1380d9b (patch)
treed861801589c11e665802276c937520ba385c512b /gcc/dce.c
parent7afa92c5a23f13e73262f1df4b252342326ce456 (diff)
downloadgcc-5ba5ab9bdb7eab6099e969e9b8e098eba1380d9b.zip
gcc-5ba5ab9bdb7eab6099e969e9b8e098eba1380d9b.tar.gz
gcc-5ba5ab9bdb7eab6099e969e9b8e098eba1380d9b.tar.bz2
re PR middle-end/36177 (g++.dg/opt/pr23714.C ICEs with 135041 -> 135057)
2008-05-08 Kenneth Zadeck <zadeck@naturalbridge.com> PR middle-end/36117 * dce.c (deletable_insn_p): Do not delete calls if df_in_progress. (delete_unmarked_insns): When deleting a call, call delete_unreachable_blocks. * rtl.texi (RTL_CONST_CALL_P, RTL_PURE_CALL_P, RTL_CONST_OR_PURE_CALL_P, RTL_LOOPING_CONST_OR_PURE_CALL_P): Fixed doc. From-SVN: r135113
Diffstat (limited to 'gcc/dce.c')
-rw-r--r--gcc/dce.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/gcc/dce.c b/gcc/dce.c
index 403d099..91cc9aa 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -99,11 +99,16 @@ deletable_insn_p (rtx insn, bool fast)
rtx body, x;
int i;
- /* We can delete dead const or pure calls as long as they do not
- infinite loop and are not sibling calls. The problem with
- sibling calls is that it is hard to see the result. */
- if (CALL_P (insn)
+ if (CALL_P (insn)
+ /* We cannot delete calls inside of the recursive dce because
+ this may cause basic blocks to be deleted and this messes up
+ the rest of the stack of optimization passes. */
+ && (!df_in_progress)
+ /* We cannot delete pure or const sibling calls because it is
+ hard to see the result. */
&& (!SIBLING_CALL_P (insn))
+ /* We can delete dead const or pure calls as long as they do not
+ infinite loop. */
&& (RTL_CONST_OR_PURE_CALL_P (insn)
&& !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
return true;
@@ -305,6 +310,7 @@ delete_unmarked_insns (void)
{
basic_block bb;
rtx insn, next;
+ bool must_clean = false;
FOR_EACH_BB (bb)
FOR_BB_INSNS_SAFE (bb, insn, next)
@@ -382,9 +388,19 @@ delete_unmarked_insns (void)
remove_note (XEXP (note, 0), libcall_note);
}
+ /* If a pure or const call is deleted, this may make the cfg
+ have unreachable blocks. We rememeber this and call
+ delete_unreachable_blocks at the end. */
+ if (CALL_P (insn))
+ must_clean = true;
+
/* Now delete the insn. */
delete_insn_and_edges (insn);
}
+
+ /* Deleted a pure or const call. */
+ if (must_clean)
+ delete_unreachable_blocks ();
}