diff options
author | Alexandre Oliva <aoliva@gcc.gnu.org> | 2007-03-14 01:45:39 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2007-03-14 01:45:39 +0000 |
commit | 481e0a49bb403b8bb01550e550f90ed2125b9e04 (patch) | |
tree | 69d1846bc7e05624b70bc682d57e1942c56bf793 /gcc/cse.c | |
parent | 4cdb798f6c9b2bb7090f9fa8101da6e34bd2e569 (diff) | |
download | gcc-481e0a49bb403b8bb01550e550f90ed2125b9e04.zip gcc-481e0a49bb403b8bb01550e550f90ed2125b9e04.tar.gz gcc-481e0a49bb403b8bb01550e550f90ed2125b9e04.tar.bz2 |
re PR middle-end/31127 (ICE in cse_find_path, at cse.c:5930)
gcc/ChangeLog:
PR middle-end/31127
* cse.c (cse_find_path): Do not bail out if a basic block that
we already visited now becomes part of a path that starts at a
different basic block. Just disallow this, to make sure we
visit each basic block at most once.
gcc/testsuite/ChangeLog:
PR middle-end/31127
* gcc.dg/pr31127.c: New.
From-SVN: r122900
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 29 |
1 files changed, 17 insertions, 12 deletions
@@ -5876,13 +5876,20 @@ cse_find_path (basic_block first_bb, struct cse_basic_block_data *data, { bb = FALLTHRU_EDGE (previous_bb_in_path)->dest; if (bb != EXIT_BLOCK_PTR - && single_pred_p (bb)) + && single_pred_p (bb) + /* We used to assert here that we would only see blocks + that we have not visited yet. But we may end up + visiting basic blocks twice if the CFG has changed + in this run of cse_main, because when the CFG changes + the topological sort of the CFG also changes. A basic + blocks that previously had more than two predecessors + may now have a single predecessor, and become part of + a path that starts at another basic block. + + We still want to visit each basic block only once, so + halt the path here if we have already visited BB. */ + && !TEST_BIT (cse_visited_basic_blocks, bb->index)) { -#if ENABLE_CHECKING - /* We should only see blocks here that we have not - visited yet. */ - gcc_assert (!TEST_BIT (cse_visited_basic_blocks, bb->index)); -#endif SET_BIT (cse_visited_basic_blocks, bb->index); data->path[path_size++].bb = bb; break; @@ -5921,14 +5928,12 @@ cse_find_path (basic_block first_bb, struct cse_basic_block_data *data, e = NULL; if (e && e->dest != EXIT_BLOCK_PTR - && single_pred_p (e->dest)) + && single_pred_p (e->dest) + /* Avoid visiting basic blocks twice. The large comment + above explains why this can happen. */ + && !TEST_BIT (cse_visited_basic_blocks, e->dest->index)) { basic_block bb2 = e->dest; - - /* We should only see blocks here that we have not - visited yet. */ - gcc_assert (!TEST_BIT (cse_visited_basic_blocks, bb2->index)); - SET_BIT (cse_visited_basic_blocks, bb2->index); data->path[path_size++].bb = bb2; bb = bb2; |