From: hubicka Date: Wed, 8 Apr 2009 15:13:01 +0000 (+0000) Subject: * tree-eh.c (cleanup_eh): When not optimizing, do not try EH merging. X-Git-Tag: upstream/4.9.2~37052 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=48d5ef936a6789741451bd5c111039cba5cb275b;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145747 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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 + + * 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 * 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)