aboutsummaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-04-11 14:02:26 +0000
committerRichard Guenther <rguenther@suse.de>2012-04-11 14:02:26 +0000
commite2c3ff4fc517bdf194e11a73d841b1505b63e344 (patch)
tree8d818b24c6d556017465b882562342d6e6bdb7fa /gcc/except.c
parent7d2e74fd7074c60423d3963435b045174a8901e7 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@186320 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/except.c b/gcc/except.c
index e3a9ef07422..e6e7794f246 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);
}
}