[RFA] pretty-ipa merge 8: handle aka bitmaps in EH duplication
Jan Hubicka
hubicka@ucw.cz
Sat Mar 28 23:42:00 GMT 2009
Hi,
this patch update EH duplication code to handle AKA bitmaps I need for
the ehcleanup pass. It depends on bitmap_last_set_bit I am retesting
after some last minute change and will send soon.
There is nothing earthshaking, just extra logic to duplicate the
aka bitmaps and find completely removed toplevel regions and add
them to the outer region of inlined function.
Path also makes foreach_reachable_handler, can_throw_internal_1,
can_throw_external_1 to handle case where toplevel handler was removed
(because it was empty catch block)
Bootstrapped/regtested x86_64-linux, OK?
* 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.
(struct reachable_info): Remove dead saw_any_handlers.
Index: except.c
===================================================================
--- except.c (revision 145204)
+++ except.c (working copy)
@@ -821,6 +959,17 @@ current_function_has_exception_handlers
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 +1001,18 @@ duplicate_eh_regions_1 (eh_region old, e
*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 +1043,11 @@ duplicate_eh_regions (struct function *i
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 +1068,18 @@ duplicate_eh_regions (struct function *i
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 +1089,19 @@ duplicate_eh_regions (struct function *i
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)
{
@@ -978,7 +1149,21 @@ duplicate_eh_regions (struct function *i
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 +1199,9 @@ duplicate_eh_regions (struct function *i
#undef REMAP
}
+#ifdef ENABLE_CHECKING
+ verify_eh_tree (cfun);
+#endif
return eh_offset;
}
@@ -2316,7 +2515,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 +2750,8 @@ foreach_reachable_handler (int region_nu
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 +2842,8 @@ can_throw_internal_1 (int region_number,
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 +2905,8 @@ can_throw_external_1 (int region_number,
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)
More information about the Gcc-patches
mailing list