diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2013-03-05 14:45:23 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2013-03-05 14:45:23 +0000 |
commit | d273b1767420781173a2d2b6ff9570b172756bf7 (patch) | |
tree | 4ff07f0d40ea5cef8af4fe46b0f91b0ca63c916a /gcc/except.c | |
parent | 574f9d7ecdea31bb7c611ae6d99efef10fb8cd0a (diff) | |
download | gcc-d273b1767420781173a2d2b6ff9570b172756bf7.zip gcc-d273b1767420781173a2d2b6ff9570b172756bf7.tar.gz gcc-d273b1767420781173a2d2b6ff9570b172756bf7.tar.bz2 |
re PR c++/55135 (Segfault of gcc on a big file)
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.
From-SVN: r196464
Diffstat (limited to 'gcc/except.c')
-rw-r--r-- | gcc/except.c | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/gcc/except.c b/gcc/except.c index 3e424eb..4e85f73 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 (®ion->inner, r_reachable); + if (!bitmap_bit_p (r_reachable, region->index)) + remove_eh_handler_splicer (pp); + else + pp = ®ion->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. */ |