summaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2013-03-05 14:45:23 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2013-03-05 14:45:23 +0000
commit390f4a4b5eb4ff6f4f06d7346d641729703bbad6 (patch)
tree4ff07f0d40ea5cef8af4fe46b0f91b0ca63c916a /gcc/except.c
parentf5f9d87c0243ce7d99422290997432990a4d8de9 (diff)
downloadgcc-390f4a4b5eb4ff6f4f06d7346d641729703bbad6.tar.gz
gcc/
PR c++/55135 * except.h (remove_unreachable_eh_regions): New prototype. * except.c (remove_eh_handler_splicer): New function, split out of remove_eh_handler. (remove_eh_handler): Use remove_eh_handler_splicer. Add comment warning about running it on many EH regions one at a time. (remove_unreachable_eh_regions_worker): New function, walk the EH tree in depth-first order and remove non-marked regions. (remove_unreachable_eh_regions): New function. * tree-eh.c (mark_reachable_handlers): New function, split out from remove_unreachable_handlers. (remove_unreachable_handlers): Use mark_reachable_handlers and remove_unreachable_eh_regions. (remove_unreachable_handlers_no_lp): Use mark_reachable_handlers and remove_unreachable_eh_regions. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196464 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c71
1 files changed, 60 insertions, 11 deletions
diff --git a/gcc/except.c b/gcc/except.c
index 3e424eb9d7f..4e85f731837 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1505,12 +1505,12 @@ remove_eh_landing_pad (eh_landing_pad lp)
(*cfun->eh->lp_array)[lp->index] = NULL;
}
-/* Splice REGION from the region tree. */
+/* Splice the EH region at PP from the region tree. */
-void
-remove_eh_handler (eh_region region)
+static void
+remove_eh_handler_splicer (eh_region *pp)
{
- eh_region *pp, *pp_start, p, outer;
+ eh_region region = *pp;
eh_landing_pad lp;
for (lp = region->landing_pads; lp ; lp = lp->next_lp)
@@ -1520,15 +1520,11 @@ remove_eh_handler (eh_region region)
(*cfun->eh->lp_array)[lp->index] = NULL;
}
- outer = region->outer;
- if (outer)
- pp_start = &outer->inner;
- else
- pp_start = &cfun->eh->region_tree;
- for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
- continue;
if (region->inner)
{
+ eh_region p, outer;
+ outer = region->outer;
+
*pp = p = region->inner;
do
{
@@ -1543,6 +1539,59 @@ remove_eh_handler (eh_region region)
(*cfun->eh->region_array)[region->index] = NULL;
}
+/* Splice a single EH region REGION from the region tree.
+
+ To unlink REGION, we need to find the pointer to it with a relatively
+ expensive search in REGION's outer region. If you are going to
+ remove a number of handlers, using remove_unreachable_eh_regions may
+ be a better option. */
+
+void
+remove_eh_handler (eh_region region)
+{
+ eh_region *pp, *pp_start, p, outer;
+
+ outer = region->outer;
+ if (outer)
+ pp_start = &outer->inner;
+ else
+ pp_start = &cfun->eh->region_tree;
+ for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
+ continue;
+
+ remove_eh_handler_splicer (pp);
+}
+
+/* Worker for remove_unreachable_eh_regions.
+ PP is a pointer to the region to start a region tree depth-first
+ search from. R_REACHABLE is the set of regions that have to be
+ preserved. */
+
+static void
+remove_unreachable_eh_regions_worker (eh_region *pp, sbitmap r_reachable)
+{
+ while (*pp)
+ {
+ eh_region region = *pp;
+ remove_unreachable_eh_regions_worker (&region->inner, r_reachable);
+ if (!bitmap_bit_p (r_reachable, region->index))
+ remove_eh_handler_splicer (pp);
+ else
+ pp = &region->next_peer;
+ }
+}
+
+/* Splice all EH regions *not* marked in R_REACHABLE from the region tree.
+ Do this by traversing the EH tree top-down and splice out regions that
+ are not marked. By removing regions from the leaves, we avoid costly
+ searches in the region tree. */
+
+void
+remove_unreachable_eh_regions (sbitmap r_reachable)
+{
+ remove_unreachable_eh_regions_worker (&cfun->eh->region_tree, r_reachable);
+}
+
/* Invokes CALLBACK for every exception handler landing pad label.
Only used by reload hackery; should not be used by new code. */