From cd451a8b3122429c3d7add8b7b87437745dda453 Mon Sep 17 00:00:00 2001 From: hubicka Date: Sun, 29 Mar 2009 13:16:18 +0000 Subject: [PATCH] * except.c (duplicate_eh_regions_0): Handle AKA bitmap. (duplicate_eh_regions_1): Likewise. (duplicate_eh_regions): Likewise; cleanup code gorwing the region vector; call EH verification. (foreach_reachable_handler, can_throw_internal_1, can_throw_external_1): Be ready for region being removed. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145230 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 ++++++ gcc/except.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 64577280cf6..964a4106f23 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2009-03-29 Jan Hubicka + * except.c (duplicate_eh_regions_0): Handle AKA bitmap. + (duplicate_eh_regions_1): Likewise. + (duplicate_eh_regions): Likewise; cleanup code gorwing the region + vector; call EH verification. + (foreach_reachable_handler, can_throw_internal_1, can_throw_external_1): + Be ready for region being removed. + +2009-03-29 Jan Hubicka + * bitmap.c (bitmap_last_set_bit): New function. * bitmap.h (bitmap_last_set_bit): Declare. diff --git a/gcc/except.c b/gcc/except.c index f18e78e3f48..9fad1563555 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -821,6 +821,17 @@ current_function_has_exception_handlers (void) static void duplicate_eh_regions_0 (eh_region o, int *min, int *max) { + int i; + + if (o->aka) + { + i = bitmap_first_set_bit (o->aka); + if (i < *min) + *min = i; + i = bitmap_last_set_bit (o->aka); + if (i > *max) + *max = i; + } if (o->region_number < *min) *min = o->region_number; if (o->region_number > *max) @@ -852,7 +863,18 @@ duplicate_eh_regions_1 (eh_region old, eh_region outer, int eh_offset) *n = *old; n->outer = outer; n->next_peer = NULL; - gcc_assert (!old->aka); + if (old->aka) + { + unsigned i; + bitmap_iterator bi; + n->aka = BITMAP_GGC_ALLOC (); + + EXECUTE_IF_SET_IN_BITMAP (old->aka, 0, i, bi) + { + bitmap_set_bit (n->aka, i + eh_offset); + VEC_replace (eh_region, cfun->eh->region_array, i + eh_offset, n); + } + } n->region_number += eh_offset; VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n); @@ -883,8 +905,11 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, int i, min_region, max_region, eh_offset, cfun_last_region_number; int num_regions; - if (!ifun->eh->region_tree) + if (!ifun->eh) return 0; +#ifdef ENABLE_CHECKING + verify_eh_tree (ifun); +#endif /* Find the range of region numbers to be copied. The interface we provide here mandates a single offset to find new number from old, @@ -905,23 +930,18 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, eh_offset = cfun_last_region_number + 1 - min_region; /* If we've not yet created a region array, do so now. */ - VEC_safe_grow (eh_region, gc, cfun->eh->region_array, - cfun_last_region_number + 1 + num_regions); - cfun->eh->last_region_number = max_region + eh_offset; - - /* We may have just allocated the array for the first time. - Make sure that element zero is null. */ - VEC_replace (eh_region, cfun->eh->region_array, 0, 0); - - /* Zero all entries in the range allocated. */ - memset (VEC_address (eh_region, cfun->eh->region_array) - + cfun_last_region_number + 1, 0, num_regions * sizeof (eh_region)); + cfun->eh->last_region_number = cfun_last_region_number + num_regions; + VEC_safe_grow_cleared (eh_region, gc, cfun->eh->region_array, + cfun->eh->last_region_number + 1); /* Locate the spot at which to insert the new tree. */ if (outer_region > 0) { outer = VEC_index (eh_region, cfun->eh->region_array, outer_region); - splice = &outer->inner; + if (outer) + splice = &outer->inner; + else + splice = &cfun->eh->region_tree; } else { @@ -931,6 +951,20 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, while (*splice) splice = &(*splice)->next_peer; + if (!ifun->eh->region_tree) + { + if (outer) + for (i = cfun_last_region_number + 1; + i <= cfun->eh->last_region_number; i++) + { + VEC_replace (eh_region, cfun->eh->region_array, i, outer); + if (outer->aka == NULL) + outer->aka = BITMAP_GGC_ALLOC (); + bitmap_set_bit (outer->aka, i); + } + return eh_offset; + } + /* Copy all the regions in the subtree. */ if (copy_region > 0) { @@ -960,9 +994,9 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, the prev_try short-cuts for ERT_CLEANUP regions. */ prev_try = NULL; if (outer_region > 0) - for (prev_try = VEC_index (eh_region, cfun->eh->region_array, outer_region); - prev_try && prev_try->type != ERT_TRY; - prev_try = prev_try->outer) + for (prev_try = + VEC_index (eh_region, cfun->eh->region_array, outer_region); + prev_try && prev_try->type != ERT_TRY; prev_try = prev_try->outer) if (prev_try->type == ERT_MUST_NOT_THROW || (prev_try->type == ERT_ALLOWED_EXCEPTIONS && !prev_try->u.allowed.type_list)) @@ -978,7 +1012,23 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, for (i = cfun_last_region_number + 1; VEC_iterate (eh_region, cfun->eh->region_array, i, cur); ++i) { + /* All removed EH that is toplevel in input function is now + in outer EH of output function. */ if (cur == NULL) + { + gcc_assert (VEC_index + (eh_region, ifun->eh->region_array, + i - eh_offset) == NULL); + if (outer) + { + VEC_replace (eh_region, cfun->eh->region_array, i, outer); + if (outer->aka == NULL) + outer->aka = BITMAP_GGC_ALLOC (); + bitmap_set_bit (outer->aka, i); + } + continue; + } + if (i != cur->region_number) continue; #define REMAP(REG) \ @@ -1014,6 +1064,9 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, #undef REMAP } +#ifdef ENABLE_CHECKING + verify_eh_tree (cfun); +#endif return eh_offset; } @@ -2316,7 +2369,6 @@ struct reachable_info tree types_allowed; void (*callback) (struct eh_region *, void *); void *callback_data; - bool saw_any_handlers; }; /* A subroutine of reachable_next_level. Return true if TYPE, or a @@ -2552,6 +2604,8 @@ foreach_reachable_handler (int region_number, bool is_resx, bool inlinable_call, info.callback_data = callback_data; region = VEC_index (eh_region, cfun->eh->region_array, region_number); + if (!region) + return; type_thrown = NULL_TREE; if (is_resx) @@ -2642,6 +2696,8 @@ can_throw_internal_1 (int region_number, bool is_resx, bool inlinable_call) tree type_thrown; region = VEC_index (eh_region, cfun->eh->region_array, region_number); + if (!region) + return false; type_thrown = NULL_TREE; if (is_resx) @@ -2703,6 +2759,8 @@ can_throw_external_1 (int region_number, bool is_resx, bool inlinable_call) tree type_thrown; region = VEC_index (eh_region, cfun->eh->region_array, region_number); + if (!region) + return true; type_thrown = NULL_TREE; if (is_resx) -- 2.11.0