Commit 98f464e0 by Steven Bosscher Committed by Jan Hubicka

except.c (duplicate_eh_region_1, [...]): New functions, based on old…

except.c (duplicate_eh_region_1, [...]): New functions, based on old implementation removed with RTL inliner.


	* except.c  (duplicate_eh_region_1, duplicate_eh_region_2,
	duplicate_eh_regions): New functions, based on old
	implementation removed with RTL inliner.
	(reachable_next_level): Modify behaviour pre-inline.
	* except.h (duplicate_eh_regions_map, duplicate_eh_regions):
	Declare.
	* function.h (struct function): Add after_inlining flag.
	* tree-optimize.c (tree_rest_of_compilation): Set it.
	* tree-eh.c (add_stmt_to_eh_region_fn): Initialize hashtable
	when needed.
	* tree-cfg.c (label_to_block_fn): Deal with cases where
	label was never insterted into code.

Co-Authored-By: Jan Hubicka <jh@suse.cz>
Co-Authored-By: Stuart Hastings <stuart@apple.com>

From-SVN: r99625
parent 1ed17cd5
2005-05-12 Steven Bosscher <stevenb@suse.de>
Stuart Hastings <stuart@apple.com>
Jan Hubicka <jh@suse.cz>
* except.c (duplicate_eh_region_1, duplicate_eh_region_2,
duplicate_eh_regions): New functions, based on old
implementation removed with RTL inliner.
(reachable_next_level): Modify behaviour pre-inline.
* except.h (duplicate_eh_regions_map, duplicate_eh_regions):
Declare.
* function.h (struct function): Add after_inlining flag.
* tree-optimize.c (tree_rest_of_compilation): Set it.
* tree-eh.c (add_stmt_to_eh_region_fn): Initialize hashtable
when needed.
* tree-cfg.c (label_to_block_fn): Deal with cases where
label was never insterted into code.
2005-05-12 Zack Weinberg <zack@codesourcery.com>
* doc/cpp.texi: Document that #sccs is a synonym for #ident.
......
......@@ -853,6 +853,148 @@ current_function_has_exception_handlers (void)
return false;
}
static struct eh_region *
duplicate_eh_region_1 (struct eh_region *o)
{
struct eh_region *n = ggc_alloc_cleared (sizeof (struct eh_region));
*n = *o;
n->region_number = o->region_number + cfun->eh->last_region_number;
gcc_assert (!o->aka);
return n;
}
static void
duplicate_eh_region_2 (struct eh_region *o, struct eh_region **n_array,
struct eh_region *prev_try)
{
struct eh_region *n = n_array[o->region_number];
switch (n->type)
{
case ERT_TRY:
if (o->u.try.catch)
n->u.try.catch = n_array[o->u.try.catch->region_number];
if (o->u.try.last_catch)
n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
break;
case ERT_CATCH:
if (o->u.catch.next_catch)
n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
if (o->u.catch.prev_catch)
n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
break;
case ERT_CLEANUP:
if (o->u.cleanup.prev_try)
n->u.cleanup.prev_try = n_array[o->u.cleanup.prev_try->region_number];
else
n->u.cleanup.prev_try = prev_try;
break;
default:
break;
}
if (o->outer)
n->outer = n_array[o->outer->region_number];
if (o->inner)
n->inner = n_array[o->inner->region_number];
if (o->next_peer)
n->next_peer = n_array[o->next_peer->region_number];
}
/* Duplicate the EH regions of IFUN into current function, root the tree in
OUTER_REGION and remap labels using MAP callback. */
int
duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
void *data, int outer_region)
{
int ifun_last_region_number = ifun->eh->last_region_number;
struct eh_region **n_array, *root, *cur, *prev_try;
int i;
if (ifun_last_region_number == 0 || !ifun->eh->region_tree)
return 0;
n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
/* 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)
for (prev_try = cfun->eh->region_array[outer_region];
prev_try && prev_try->type != ERT_TRY;
prev_try = prev_try->outer)
;
for (i = 1; i <= ifun_last_region_number; ++i)
{
cur = ifun->eh->region_array[i];
if (!cur || cur->region_number != i)
continue;
n_array[i] = duplicate_eh_region_1 (cur);
if (cur->tree_label)
{
tree newlabel = map (cur->tree_label, data);
n_array[i]->tree_label = newlabel;
}
else
n_array[i]->tree_label = NULL;
}
for (i = 1; i <= ifun_last_region_number; ++i)
{
cur = ifun->eh->region_array[i];
if (!cur || cur->region_number != i)
continue;
duplicate_eh_region_2 (cur, n_array, prev_try);
}
root = n_array[ifun->eh->region_tree->region_number];
gcc_assert (root->outer == NULL);
if (outer_region > 0)
{
struct eh_region *cur = cfun->eh->region_array[outer_region];
struct eh_region *p = cur->inner;
if (p)
{
while (p->next_peer)
p = p->next_peer;
p->next_peer = root;
}
else
cur->inner = root;
for (i = 1; i <= ifun_last_region_number; ++i)
if (n_array[i] && n_array[i]->outer == NULL)
n_array[i]->outer = cur;
}
else
{
struct eh_region *p = cfun->eh->region_tree;
if (p)
{
while (p->next_peer)
p = p->next_peer;
p->next_peer = root;
}
else
cfun->eh->region_tree = root;
}
free (n_array);
i = cfun->eh->last_region_number;
cfun->eh->last_region_number = i + ifun_last_region_number;
collect_eh_region_array ();
return i;
}
static int
t2r_eq (const void *pentry, const void *pdata)
{
......@@ -2273,8 +2415,13 @@ reachable_next_level (struct eh_region *region, tree type_thrown,
/* Here we end our search, since no exceptions may propagate.
If we've touched down at some landing pad previous, then the
explicit function call we generated may be used. Otherwise
the call is made by the runtime. */
if (info && info->saw_any_handlers)
the call is made by the runtime.
Before inlining, do not perform this optimization. We may
inline a subroutine that contains handlers, and that will
change the value of saw_any_handlers. */
if ((info && info->saw_any_handlers) || !cfun->after_inlining)
{
add_reachable_handler (info, region, region);
return RNL_CAUGHT;
......
......@@ -81,6 +81,8 @@ extern void expand_eh_return (void);
extern rtx expand_builtin_extend_pointer (tree);
extern rtx get_exception_pointer (struct function *);
extern rtx get_exception_filter (struct function *);
typedef tree (*duplicate_eh_regions_map) (tree, void *);
extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, void *, int);
extern void sjlj_emit_function_exit_after (rtx);
......
......@@ -168,6 +168,7 @@ struct function GTY(())
/* The control flow graph for this function. */
struct control_flow_graph *cfg;
bool after_inlining;
/* For tree-optimize.c. */
......
......@@ -823,6 +823,8 @@ label_to_block_fn (struct function *ifun, tree dest)
bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
uid = LABEL_DECL_UID (dest);
}
if (VARRAY_SIZE (ifun->cfg->x_label_to_block_map) <= (unsigned int)uid)
return NULL;
return VARRAY_BB (ifun->cfg->x_label_to_block_map, uid);
}
......
......@@ -112,6 +112,11 @@ add_stmt_to_eh_region_fn (struct function *ifun, tree t, int num)
n->stmt = t;
n->region_nr = num;
if (!get_eh_throw_stmt_table (ifun))
set_eh_throw_stmt_table (ifun, htab_create_ggc (31, struct_ptr_hash,
struct_ptr_eq,
ggc_free));
slot = htab_find_slot (get_eh_throw_stmt_table (ifun), n, INSERT);
gcc_assert (!*slot);
*slot = n;
......
......@@ -675,6 +675,7 @@ tree_rest_of_compilation (tree fndecl)
We haven't necessarily assigned RTL to all variables yet, so it's
not safe to try to expand expressions involving them. */
cfun->x_dont_save_pending_sizes_p = 1;
cfun->after_inlining = true;
node = cgraph_node (fndecl);
......
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