diff options
author | Richard Guenther <rguenther@suse.de> | 2012-04-11 14:02:26 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-04-11 14:02:26 +0000 |
commit | 405af656bcbddb0f655aa7744220478b80df09d7 (patch) | |
tree | 8d818b24c6d556017465b882562342d6e6bdb7fa /gcc/except.c | |
parent | e9184c9ece086653c99b6ffb439aac9aa2e6dbbb (diff) | |
download | gcc-405af656bcbddb0f655aa7744220478b80df09d7.zip gcc-405af656bcbddb0f655aa7744220478b80df09d7.tar.gz gcc-405af656bcbddb0f655aa7744220478b80df09d7.tar.bz2 |
re PR target/52918 (ICE: Invalid bb->loop_father (NULL) in add_bb_to_loop)
2012-04-11 Richard Guenther <rguenther@suse.de>
PR middle-end/52918
* except.c (sjlj_emit_dispatch_table): Properly update loop
structure.
* g++.dg/torture/pr52918-1.C: New testcase.
* g++.dg/torture/pr52918-2.C: Likewise.
From-SVN: r186320
Diffstat (limited to 'gcc/except.c')
-rw-r--r-- | gcc/except.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/except.c b/gcc/except.c index e3a9ef0..e6e7794 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -1344,6 +1344,28 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch) e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU); e->count = bb->count; e->probability = REG_BR_PROB_BASE; + if (current_loops) + { + struct loop *loop = bb->next_bb->loop_father; + /* If we created a pre-header block, add the new block to the + outer loop, otherwise to the loop itself. */ + if (bb->next_bb == loop->header) + add_bb_to_loop (bb, loop_outer (loop)); + else + add_bb_to_loop (bb, loop); + /* ??? For multiple dispatches we will end up with edges + from the loop tree root into this loop, making it a + multiple-entry loop. Discard all affected loops. */ + if (num_dispatch > 1) + { + for (loop = bb->loop_father; + loop_outer (loop); loop = loop_outer (loop)) + { + loop->header = NULL; + loop->latch = NULL; + } + } + } disp_index++; } @@ -1364,6 +1386,24 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch) e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU); e->count = bb->count; e->probability = REG_BR_PROB_BASE; + if (current_loops) + { + struct loop *loop = bb->next_bb->loop_father; + /* If we created a pre-header block, add the new block to the + outer loop, otherwise to the loop itself. */ + if (bb->next_bb == loop->header) + add_bb_to_loop (bb, loop_outer (loop)); + else + add_bb_to_loop (bb, loop); + } + } + else + { + /* We are not wiring up edges here, but as the dispatcher call + is at function begin simply associate the block with the + outermost (non-)loop. */ + if (current_loops) + add_bb_to_loop (bb, current_loops->tree_root); } } |