Commit 6d07ad98 by Jan Hubicka Committed by Jan Hubicka

tree-eh.c (cleanup_eh): When not optimizing, do not try EH merging.

	* tree-eh.c (cleanup_eh): When not optimizing, do not try EH merging.
	* function.h (rtl_eh): Remove exception_handler_label_map.
	* except.c (ehl_hash, ehl_eq, add_ehl_entry,
	remove_exception_handler_label, for_each_eh_label_1): Remove.
	(rtl_remove_unreachable_regions): Remove.
	(convert_from_eh_region_ranges): Do not remove unreachable regions.
	(find_exception_handler_labels): Don't build the hashtable.
	(maybe_remove_eh_handler): Remove.
	(for_each_eh_label): Rewrite to walk the tree.
	(rest_of_handle_eh): Do not cleanup cfg prior EH construction.
	* except.h (maybe_remove_eh_handler): Remove.
	* passes.c (init_optimization_passes): Schedule second EH cleanup
	before out-of-ssa.
	* cfgrtl.c (rtl_delete_block, rtl_merge_blocks,
	cfg_layout_merge_blocks): Do not call maybe_remove_eh_handler.

From-SVN: r145747
parent 7ddf71e3
2009-04-08 Jan Hubicka <jh@suse.cz>
* tree-eh.c (cleanup_eh): When not optimizing, do not try EH merging.
* function.h (rtl_eh): Remove exception_handler_label_map.
* except.c (ehl_hash, ehl_eq, add_ehl_entry,
remove_exception_handler_label, for_each_eh_label_1): Remove.
(rtl_remove_unreachable_regions): Remove.
(convert_from_eh_region_ranges): Do not remove unreachable regions.
(find_exception_handler_labels): Don't build the hashtable.
(maybe_remove_eh_handler): Remove.
(for_each_eh_label): Rewrite to walk the tree.
(rest_of_handle_eh): Do not cleanup cfg prior EH construction.
* except.h (maybe_remove_eh_handler): Remove.
* passes.c (init_optimization_passes): Schedule second EH cleanup
before out-of-ssa.
* cfgrtl.c (rtl_delete_block, rtl_merge_blocks,
cfg_layout_merge_blocks): Do not call maybe_remove_eh_handler.
2009-04-08 Paolo Bonzini <bonzini@gnu.org>
* genoutput.c (validate_optab_operands): New.
......
......@@ -2198,8 +2198,6 @@ cleanup_cfg (int mode)
static unsigned int
rest_of_handle_jump (void)
{
delete_unreachable_blocks ();
if (crtl->tail_call_emit)
fixup_tail_calls ();
return 0;
......
......@@ -379,8 +379,6 @@ rtl_delete_block (basic_block b)
label for an exception handler which can't be reached. We need
to remove the label from the exception_handler_label list. */
insn = BB_HEAD (b);
if (LABEL_P (insn))
maybe_remove_eh_handler (insn);
end = get_last_bb_insn (b);
......@@ -572,10 +570,6 @@ rtl_merge_blocks (basic_block a, basic_block b)
/* If there was a CODE_LABEL beginning B, delete it. */
if (LABEL_P (b_head))
{
/* This might have been an EH label that no longer has incoming
EH edges. Update data structures to match. */
maybe_remove_eh_handler (b_head);
/* Detect basic blocks with nothing but a label. This can happen
in particular at the end of a function. */
if (b_head == b_end)
......@@ -2598,10 +2592,6 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
/* If there was a CODE_LABEL beginning B, delete it. */
if (LABEL_P (BB_HEAD (b)))
{
/* This might have been an EH label that no longer has incoming
EH edges. Update data structures to match. */
maybe_remove_eh_handler (BB_HEAD (b));
delete_insn (BB_HEAD (b));
}
......
......@@ -248,14 +248,9 @@ static void sjlj_emit_function_exit (void);
static void sjlj_emit_dispatch_table (rtx, struct sjlj_lp_info *);
static void sjlj_build_landing_pads (void);
static hashval_t ehl_hash (const void *);
static int ehl_eq (const void *, const void *);
static void add_ehl_entry (rtx, struct eh_region *);
static void remove_exception_handler_label (rtx);
static void remove_eh_handler (struct eh_region *);
static void remove_eh_handler_and_replace (struct eh_region *,
struct eh_region *);
static int for_each_eh_label_1 (void **, void *);
/* The return value of reachable_next_level. */
enum reachable_code
......@@ -895,53 +890,11 @@ num_eh_regions (void)
return cfun->eh->last_region_number + 1;
}
/* Remove all regions whose labels are not reachable from insns. */
static void
rtl_remove_unreachable_regions (rtx insns)
{
int i, *uid_region_num;
sbitmap reachable;
struct eh_region *r;
rtx insn;
uid_region_num = XCNEWVEC (int, get_max_uid ());
reachable = sbitmap_alloc (cfun->eh->last_region_number + 1);
sbitmap_zero (reachable);
for (i = cfun->eh->last_region_number; i > 0; --i)
{
r = VEC_index (eh_region, cfun->eh->region_array, i);
if (!r || r->region_number != i)
continue;
if (r->resume)
{
gcc_assert (!uid_region_num[INSN_UID (r->resume)]);
uid_region_num[INSN_UID (r->resume)] = i;
}
if (r->label)
{
gcc_assert (!uid_region_num[INSN_UID (r->label)]);
uid_region_num[INSN_UID (r->label)] = i;
}
}
for (insn = insns; insn; insn = NEXT_INSN (insn))
SET_BIT (reachable, uid_region_num[INSN_UID (insn)]);
remove_unreachable_regions (reachable, NULL);
sbitmap_free (reachable);
free (uid_region_num);
}
/* Set up EH labels for RTL. */
void
convert_from_eh_region_ranges (void)
{
rtx insns = get_insns ();
int i, n = cfun->eh->last_region_number;
/* Most of the work is already done at the tree level. All we need to
......@@ -956,31 +909,6 @@ convert_from_eh_region_ranges (void)
if (region && region->tree_label)
region->label = DECL_RTL_IF_SET (region->tree_label);
}
rtl_remove_unreachable_regions (insns);
}
static void
add_ehl_entry (rtx label, struct eh_region *region)
{
struct ehl_map_entry **slot, *entry;
LABEL_PRESERVE_P (label) = 1;
entry = GGC_NEW (struct ehl_map_entry);
entry->label = label;
entry->region = region;
slot = (struct ehl_map_entry **)
htab_find_slot (crtl->eh.exception_handler_label_map, entry, INSERT);
/* Before landing pad creation, each exception handler has its own
label. After landing pad creation, the exception handlers may
share landing pads. This is ok, since maybe_remove_eh_handler
only requires the 1-1 mapping before landing pad creation. */
gcc_assert (!*slot || crtl->eh.built_landing_pads);
*slot = entry;
}
void
......@@ -988,17 +916,6 @@ find_exception_handler_labels (void)
{
int i;
if (crtl->eh.exception_handler_label_map)
htab_empty (crtl->eh.exception_handler_label_map);
else
{
/* ??? The expansion factor here (3/2) must be greater than the htab
occupancy factor (4/3) to avoid unnecessary resizing. */
crtl->eh.exception_handler_label_map
= htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
ehl_hash, ehl_eq, NULL);
}
if (cfun->eh->region_tree == NULL)
return;
......@@ -1014,15 +931,7 @@ find_exception_handler_labels (void)
lab = region->landing_pad;
else
lab = region->label;
if (lab)
add_ehl_entry (lab, region);
}
/* For sjlj exceptions, need the return label to remain live until
after landing pad generation. */
if (USING_SJLJ_EXCEPTIONS && ! crtl->eh.built_landing_pads)
add_ehl_entry (return_label, NULL);
}
/* Returns true if the current function has exception handling regions. */
......@@ -2387,50 +2296,8 @@ finish_eh_generation (void)
}
}
static hashval_t
ehl_hash (const void *pentry)
{
const struct ehl_map_entry *const entry
= (const struct ehl_map_entry *) pentry;
/* 2^32 * ((sqrt(5) - 1) / 2) */
const hashval_t scaled_golden_ratio = 0x9e3779b9;
return CODE_LABEL_NUMBER (entry->label) * scaled_golden_ratio;
}
static int
ehl_eq (const void *pentry, const void *pdata)
{
const struct ehl_map_entry *const entry
= (const struct ehl_map_entry *) pentry;
const struct ehl_map_entry *const data
= (const struct ehl_map_entry *) pdata;
return entry->label == data->label;
}
/* This section handles removing dead code for flow. */
/* Remove LABEL from exception_handler_label_map. */
static void
remove_exception_handler_label (rtx label)
{
struct ehl_map_entry **slot, tmp;
/* If exception_handler_label_map was not built yet,
there is nothing to do. */
if (crtl->eh.exception_handler_label_map == NULL)
return;
tmp.label = label;
slot = (struct ehl_map_entry **)
htab_find_slot (crtl->eh.exception_handler_label_map, &tmp, NO_INSERT);
gcc_assert (slot);
htab_clear_slot (crtl->eh.exception_handler_label_map, (void **) slot);
}
/* Splice REGION from the region tree and replace it by REPLACE etc. */
static void
......@@ -2473,9 +2340,6 @@ remove_eh_handler_and_replace (struct eh_region *region,
lab = region->landing_pad;
else
lab = region->label;
if (lab)
remove_exception_handler_label (lab);
if (outer)
pp_start = &outer->inner;
else
......@@ -2536,45 +2400,6 @@ remove_eh_handler (struct eh_region *region)
remove_eh_handler_and_replace (region, region->outer);
}
/* LABEL heads a basic block that is about to be deleted. If this
label corresponds to an exception region, we may be able to
delete the region. */
void
maybe_remove_eh_handler (rtx label)
{
struct ehl_map_entry **slot, tmp;
struct eh_region *region;
/* ??? After generating landing pads, it's not so simple to determine
if the region data is completely unused. One must examine the
landing pad and the post landing pad, and whether an inner try block
is referencing the catch handlers directly. */
if (crtl->eh.built_landing_pads)
return;
tmp.label = label;
slot = (struct ehl_map_entry **)
htab_find_slot (crtl->eh.exception_handler_label_map, &tmp, NO_INSERT);
if (! slot)
return;
region = (*slot)->region;
if (! region)
return;
/* Flow will want to remove MUST_NOT_THROW regions as unreachable
because there is no path to the fallback call to terminate.
But the region continues to affect call-site data until there
are no more contained calls, which we don't see here. */
if (region->type == ERT_MUST_NOT_THROW)
{
htab_clear_slot (crtl->eh.exception_handler_label_map, (void **) slot);
region->label = NULL_RTX;
}
else
remove_eh_handler (region);
}
/* Remove Eh region R that has turned out to have no code in its handler. */
void
......@@ -2592,18 +2417,14 @@ remove_eh_region (int r)
void
for_each_eh_label (void (*callback) (rtx))
{
htab_traverse (crtl->eh.exception_handler_label_map, for_each_eh_label_1,
(void *) &callback);
}
static int
for_each_eh_label_1 (void **pentry, void *data)
{
struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
void (*callback) (rtx) = *(void (**) (rtx)) data;
(*callback) (entry->label);
return 1;
int i;
for (i = 0; i < cfun->eh->last_region_number; i++)
{
struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
if (r && r->region_number == i && r->label
&& GET_CODE (r->label) == CODE_LABEL)
(*callback) (r->label);
}
}
/* Invoke CALLBACK for every exception region in the current function. */
......@@ -4333,7 +4154,6 @@ gate_handle_eh (void)
static unsigned int
rest_of_handle_eh (void)
{
cleanup_cfg (CLEANUP_NO_INSN_DEL);
finish_eh_generation ();
cleanup_cfg (CLEANUP_NO_INSN_DEL);
return 0;
......
......@@ -62,7 +62,6 @@ extern void init_eh (void);
extern void init_eh_for_function (void);
extern rtx reachable_handlers (rtx);
extern void maybe_remove_eh_handler (rtx);
void remove_eh_region (int);
extern void convert_from_eh_region_ranges (void);
......
......@@ -156,8 +156,6 @@ struct rtl_eh GTY(())
rtx sjlj_fc;
rtx sjlj_exit_after;
htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
VEC(tree,gc) *ttype_data;
varray_type ehspec_data;
varray_type action_record_data;
......
......@@ -706,6 +706,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_uncprop);
NEXT_PASS (pass_local_pure_const);
}
NEXT_PASS (pass_cleanup_eh);
NEXT_PASS (pass_del_ssa);
NEXT_PASS (pass_nrv);
NEXT_PASS (pass_mark_used_blocks);
......
......@@ -3121,23 +3121,26 @@ cleanup_eh (void)
dump_eh_tree (dump_file, cfun);
}
dominance_info_invalidated = false;
/* We cannot use FOR_EACH_BB, since the basic blocks may get removed. */
for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
if (optimize)
{
bb = BASIC_BLOCK (i);
if (bb)
changed |= cleanup_empty_eh (bb);
}
if (dominance_info_invalidated)
{
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
}
dominance_info_invalidated = false;
/* We cannot use FOR_EACH_BB, since the basic blocks may get removed. */
for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
{
bb = BASIC_BLOCK (i);
if (bb)
changed |= cleanup_empty_eh (bb);
}
if (dominance_info_invalidated)
{
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
}
/* Removing contained cleanup can render MUST_NOT_THROW regions empty. */
if (changed)
delete_unreachable_blocks ();
/* Removing contained cleanup can render MUST_NOT_THROW regions empty. */
if (changed)
delete_unreachable_blocks ();
}
tree_remove_unreachable_handlers ();
if (dump_file)
......
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