diff options
author | Kenneth Zadeck <zadeck@naturalbridge.com> | 2008-05-09 12:14:57 +0000 |
---|---|---|
committer | Kenneth Zadeck <zadeck@gcc.gnu.org> | 2008-05-09 12:14:57 +0000 |
commit | 5ba5ab9bdb7eab6099e969e9b8e098eba1380d9b (patch) | |
tree | d861801589c11e665802276c937520ba385c512b /gcc/dce.c | |
parent | 7afa92c5a23f13e73262f1df4b252342326ce456 (diff) | |
download | gcc-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.c | 24 |
1 files changed, 20 insertions, 4 deletions
@@ -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 (); } |