aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2009-04-08 17:13:01 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2009-04-08 15:13:01 +0000
commit6d07ad98760362cd9615c673cf8302908ce60980 (patch)
treedde23269eb49d700833365c7340d997fe20ae49d
parent7ddf71e3171fb2d809e7baf6a94c9243b8d9fcac (diff)
downloadgcc-6d07ad98760362cd9615c673cf8302908ce60980.zip
gcc-6d07ad98760362cd9615c673cf8302908ce60980.tar.gz
gcc-6d07ad98760362cd9615c673cf8302908ce60980.tar.bz2
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
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/cfgcleanup.c2
-rw-r--r--gcc/cfgrtl.c10
-rw-r--r--gcc/except.c196
-rw-r--r--gcc/except.h1
-rw-r--r--gcc/function.h2
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/tree-eh.c33
8 files changed, 45 insertions, 218 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4f3d18d..c6ec14d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+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.
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 190bde6..39aae8c 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -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;
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index a7dc507..95d28ac 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -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));
}
diff --git a/gcc/except.c b/gcc/except.c
index e92b827..7e89e06 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -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;
diff --git a/gcc/except.h b/gcc/except.h
index 741c654..24611a5 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -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);
diff --git a/gcc/function.h b/gcc/function.h
index 7079797..5bee64b 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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;
diff --git a/gcc/passes.c b/gcc/passes.c
index f19b8dd..f3f43d4 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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);
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 7f04068..bc93ee1 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -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)