Commit 0856ee98 by Jan Hubicka Committed by Richard Biener

except.c (struct eh_status): Turn region_array into vec.

2005-09-17  Jan Hubicka  <jh@suse.cz>

	* except.c (struct eh_status): Turn region_array into vec.
	(expand_resx_expr, collect_eh_region_array, remove_unreachable_regions,
	convert_from_eh_region_ranges, find_exception_handler_labels,
	current_function_has_exception_handlers, assign_filter_values,
	build_post_landing_pads, dw2_build_landing_pads,
	sjlj_find_directly_reachable_regions, sjlj_mark_call_sites,
	sjlj_emit_dispatch_table, remove_eh_handler, for_each_eh_region,
	foreach_reachable_handler, can_throw_internal_1,
	convert_to_eh_region_ranges, verify_eh_tree): Update uses of
	region_array.
	(duplicate_eh_region_1): Update region_array.
	(duplicate_eh_regions): Resize region_array and avoid recomputing.

From-SVN: r104375
parent 53c4ca47
2005-09-17 Jan Hubicka <jh@suse.cz>
* except.c (struct eh_status): Turn region_array into vec.
(expand_resx_expr, collect_eh_region_array, remove_unreachable_regions,
convert_from_eh_region_ranges, find_exception_handler_labels,
current_function_has_exception_handlers, assign_filter_values,
build_post_landing_pads, dw2_build_landing_pads,
sjlj_find_directly_reachable_regions, sjlj_mark_call_sites,
sjlj_emit_dispatch_table, remove_eh_handler, for_each_eh_region,
foreach_reachable_handler, can_throw_internal_1,
convert_to_eh_region_ranges, verify_eh_tree): Update uses of
region_array.
(duplicate_eh_region_1): Update region_array.
(duplicate_eh_regions): Resize region_array and avoid recomputing.
2005-09-17 David Edelsohn <edelsohn@gnu.org> 2005-09-17 David Edelsohn <edelsohn@gnu.org>
PR middle-end/22067 PR middle-end/22067
......
...@@ -199,12 +199,17 @@ struct eh_region GTY(()) ...@@ -199,12 +199,17 @@ struct eh_region GTY(())
unsigned may_contain_throw : 1; unsigned may_contain_throw : 1;
}; };
typedef struct eh_region *eh_region;
struct call_site_record GTY(()) struct call_site_record GTY(())
{ {
rtx landing_pad; rtx landing_pad;
int action; int action;
}; };
DEF_VEC_P(eh_region);
DEF_VEC_ALLOC_P(eh_region, gc);
/* Used to save exception status for each function. */ /* Used to save exception status for each function. */
struct eh_status GTY(()) struct eh_status GTY(())
{ {
...@@ -212,7 +217,7 @@ struct eh_status GTY(()) ...@@ -212,7 +217,7 @@ struct eh_status GTY(())
struct eh_region *region_tree; struct eh_region *region_tree;
/* The same information as an indexable array. */ /* The same information as an indexable array. */
struct eh_region ** GTY ((length ("%h.last_region_number"))) region_array; VEC(eh_region,gc) *region_array;
/* The most recently open region. */ /* The most recently open region. */
struct eh_region *cur_region; struct eh_region *cur_region;
...@@ -562,7 +567,8 @@ void ...@@ -562,7 +567,8 @@ void
expand_resx_expr (tree exp) expand_resx_expr (tree exp)
{ {
int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)); int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
struct eh_region *reg = cfun->eh->region_array[region_nr]; struct eh_region *reg = VEC_index (eh_region,
cfun->eh->region_array, region_nr);
gcc_assert (!reg->resume); gcc_assert (!reg->resume);
reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr)); reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
...@@ -626,19 +632,19 @@ get_exception_filter (struct function *fun) ...@@ -626,19 +632,19 @@ get_exception_filter (struct function *fun)
void void
collect_eh_region_array (void) collect_eh_region_array (void)
{ {
struct eh_region **array, *i; struct eh_region *i;
i = cfun->eh->region_tree; i = cfun->eh->region_tree;
if (! i) if (! i)
return; return;
array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1) VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
* sizeof (*array)); cfun->eh->last_region_number + 1);
cfun->eh->region_array = array; VEC_replace (eh_region, cfun->eh->region_array, 0, 0);
while (1) while (1)
{ {
array[i->region_number] = i; VEC_replace (eh_region, cfun->eh->region_array, i->region_number, i);
/* If there are sub-regions, process them. */ /* If there are sub-regions, process them. */
if (i->inner) if (i->inner)
...@@ -674,7 +680,7 @@ remove_unreachable_regions (rtx insns) ...@@ -674,7 +680,7 @@ remove_unreachable_regions (rtx insns)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
r = cfun->eh->region_array[i]; r = VEC_index (eh_region, cfun->eh->region_array, i);
if (!r || r->region_number != i) if (!r || r->region_number != i)
continue; continue;
...@@ -695,7 +701,7 @@ remove_unreachable_regions (rtx insns) ...@@ -695,7 +701,7 @@ remove_unreachable_regions (rtx insns)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
r = cfun->eh->region_array[i]; r = VEC_index (eh_region, cfun->eh->region_array, i);
if (r && r->region_number == i && !reachable[i]) if (r && r->region_number == i && !reachable[i])
{ {
bool kill_it = true; bool kill_it = true;
...@@ -756,7 +762,9 @@ convert_from_eh_region_ranges (void) ...@@ -756,7 +762,9 @@ convert_from_eh_region_ranges (void)
we allocated earlier. */ we allocated earlier. */
for (i = 1; i <= n; ++i) for (i = 1; i <= n; ++i)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region;
region = VEC_index (eh_region, cfun->eh->region_array, i);
if (region && region->tree_label) if (region && region->tree_label)
region->label = DECL_RTL_IF_SET (region->tree_label); region->label = DECL_RTL_IF_SET (region->tree_label);
} }
...@@ -808,9 +816,10 @@ find_exception_handler_labels (void) ...@@ -808,9 +816,10 @@ find_exception_handler_labels (void)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region;
rtx lab; rtx lab;
region = VEC_index (eh_region, cfun->eh->region_array, i);
if (! region || region->region_number != i) if (! region || region->region_number != i)
continue; continue;
if (cfun->eh->built_landing_pads) if (cfun->eh->built_landing_pads)
...@@ -837,8 +846,9 @@ current_function_has_exception_handlers (void) ...@@ -837,8 +846,9 @@ current_function_has_exception_handlers (void)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region;
region = VEC_index (eh_region, cfun->eh->region_array, i);
if (region if (region
&& region->region_number == i && region->region_number == i
&& region->type != ERT_THROW) && region->type != ERT_THROW)
...@@ -856,6 +866,7 @@ duplicate_eh_region_1 (struct eh_region *o) ...@@ -856,6 +866,7 @@ duplicate_eh_region_1 (struct eh_region *o)
*n = *o; *n = *o;
n->region_number = o->region_number + cfun->eh->last_region_number; n->region_number = o->region_number + cfun->eh->last_region_number;
VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n);
gcc_assert (!o->aka); gcc_assert (!o->aka);
return n; return n;
...@@ -916,19 +927,28 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, ...@@ -916,19 +927,28 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
return 0; return 0;
n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array)); n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
cfun->eh->last_region_number + 1 + ifun_last_region_number);
/* We might've created new cfun->eh->region_array so zero out nonexisting region 0. */
VEC_replace (eh_region, cfun->eh->region_array, 0, 0);
for (i = cfun->eh->last_region_number + 1;
i < cfun->eh->last_region_number + 1 + ifun_last_region_number; i++)
VEC_replace (eh_region, cfun->eh->region_array, i, 0);
/* Search for the containing ERT_TRY region to fix up /* Search for the containing ERT_TRY region to fix up
the prev_try short-cuts for ERT_CLEANUP regions. */ the prev_try short-cuts for ERT_CLEANUP regions. */
prev_try = NULL; prev_try = NULL;
if (outer_region > 0) if (outer_region > 0)
for (prev_try = cfun->eh->region_array[outer_region]; for (prev_try = VEC_index (eh_region, cfun->eh->region_array, outer_region);
prev_try && prev_try->type != ERT_TRY; prev_try && prev_try->type != ERT_TRY;
prev_try = prev_try->outer) prev_try = prev_try->outer)
; ;
for (i = 1; i <= ifun_last_region_number; ++i) for (i = 1; i <= ifun_last_region_number; ++i)
{ {
cur = ifun->eh->region_array[i]; cur = VEC_index (eh_region, ifun->eh->region_array, i);
if (!cur || cur->region_number != i) if (!cur || cur->region_number != i)
continue; continue;
n_array[i] = duplicate_eh_region_1 (cur); n_array[i] = duplicate_eh_region_1 (cur);
...@@ -942,7 +962,7 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, ...@@ -942,7 +962,7 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
} }
for (i = 1; i <= ifun_last_region_number; ++i) for (i = 1; i <= ifun_last_region_number; ++i)
{ {
cur = ifun->eh->region_array[i]; cur = VEC_index (eh_region, ifun->eh->region_array, i);
if (!cur || cur->region_number != i) if (!cur || cur->region_number != i)
continue; continue;
duplicate_eh_region_2 (cur, n_array, prev_try); duplicate_eh_region_2 (cur, n_array, prev_try);
...@@ -952,7 +972,8 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, ...@@ -952,7 +972,8 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
gcc_assert (root->outer == NULL); gcc_assert (root->outer == NULL);
if (outer_region > 0) if (outer_region > 0)
{ {
struct eh_region *cur = cfun->eh->region_array[outer_region]; struct eh_region *cur
= VEC_index (eh_region, cfun->eh->region_array, outer_region);
struct eh_region *p = cur->inner; struct eh_region *p = cur->inner;
if (p) if (p)
...@@ -985,8 +1006,6 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, ...@@ -985,8 +1006,6 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
i = cfun->eh->last_region_number; i = cfun->eh->last_region_number;
cfun->eh->last_region_number = i + ifun_last_region_number; cfun->eh->last_region_number = i + ifun_last_region_number;
collect_eh_region_array ();
return i; return i;
} }
...@@ -1180,7 +1199,9 @@ assign_filter_values (void) ...@@ -1180,7 +1199,9 @@ assign_filter_values (void)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
struct eh_region *r = cfun->eh->region_array[i]; struct eh_region *r;
r = VEC_index (eh_region, cfun->eh->region_array, i);
/* Mind we don't process a region more than once. */ /* Mind we don't process a region more than once. */
if (!r || r->region_number != i) if (!r || r->region_number != i)
...@@ -1273,9 +1294,10 @@ build_post_landing_pads (void) ...@@ -1273,9 +1294,10 @@ build_post_landing_pads (void)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region;
rtx seq; rtx seq;
region = VEC_index (eh_region, cfun->eh->region_array, i);
/* Mind we don't process a region more than once. */ /* Mind we don't process a region more than once. */
if (!region || region->region_number != i) if (!region || region->region_number != i)
continue; continue;
...@@ -1392,11 +1414,12 @@ connect_post_landing_pads (void) ...@@ -1392,11 +1414,12 @@ connect_post_landing_pads (void)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region;
struct eh_region *outer; struct eh_region *outer;
rtx seq; rtx seq;
rtx barrier; rtx barrier;
region = VEC_index (eh_region, cfun->eh->region_array, i);
/* Mind we don't process a region more than once. */ /* Mind we don't process a region more than once. */
if (!region || region->region_number != i) if (!region || region->region_number != i)
continue; continue;
...@@ -1469,12 +1492,13 @@ dw2_build_landing_pads (void) ...@@ -1469,12 +1492,13 @@ dw2_build_landing_pads (void)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region;
rtx seq; rtx seq;
basic_block bb; basic_block bb;
bool clobbers_hard_regs = false; bool clobbers_hard_regs = false;
edge e; edge e;
region = VEC_index (eh_region, cfun->eh->region_array, i);
/* Mind we don't process a region more than once. */ /* Mind we don't process a region more than once. */
if (!region || region->region_number != i) if (!region || region->region_number != i)
continue; continue;
...@@ -1570,7 +1594,7 @@ sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info) ...@@ -1570,7 +1594,7 @@ sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
if (!note || INTVAL (XEXP (note, 0)) <= 0) if (!note || INTVAL (XEXP (note, 0)) <= 0)
continue; continue;
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
type_thrown = NULL_TREE; type_thrown = NULL_TREE;
if (region->type == ERT_THROW) if (region->type == ERT_THROW)
...@@ -1612,7 +1636,8 @@ sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info) ...@@ -1612,7 +1636,8 @@ sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
for (i = cfun->eh->last_region_number; i > 0; --i) for (i = cfun->eh->last_region_number; i > 0; --i)
if (lp_info[i].directly_reachable) if (lp_info[i].directly_reachable)
{ {
struct eh_region *r = cfun->eh->region_array[i]; struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
r->landing_pad = dispatch_label; r->landing_pad = dispatch_label;
lp_info[i].action_index = collect_one_action_chain (ar_hash, r); lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
if (lp_info[i].action_index != -1) if (lp_info[i].action_index != -1)
...@@ -1698,7 +1723,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info) ...@@ -1698,7 +1723,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
if (INTVAL (XEXP (note, 0)) <= 0) if (INTVAL (XEXP (note, 0)) <= 0)
continue; continue;
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
this_call_site = lp_info[region->region_number].call_site_index; this_call_site = lp_info[region->region_number].call_site_index;
} }
...@@ -1911,13 +1936,15 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info) ...@@ -1911,13 +1936,15 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index), emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0, EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
cfun->eh->region_array[i]->post_landing_pad); ((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, i))
->post_landing_pad);
} }
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
before = cfun->eh->region_array[first_reachable]->post_landing_pad; before = (((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, first_reachable))
->post_landing_pad);
bb = emit_to_new_bb_before (seq, before); bb = emit_to_new_bb_before (seq, before);
e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU); e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
...@@ -2069,7 +2096,7 @@ remove_eh_handler (struct eh_region *region) ...@@ -2069,7 +2096,7 @@ remove_eh_handler (struct eh_region *region)
list of alternate numbers by which we are known. */ list of alternate numbers by which we are known. */
outer = region->outer; outer = region->outer;
cfun->eh->region_array[region->region_number] = outer; VEC_replace (eh_region, cfun->eh->region_array, region->region_number, outer);
if (region->aka) if (region->aka)
{ {
unsigned i; unsigned i;
...@@ -2077,7 +2104,7 @@ remove_eh_handler (struct eh_region *region) ...@@ -2077,7 +2104,7 @@ remove_eh_handler (struct eh_region *region)
EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
{ {
cfun->eh->region_array[i] = outer; VEC_replace (eh_region, cfun->eh->region_array, i, outer);
} }
} }
...@@ -2211,7 +2238,9 @@ for_each_eh_region (void (*callback) (struct eh_region *)) ...@@ -2211,7 +2238,9 @@ for_each_eh_region (void (*callback) (struct eh_region *))
int i, n = cfun->eh->last_region_number; int i, n = cfun->eh->last_region_number;
for (i = 1; i <= n; ++i) for (i = 1; i <= n; ++i)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region;
region = VEC_index (eh_region, cfun->eh->region_array, i);
if (region) if (region)
(*callback) (region); (*callback) (region);
} }
...@@ -2461,7 +2490,7 @@ foreach_reachable_handler (int region_number, bool is_resx, ...@@ -2461,7 +2490,7 @@ foreach_reachable_handler (int region_number, bool is_resx,
info.callback = callback; info.callback = callback;
info.callback_data = callback_data; info.callback_data = callback_data;
region = cfun->eh->region_array[region_number]; region = VEC_index (eh_region, cfun->eh->region_array, region_number);
type_thrown = NULL_TREE; type_thrown = NULL_TREE;
if (is_resx) if (is_resx)
...@@ -2550,7 +2579,7 @@ can_throw_internal_1 (int region_number, bool is_resx) ...@@ -2550,7 +2579,7 @@ can_throw_internal_1 (int region_number, bool is_resx)
struct eh_region *region; struct eh_region *region;
tree type_thrown; tree type_thrown;
region = cfun->eh->region_array[region_number]; region = VEC_index (eh_region, cfun->eh->region_array, region_number);
type_thrown = NULL_TREE; type_thrown = NULL_TREE;
if (is_resx) if (is_resx)
...@@ -2610,7 +2639,7 @@ can_throw_external_1 (int region_number, bool is_resx) ...@@ -2610,7 +2639,7 @@ can_throw_external_1 (int region_number, bool is_resx)
struct eh_region *region; struct eh_region *region;
tree type_thrown; tree type_thrown;
region = cfun->eh->region_array[region_number]; region = VEC_index (eh_region, cfun->eh->region_array, region_number);
type_thrown = NULL_TREE; type_thrown = NULL_TREE;
if (is_resx) if (is_resx)
...@@ -3158,7 +3187,7 @@ convert_to_eh_region_ranges (void) ...@@ -3158,7 +3187,7 @@ convert_to_eh_region_ranges (void)
{ {
if (INTVAL (XEXP (note, 0)) <= 0) if (INTVAL (XEXP (note, 0)) <= 0)
continue; continue;
region = cfun->eh->region_array[INTVAL (XEXP (note, 0))]; region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
this_action = collect_one_action_chain (ar_hash, region); this_action = collect_one_action_chain (ar_hash, region);
} }
...@@ -3730,10 +3759,10 @@ verify_eh_tree (struct function *fun) ...@@ -3730,10 +3759,10 @@ verify_eh_tree (struct function *fun)
if (! i) if (! i)
return; return;
for (j = fun->eh->last_region_number; j > 0; --j) for (j = fun->eh->last_region_number; j > 0; --j)
if (fun->eh->region_array[j]) if ((i = VEC_index (eh_region, cfun->eh->region_array, j)))
{ {
count++; count++;
if (fun->eh->region_array[j]->region_number != j) if (i->region_number != j)
{ {
error ("region_array is corrupted for region %i", i->region_number); error ("region_array is corrupted for region %i", i->region_number);
err = true; err = true;
...@@ -3742,7 +3771,7 @@ verify_eh_tree (struct function *fun) ...@@ -3742,7 +3771,7 @@ verify_eh_tree (struct function *fun)
while (1) while (1)
{ {
if (fun->eh->region_array[i->region_number] != i) if (VEC_index (eh_region, cfun->eh->region_array, i->region_number) != i)
{ {
error ("region_array is corrupted for region %i", i->region_number); error ("region_array is corrupted for region %i", i->region_number);
err = true; err = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment