tree-eh.c (struct leh_state): Remove prev_try.

* tree-eh.c (struct leh_state): Remove prev_try.
	(lower_try_finally, lower_catch, lower_eh_filter, lower_cleanup): Do
	not track prev_try.
	* except.c (gen_eh_region_cleanup, duplicate_eh_regions, 
	copy_eh_region_1, copy_eh_region, redirect_eh_edge_to_label,
	remove_eh_handler_and_replace, foreach_reachable_handler,
	verify_eh_region, verify_eh_tree): Remove tracking of prev_try pointer.
	* except.h (struct eh_region): Remove eh_region_u_cleanup.
	(gen_eh_region_cleanup): Update prototype.

From-SVN: r147318
This commit is contained in:
Jan Hubicka 2009-05-09 17:00:25 +02:00 committed by Jan Hubicka
parent 0afd721984
commit f08a18d078
4 changed files with 29 additions and 103 deletions

View File

@ -1,3 +1,15 @@
2009-05-09 Jan Hubicka <jh@suse.cz>
* tree-eh.c (struct leh_state): Remove prev_try.
(lower_try_finally, lower_catch, lower_eh_filter, lower_cleanup): Do
not track prev_try.
* except.c (gen_eh_region_cleanup, duplicate_eh_regions,
copy_eh_region_1, copy_eh_region, redirect_eh_edge_to_label,
remove_eh_handler_and_replace, foreach_reachable_handler,
verify_eh_region, verify_eh_tree): Remove tracking of prev_try pointer.
* except.h (struct eh_region): Remove eh_region_u_cleanup.
(gen_eh_region_cleanup): Update prototype.
2009-05-09 Jan Hubicka <jh@suse.cz> 2009-05-09 Jan Hubicka <jh@suse.cz>
PR middle-end/40043 PR middle-end/40043

View File

@ -338,10 +338,9 @@ gen_eh_region (enum eh_region_type type, struct eh_region *outer)
} }
struct eh_region * struct eh_region *
gen_eh_region_cleanup (struct eh_region *outer, struct eh_region *prev_try) gen_eh_region_cleanup (struct eh_region *outer)
{ {
struct eh_region *cleanup = gen_eh_region (ERT_CLEANUP, outer); struct eh_region *cleanup = gen_eh_region (ERT_CLEANUP, outer);
cleanup->u.cleanup.prev_try = prev_try;
return cleanup; return cleanup;
} }
@ -1183,8 +1182,8 @@ duplicate_eh_regions_1 (eh_region old, eh_region outer, int eh_offset)
return ret; return ret;
} }
/* Return prev_try pointers catch subregions of R should /* Look for first outer region of R (or R itself) that is
point to. */ TRY region. Return NULL if none. */
static struct eh_region * static struct eh_region *
find_prev_try (struct eh_region * r) find_prev_try (struct eh_region * r)
@ -1208,7 +1207,7 @@ int
duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map, duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
void *data, int copy_region, int outer_region) void *data, int copy_region, int outer_region)
{ {
eh_region cur, prev_try, old_prev_try, outer, *splice; eh_region cur, outer, *splice;
int i, min_region, max_region, eh_offset, cfun_last_region_number; int i, min_region, max_region, eh_offset, cfun_last_region_number;
int num_regions; int num_regions;
@ -1228,14 +1227,12 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
max_region = 0; max_region = 0;
cur = VEC_index (eh_region, ifun->eh->region_array, copy_region); cur = VEC_index (eh_region, ifun->eh->region_array, copy_region);
old_prev_try = find_prev_try (cur);
duplicate_eh_regions_0 (cur, &min_region, &max_region); duplicate_eh_regions_0 (cur, &min_region, &max_region);
} }
else else
{ {
min_region = 1; min_region = 1;
max_region = ifun->eh->last_region_number; max_region = ifun->eh->last_region_number;
old_prev_try = NULL;
} }
num_regions = max_region - min_region + 1; num_regions = max_region - min_region + 1;
cfun_last_region_number = cfun->eh->last_region_number; cfun_last_region_number = cfun->eh->last_region_number;
@ -1302,12 +1299,6 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
if (cur && cur->tree_label) if (cur && cur->tree_label)
cur->tree_label = map (cur->tree_label, data); cur->tree_label = map (cur->tree_label, data);
/* Search for the containing ERT_TRY region to fix up
the prev_try short-cuts for ERT_CLEANUP regions. */
prev_try = NULL;
if (outer_region > 0)
prev_try = find_prev_try (VEC_index (eh_region, cfun->eh->region_array, outer_region));
/* Remap all of the internal catch and cleanup linkages. Since we /* Remap all of the internal catch and cleanup linkages. Since we
duplicate entire subtrees, all of the referenced regions will have duplicate entire subtrees, all of the referenced regions will have
been copied too. And since we renumbered them as a block, a simple been copied too. And since we renumbered them as a block, a simple
@ -1354,13 +1345,6 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
REMAP (cur->u.eh_catch.prev_catch); REMAP (cur->u.eh_catch.prev_catch);
break; break;
case ERT_CLEANUP:
if (cur->u.cleanup.prev_try != old_prev_try)
REMAP (cur->u.cleanup.prev_try);
else
cur->u.cleanup.prev_try = prev_try;
break;
default: default:
break; break;
} }
@ -1394,14 +1378,10 @@ copy_eh_region_1 (struct eh_region *old, struct eh_region *new_outer)
/* Return new copy of eh region OLD inside region NEW_OUTER. /* Return new copy of eh region OLD inside region NEW_OUTER.
Copy whole catch-try chain if neccesary and update cleanup region prev_try Copy whole catch-try chain if neccesary. */
pointers.
PREV_TRY_MAP points to outer TRY region if it was copied in trace already. */
static struct eh_region * static struct eh_region *
copy_eh_region (struct eh_region *old, struct eh_region *new_outer, copy_eh_region (struct eh_region *old, struct eh_region *new_outer)
struct eh_region *prev_try_map)
{ {
struct eh_region *r, *n, *old_try, *new_try, *ret = NULL; struct eh_region *r, *n, *old_try, *new_try, *ret = NULL;
VEC(eh_region,heap) *catch_list = NULL; VEC(eh_region,heap) *catch_list = NULL;
@ -1410,11 +1390,6 @@ copy_eh_region (struct eh_region *old, struct eh_region *new_outer,
{ {
gcc_assert (old->type != ERT_TRY); gcc_assert (old->type != ERT_TRY);
r = copy_eh_region_1 (old, new_outer); r = copy_eh_region_1 (old, new_outer);
if (r->type == ERT_CLEANUP)
{
gcc_assert (r->u.cleanup.prev_try || !prev_try_map);
r->u.cleanup.prev_try = prev_try_map;
}
return r; return r;
} }
@ -1477,7 +1452,7 @@ struct eh_region *
redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx, redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
bool inlinable_call, int region_number) bool inlinable_call, int region_number)
{ {
struct eh_region *outer, *prev_try_map; struct eh_region *outer;
struct eh_region *region; struct eh_region *region;
VEC (eh_region, heap) * trace = NULL; VEC (eh_region, heap) * trace = NULL;
int i; int i;
@ -1539,7 +1514,6 @@ redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
} }
outer = VEC_index (eh_region, trace, start_here)->outer; outer = VEC_index (eh_region, trace, start_here)->outer;
gcc_assert (start_here >= 0); gcc_assert (start_here >= 0);
prev_try_map = find_prev_try (outer);
/* And now do the dirty job! */ /* And now do the dirty job! */
for (i = start_here; i >= 0; i--) for (i = start_here; i >= 0; i--)
@ -1548,7 +1522,7 @@ redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
gcc_assert (!outer || old->outer != outer->outer); gcc_assert (!outer || old->outer != outer->outer);
/* Copy region and update label. */ /* Copy region and update label. */
r = copy_eh_region (old, outer, prev_try_map); r = copy_eh_region (old, outer);
VEC_replace (eh_region, trace, i, r); VEC_replace (eh_region, trace, i, r);
if (r->tree_label && label_to_block (r->tree_label) == old_bb) if (r->tree_label && label_to_block (r->tree_label) == old_bb)
{ {
@ -1588,14 +1562,11 @@ redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
} }
} }
/* Cleanup regions points to outer TRY blocks. */
if (r->type == ERT_TRY)
prev_try_map = r;
outer = r; outer = r;
} }
if (is_resx || region->type == ERT_THROW) if (is_resx || region->type == ERT_THROW)
r = copy_eh_region (region, outer, prev_try_map); r = copy_eh_region (region, outer);
} }
VEC_free (eh_region, heap, trace); VEC_free (eh_region, heap, trace);
@ -2674,32 +2645,6 @@ remove_eh_handler_and_replace (struct eh_region *region,
outer = region->outer; outer = region->outer;
/* When we are moving the region in EH tree, update prev_try pointers. */
if ((outer != replace || region->type == ERT_TRY) && region->inner)
{
struct eh_region *prev_try = find_prev_try (replace);
p = region->inner;
while (p != region)
{
if (p->type == ERT_CLEANUP)
p->u.cleanup.prev_try = prev_try;
if (p->type != ERT_TRY
&& p->type != ERT_MUST_NOT_THROW
&& (p->type != ERT_ALLOWED_EXCEPTIONS
|| p->u.allowed.type_list)
&& p->inner)
p = p->inner;
else if (p->next_peer)
p = p->next_peer;
else
{
while (p != region && !p->next_peer)
p = p->outer;
if (p != region)
p = p->next_peer;
}
}
}
/* For the benefit of efficiently handling REG_EH_REGION notes, /* For the benefit of efficiently handling REG_EH_REGION notes,
replace this region in the region array with its containing replace this region in the region array with its containing
region. Note that previous region deletions may result in region. Note that previous region deletions may result in
@ -3123,7 +3068,7 @@ foreach_reachable_handler (int region_number, bool is_resx, bool inlinable_call,
if (region->type == ERT_CLEANUP) if (region->type == ERT_CLEANUP)
{ {
enum reachable_code code = RNL_NOT_CAUGHT; enum reachable_code code = RNL_NOT_CAUGHT;
region = region->u.cleanup.prev_try; region = find_prev_try (region->outer);
/* Continue looking for outer TRY region until we find one /* Continue looking for outer TRY region until we find one
that might cath something. */ that might cath something. */
while (region while (region
@ -4431,9 +4376,6 @@ dump_eh_tree (FILE * out, struct function *fun)
switch (i->type) switch (i->type)
{ {
case ERT_CLEANUP: case ERT_CLEANUP:
if (i->u.cleanup.prev_try)
fprintf (out, " prev try:%i",
i->u.cleanup.prev_try->region_number);
break; break;
case ERT_TRY: case ERT_TRY:
@ -4513,21 +4455,13 @@ debug_eh_tree (struct function *fn)
/* Verify EH region invariants. */ /* Verify EH region invariants. */
static bool static bool
verify_eh_region (struct eh_region *region, struct eh_region *prev_try) verify_eh_region (struct eh_region *region)
{ {
bool found = false; bool found = false;
if (!region) if (!region)
return false; return false;
switch (region->type) switch (region->type)
{ {
case ERT_CLEANUP:
if (region->u.cleanup.prev_try != prev_try)
{
error ("Wrong prev_try pointer in EH region %i",
region->region_number);
found = true;
}
break;
case ERT_TRY: case ERT_TRY:
{ {
struct eh_region *c, *prev = NULL; struct eh_region *c, *prev = NULL;
@ -4574,6 +4508,7 @@ verify_eh_region (struct eh_region *region, struct eh_region *prev_try)
found = true; found = true;
} }
break; break;
case ERT_CLEANUP:
case ERT_ALLOWED_EXCEPTIONS: case ERT_ALLOWED_EXCEPTIONS:
case ERT_MUST_NOT_THROW: case ERT_MUST_NOT_THROW:
case ERT_THROW: case ERT_THROW:
@ -4581,14 +4516,8 @@ verify_eh_region (struct eh_region *region, struct eh_region *prev_try)
case ERT_UNKNOWN: case ERT_UNKNOWN:
gcc_unreachable (); gcc_unreachable ();
} }
if (region->type == ERT_TRY)
prev_try = region;
else if (region->type == ERT_MUST_NOT_THROW
|| (region->type == ERT_ALLOWED_EXCEPTIONS
&& !region->u.allowed.type_list))
prev_try = NULL;
for (region = region->inner; region; region = region->next_peer) for (region = region->inner; region; region = region->next_peer)
found |= verify_eh_region (region, prev_try); found |= verify_eh_region (region);
return found; return found;
} }
@ -4672,7 +4601,7 @@ verify_eh_tree (struct function *fun)
} }
if (!err) if (!err)
for (i = fun->eh->region_tree; i; i = i->next_peer) for (i = fun->eh->region_tree; i; i = i->next_peer)
err |= verify_eh_region (i, NULL); err |= verify_eh_region (i);
if (err) if (err)
{ {

View File

@ -85,12 +85,6 @@ struct GTY(()) eh_region
struct eh_region_u_throw { struct eh_region_u_throw {
tree type; tree type;
} GTY ((tag ("ERT_THROW"))) eh_throw; } GTY ((tag ("ERT_THROW"))) eh_throw;
/* Retain the cleanup expression even after expansion so that
we can match up fixup regions. */
struct eh_region_u_cleanup {
struct eh_region *prev_try;
} GTY ((tag ("ERT_CLEANUP"))) cleanup;
} GTY ((desc ("%0.type"))) u; } GTY ((desc ("%0.type"))) u;
/* Entry point for this region's handler before landing pads are built. */ /* Entry point for this region's handler before landing pads are built. */
@ -185,8 +179,7 @@ extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map,
extern void sjlj_emit_function_exit_after (rtx); extern void sjlj_emit_function_exit_after (rtx);
extern void default_init_unwind_resume_libfunc (void); extern void default_init_unwind_resume_libfunc (void);
extern struct eh_region *gen_eh_region_cleanup (struct eh_region *, extern struct eh_region *gen_eh_region_cleanup (struct eh_region *);
struct eh_region *);
extern struct eh_region *gen_eh_region_try (struct eh_region *); extern struct eh_region *gen_eh_region_try (struct eh_region *);
extern struct eh_region *gen_eh_region_catch (struct eh_region *, tree); extern struct eh_region *gen_eh_region_catch (struct eh_region *, tree);
extern struct eh_region *gen_eh_region_allowed (struct eh_region *, tree); extern struct eh_region *gen_eh_region_allowed (struct eh_region *, tree);

View File

@ -352,7 +352,6 @@ struct leh_state
correspond to variables of the same name in cfun->eh, which we correspond to variables of the same name in cfun->eh, which we
don't have easy access to. */ don't have easy access to. */
struct eh_region *cur_region; struct eh_region *cur_region;
struct eh_region *prev_try;
/* Processing of TRY_FINALLY requires a bit more state. This is /* Processing of TRY_FINALLY requires a bit more state. This is
split out into a separate structure so that we don't have to split out into a separate structure so that we don't have to
@ -1566,12 +1565,11 @@ lower_try_finally (struct leh_state *state, gimple tp)
this_tf.outer = state; this_tf.outer = state;
if (using_eh_for_cleanups_p) if (using_eh_for_cleanups_p)
this_tf.region this_tf.region
= gen_eh_region_cleanup (state->cur_region, state->prev_try); = gen_eh_region_cleanup (state->cur_region);
else else
this_tf.region = NULL; this_tf.region = NULL;
this_state.cur_region = this_tf.region; this_state.cur_region = this_tf.region;
this_state.prev_try = state->prev_try;
this_state.tf = &this_tf; this_state.tf = &this_tf;
lower_eh_constructs_1 (&this_state, gimple_try_eval(tp)); lower_eh_constructs_1 (&this_state, gimple_try_eval(tp));
@ -1650,7 +1648,6 @@ lower_catch (struct leh_state *state, gimple tp)
try_region = gen_eh_region_try (state->cur_region); try_region = gen_eh_region_try (state->cur_region);
this_state.cur_region = try_region; this_state.cur_region = try_region;
this_state.prev_try = try_region;
this_state.tf = state->tf; this_state.tf = state->tf;
lower_eh_constructs_1 (&this_state, gimple_try_eval (tp)); lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
@ -1672,7 +1669,6 @@ lower_catch (struct leh_state *state, gimple tp)
gimple_catch_types (gcatch)); gimple_catch_types (gcatch));
this_state.cur_region = catch_region; this_state.cur_region = catch_region;
this_state.prev_try = state->prev_try;
lower_eh_constructs_1 (&this_state, gimple_catch_handler (gcatch)); lower_eh_constructs_1 (&this_state, gimple_catch_handler (gcatch));
eh_label = create_artificial_label (); eh_label = create_artificial_label ();
@ -1719,10 +1715,6 @@ lower_eh_filter (struct leh_state *state, gimple tp)
gimple_eh_filter_types (inner)); gimple_eh_filter_types (inner));
this_state = *state; this_state = *state;
this_state.cur_region = this_region; this_state.cur_region = this_region;
/* For must not throw regions any cleanup regions inside it
can't reach outer catch regions. */
if (gimple_eh_filter_must_not_throw (inner))
this_state.prev_try = NULL;
lower_eh_constructs_1 (&this_state, gimple_try_eval (tp)); lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
@ -1759,7 +1751,7 @@ lower_cleanup (struct leh_state *state, gimple tp)
return result; return result;
} }
this_region = gen_eh_region_cleanup (state->cur_region, state->prev_try); this_region = gen_eh_region_cleanup (state->cur_region);
this_state = *state; this_state = *state;
this_state.cur_region = this_region; this_state.cur_region = this_region;