From 8f8dcce4abc08b582f0124d0b5a053bf36a34db0 Mon Sep 17 00:00:00 2001 From: rth Date: Wed, 10 Apr 2002 00:15:58 +0000 Subject: [PATCH] * basic-block.h (flow_delete_block_noexpunge): Declare. (expunge_block_nocompact): Declare. * cfg.c (expunge_block_nocompact): Split out from ... (expunge_block): ... here. * cfgrtl.c (can_delete_label_p): Don't use exception_handler_labels. (flow_delete_block_noexpunge): Split out from ... (flow_delete_block): ... here. * cfgcleanup.c (delete_unreachable_blocks): Compact while removing dead blocks. * except.c (exception_handler_labels): Remove. (exception_handler_label_map): New. (struct eh_region): Add aka member. (mark_ehl_map_entry, mark_ehl_map, free_region): New. (ehl_hash, ehl_eq, ehl_free, add_ehl_entry): New. (for_each_eh_label, for_each_eh_label_1): New. (init_eh): Register exception_handler_label_map. (free_eh_status): Use free_region. (find_exception_handler_labels): Use the map, not the list. (remove_exception_handler_label): Likewise. (maybe_remove_eh_handler): Likewise. (remove_eh_handler): Use the region aka bitmap. * except.h (exception_handler_labels): Remove. (for_each_eh_label): Declare. * jump.c (rebuild_jump_labels): Don't check exception_handler_labels. * loop.c (invalidate_loops_containing_label): New. (find_and_verify_loops): Use it. Use for_each_eh_label. * sched-rgn.c (is_cfg_nonregular): Use current_function_has_exception_handlers. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52100 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 31 +++++++ gcc/basic-block.h | 4 +- gcc/cfg.c | 20 +++-- gcc/cfgcleanup.c | 25 ++++-- gcc/cfgrtl.c | 16 +++- gcc/except.c | 248 +++++++++++++++++++++++++++++++++++++++++++----------- gcc/except.h | 7 +- gcc/jump.c | 7 -- gcc/loop.c | 33 ++++---- gcc/sched-rgn.c | 2 +- 10 files changed, 297 insertions(+), 96 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a762370..8aa8936 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,36 @@ 2002-04-09 Richard Henderson + * basic-block.h (flow_delete_block_noexpunge): Declare. + (expunge_block_nocompact): Declare. + * cfg.c (expunge_block_nocompact): Split out from ... + (expunge_block): ... here. + * cfgrtl.c (can_delete_label_p): Don't use exception_handler_labels. + (flow_delete_block_noexpunge): Split out from ... + (flow_delete_block): ... here. + * cfgcleanup.c (delete_unreachable_blocks): Compact while + removing dead blocks. + * except.c (exception_handler_labels): Remove. + (exception_handler_label_map): New. + (struct eh_region): Add aka member. + (mark_ehl_map_entry, mark_ehl_map, free_region): New. + (ehl_hash, ehl_eq, ehl_free, add_ehl_entry): New. + (for_each_eh_label, for_each_eh_label_1): New. + (init_eh): Register exception_handler_label_map. + (free_eh_status): Use free_region. + (find_exception_handler_labels): Use the map, not the list. + (remove_exception_handler_label): Likewise. + (maybe_remove_eh_handler): Likewise. + (remove_eh_handler): Use the region aka bitmap. + * except.h (exception_handler_labels): Remove. + (for_each_eh_label): Declare. + * jump.c (rebuild_jump_labels): Don't check exception_handler_labels. + * loop.c (invalidate_loops_containing_label): New. + (find_and_verify_loops): Use it. Use for_each_eh_label. + * sched-rgn.c (is_cfg_nonregular): Use + current_function_has_exception_handlers. + +2002-04-09 Richard Henderson + * sbitmap.c (sbitmap_union_of_diff, sbitmap_a_and_b, sbitmap_a_xor_b, sbitmap_a_or_b, sbitmap_a_or_b_and_c, sbitmap_a_and_b_or_c): Do not return changed status. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index c9fc4b8..24d2af8 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -1,5 +1,5 @@ /* Define control and data flow tables, and regsets. - Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001 + Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -316,6 +316,7 @@ extern void redirect_edge_pred PARAMS ((edge, basic_block)); extern basic_block create_basic_block_structure PARAMS ((int, rtx, rtx, rtx)); extern basic_block create_basic_block PARAMS ((int, rtx, rtx)); extern int flow_delete_block PARAMS ((basic_block)); +extern int flow_delete_block_noexpunge PARAMS ((basic_block)); extern void clear_bb_flags PARAMS ((void)); extern void merge_blocks_nomove PARAMS ((basic_block, basic_block)); extern void tidy_fallthru_edge PARAMS ((edge, basic_block, @@ -637,6 +638,7 @@ extern void debug_regset PARAMS ((regset)); extern void allocate_reg_life_data PARAMS ((void)); extern void allocate_bb_life_data PARAMS ((void)); extern void expunge_block PARAMS ((basic_block)); +extern void expunge_block_nocompact PARAMS ((basic_block)); extern basic_block alloc_block PARAMS ((void)); extern void find_unreachable_blocks PARAMS ((void)); extern int delete_noop_moves PARAMS ((rtx)); diff --git a/gcc/cfg.c b/gcc/cfg.c index 0a71867..766c1b8 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -223,6 +223,17 @@ alloc_block () /* Remove block B from the basic block array and compact behind it. */ void +expunge_block_nocompact (b) + basic_block b; +{ + /* Invalidate data to make bughunting easier. */ + memset (b, 0, sizeof *b); + b->index = -3; + b->succ = (edge) first_deleted_block; + first_deleted_block = (basic_block) b; +} + +void expunge_block (b) basic_block b; { @@ -235,13 +246,10 @@ expunge_block (b) x->index = i; } - /* Invalidate data to make bughunting easier. */ - memset (b, 0, sizeof *b); - b->index = -3; - basic_block_info->num_elements--; n_basic_blocks--; - b->succ = (edge) first_deleted_block; - first_deleted_block = (basic_block) b; + basic_block_info->num_elements--; + + expunge_block_nocompact (b); } /* Create an edge connecting SRC and DST with FLAGS optionally using diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index b6a7f0c..74a2256 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1,6 +1,6 @@ /* Control flow optimization code for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -1751,22 +1751,33 @@ try_optimize_cfg (mode) static bool delete_unreachable_blocks () { - int i; + int i, j; bool changed = false; find_unreachable_blocks (); - /* Delete all unreachable basic blocks. Count down so that we - don't interfere with the block renumbering that happens in - flow_delete_block. */ + /* Delete all unreachable basic blocks. Do compaction concurrently, + as otherwise we can wind up with O(N^2) behaviour here when we + have oodles of dead code. */ - for (i = n_basic_blocks - 1; i >= 0; --i) + for (i = j = 0; i < n_basic_blocks; ++i) { basic_block b = BASIC_BLOCK (i); if (!(b->flags & BB_REACHABLE)) - flow_delete_block (b), changed = true; + { + flow_delete_block_noexpunge (b); + expunge_block_nocompact (b); + changed = true; + } + else + { + BASIC_BLOCK (j) = b; + b->index = j++; + } } + n_basic_blocks = j; + basic_block_info->num_elements = j; if (changed) tidy_fallthru_edges (); diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index ef9a91c..a56eea2 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1,6 +1,6 @@ /* Control flow graph manipulation code for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -102,8 +102,7 @@ can_delete_label_p (label) /* User declared labels must be preserved. */ && LABEL_NAME (label) == 0 && !in_expr_list_p (forced_labels, label) - && !in_expr_list_p (label_value_list, label) - && !in_expr_list_p (exception_handler_labels, label)); + && !in_expr_list_p (label_value_list, label)); } /* Delete INSN by patching it out. Return the next insn. */ @@ -363,7 +362,7 @@ create_basic_block (index, head, end) to post-process the stream to remove empty blocks, loops, ranges, etc. */ int -flow_delete_block (b) +flow_delete_block_noexpunge (b) basic_block b; { int deleted_handler = 0; @@ -412,6 +411,15 @@ flow_delete_block (b) b->pred = NULL; b->succ = NULL; + return deleted_handler; +} + +int +flow_delete_block (b) + basic_block b; +{ + int deleted_handler = flow_delete_block_noexpunge (b); + /* Remove the basic block from the array, and compact behind it. */ expunge_block (b); diff --git a/gcc/except.c b/gcc/except.c index e5079f9..d4a903e 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -98,8 +98,15 @@ int (*lang_eh_type_covers) PARAMS ((tree a, tree b)); /* Map a type to a runtime object to match type. */ tree (*lang_eh_runtime_type) PARAMS ((tree)); -/* A list of labels used for exception handlers. */ -rtx exception_handler_labels; +/* A hash table of label to region number. */ + +struct ehl_map_entry +{ + rtx label; + struct eh_region *region; +}; + +static htab_t exception_handler_label_map; static int call_site_base; static unsigned int sjlj_funcdef_number; @@ -126,6 +133,10 @@ struct eh_region /* An identifier for this region. */ int region_number; + /* When a region is deleted, its parents inherit the REG_EH_REGION + numbers already assigned. */ + bitmap aka; + /* Each region does exactly one thing. */ enum eh_region_type { @@ -242,6 +253,10 @@ struct eh_status static void mark_eh_region PARAMS ((struct eh_region *)); +static int mark_ehl_map_entry PARAMS ((PTR *, PTR)); +static void mark_ehl_map PARAMS ((void *)); + +static void free_region PARAMS ((struct eh_region *)); static int t2r_eq PARAMS ((const PTR, const PTR)); @@ -292,8 +307,15 @@ static void sjlj_emit_dispatch_table PARAMS ((rtx, struct sjlj_lp_info *)); static void sjlj_build_landing_pads PARAMS ((void)); +static hashval_t ehl_hash PARAMS ((const PTR)); +static int ehl_eq PARAMS ((const PTR, + const PTR)); +static void ehl_free PARAMS ((PTR)); +static void add_ehl_entry PARAMS ((rtx, + struct eh_region *)); static void remove_exception_handler_label PARAMS ((rtx)); static void remove_eh_handler PARAMS ((struct eh_region *)); +static int for_each_eh_label_1 PARAMS ((PTR *, PTR)); struct reachable_info; @@ -364,7 +386,7 @@ doing_eh (do_warn) void init_eh () { - ggc_add_rtx_root (&exception_handler_labels, 1); + ggc_add_root (&exception_handler_label_map, 1, 1, mark_ehl_map); if (! flag_exceptions) return; @@ -511,6 +533,25 @@ mark_eh_region (region) ggc_mark_rtx (region->post_landing_pad); } +static int +mark_ehl_map_entry (pentry, data) + PTR *pentry; + PTR data ATTRIBUTE_UNUSED; +{ + struct ehl_map_entry *entry = *(struct ehl_map_entry **) pentry; + ggc_mark_rtx (entry->label); + return 1; +} + +static void +mark_ehl_map (pp) + void *pp; +{ + htab_t map = *(htab_t *) pp; + if (map) + htab_traverse (map, mark_ehl_map_entry, NULL); +} + void mark_eh_status (eh) struct eh_status *eh; @@ -572,6 +613,16 @@ mark_eh_status (eh) ggc_mark_rtx (eh->sjlj_exit_after); } +static inline void +free_region (r) + struct eh_region *r; +{ + /* Note that the aka bitmap is freed by regset_release_memory. But if + we ever replace with a non-obstack implementation, this would be + the place to do it. */ + free (r); +} + void free_eh_status (f) struct function *f; @@ -586,7 +637,7 @@ free_eh_status (f) struct eh_region *r = eh->region_array[i]; /* Mind we don't free a region struct more than once. */ if (r && r->region_number == i) - free (r); + free_region (r); } free (eh->region_array); } @@ -600,20 +651,20 @@ free_eh_status (f) else if (r->next_peer) { next = r->next_peer; - free (r); + free_region (r); r = next; } else { do { next = r->outer; - free (r); + free_region (r); r = next; if (r == NULL) goto tree_done; } while (r->next_peer == NULL); next = r->next_peer; - free (r); + free_region (r); r = next; } } @@ -628,7 +679,12 @@ free_eh_status (f) free (eh); f->eh = NULL; - exception_handler_labels = NULL; + + if (exception_handler_label_map) + { + htab_delete (exception_handler_label_map); + exception_handler_label_map = NULL; + } } @@ -1312,13 +1368,50 @@ convert_from_eh_region_ranges () remove_unreachable_regions (insns); } +static void +add_ehl_entry (label, region) + rtx label; + struct eh_region *region; +{ + struct ehl_map_entry **slot, *entry; + + LABEL_PRESERVE_P (label) = 1; + + entry = (struct ehl_map_entry *) xmalloc (sizeof (*entry)); + entry->label = label; + entry->region = region; + + slot = (struct ehl_map_entry **) + htab_find_slot (exception_handler_label_map, entry, INSERT); + if (*slot) + abort (); + *slot = entry; +} + +static void +ehl_free (pentry) + PTR pentry; +{ + struct ehl_map_entry *entry = (struct ehl_map_entry *)pentry; + LABEL_PRESERVE_P (entry->label) = 0; + free (entry); +} + void find_exception_handler_labels () { - rtx list = NULL_RTX; int i; - free_EXPR_LIST_list (&exception_handler_labels); + if (exception_handler_label_map) + htab_empty (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. */ + exception_handler_label_map + = htab_create (cfun->eh->last_region_number * 3 / 2, + ehl_hash, ehl_eq, ehl_free); + } if (cfun->eh->region_tree == NULL) return; @@ -1336,15 +1429,13 @@ find_exception_handler_labels () lab = region->label; if (lab) - list = alloc_EXPR_LIST (0, lab, list); + add_ehl_entry (lab, region); } /* For sjlj exceptions, need the return label to remain live until after landing pad generation. */ if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads) - list = alloc_EXPR_LIST (0, return_label, list); - - exception_handler_labels = list; + add_ehl_entry (return_label, NULL); } bool @@ -2430,28 +2521,50 @@ finish_eh_generation () cleanup_cfg (CLEANUP_PRE_LOOP); } +static hashval_t +ehl_hash (pentry) + const PTR pentry; +{ + struct ehl_map_entry *entry = (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 (pentry, pdata) + const PTR pentry; + const PTR pdata; +{ + struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry; + struct ehl_map_entry *data = (struct ehl_map_entry *) pdata; + + return entry->label == data->label; +} + /* This section handles removing dead code for flow. */ -/* Remove LABEL from the exception_handler_labels list. */ +/* Remove LABEL from exception_handler_label_map. */ static void remove_exception_handler_label (label) rtx label; { - rtx *pl, l; + struct ehl_map_entry **slot, tmp; - /* If exception_handler_labels was not built yet, + /* If exception_handler_label_map was not built yet, there is nothing to do. */ - if (exception_handler_labels == NULL) + if (exception_handler_label_map == NULL) return; - for (pl = &exception_handler_labels, l = *pl; - XEXP (l, 0) != label; - pl = &XEXP (l, 1), l = *pl) - continue; + tmp.label = label; + slot = (struct ehl_map_entry **) + htab_find_slot (exception_handler_label_map, &tmp, NO_INSERT); + if (! slot) + abort (); - *pl = XEXP (l, 1); - free_EXPR_LIST_node (l); + htab_clear_slot (exception_handler_label_map, (void **) slot); } /* Splice REGION from the region tree etc. */ @@ -2462,16 +2575,29 @@ remove_eh_handler (region) { struct eh_region **pp, *p; rtx lab; - int i; /* For the benefit of efficiently handling REG_EH_REGION notes, replace this region in the region array with its containing region. Note that previous region deletions may result in - multiple copies of this region in the array, so we have to - search the whole thing. */ - for (i = cfun->eh->last_region_number; i > 0; --i) - if (cfun->eh->region_array[i] == region) - cfun->eh->region_array[i] = region->outer; + multiple copies of this region in the array, so we have a + list of alternate numbers by which we are known. */ + + cfun->eh->region_array[region->region_number] = region->outer; + if (region->aka) + { + int i; + EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, + { cfun->eh->region_array[i] = region->outer; }); + } + + if (region->outer) + { + if (!region->outer->aka) + region->outer->aka = BITMAP_XMALLOC (); + if (region->aka) + bitmap_a_or_b (region->outer->aka, region->outer->aka, region->aka); + bitmap_set_bit (region->outer->aka, region->region_number); + } if (cfun->eh->built_landing_pads) lab = region->landing_pad; @@ -2526,7 +2652,7 @@ remove_eh_handler (region) } } - free (region); + free_region (region); } /* LABEL heads a basic block that is about to be deleted. If this @@ -2537,7 +2663,8 @@ void maybe_remove_eh_handler (label) rtx label; { - int i; + 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 @@ -2546,27 +2673,50 @@ maybe_remove_eh_handler (label) if (cfun->eh->built_landing_pads) return; - for (i = cfun->eh->last_region_number; i > 0; --i) + tmp.label = label; + slot = (struct ehl_map_entry **) + htab_find_slot (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) { - struct eh_region *region = cfun->eh->region_array[i]; - if (region && region->label == label) - { - /* 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) - { - remove_exception_handler_label (region->label); - region->label = NULL_RTX; - } - else - remove_eh_handler (region); - break; - } + htab_clear_slot (exception_handler_label_map, (void **) slot); + region->label = NULL_RTX; } + else + remove_eh_handler (region); +} + +/* Invokes CALLBACK for every exception handler label. Only used by old + loop hackery; should not be used by new code. */ + +void +for_each_eh_label (callback) + void (*callback) PARAMS ((rtx)); +{ + htab_traverse (exception_handler_label_map, for_each_eh_label_1, + (void *)callback); } +static int +for_each_eh_label_1 (pentry, data) + PTR *pentry; + PTR data; +{ + struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry; + void (*callback) PARAMS ((rtx)) = (void (*) PARAMS ((rtx))) data; + + (*callback) (entry->label); + return 1; +} /* This section describes CFG exception edges for flow. */ diff --git a/gcc/except.h b/gcc/except.h index 200210f..ce91051 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -1,5 +1,5 @@ /* Exception Handling interface routines. - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Mike Stump . @@ -83,8 +83,9 @@ extern void expand_eh_region_end_throw PARAMS ((tree)); destroying an object twice. */ extern void expand_eh_region_end_fixup PARAMS ((tree)); -/* A list of labels used for exception handlers. */ -extern rtx exception_handler_labels; +/* Invokes CALLBACK for every exception handler label. Only used by old + loop hackery; should not be used by new code. */ +extern void for_each_eh_label PARAMS ((void (*) (rtx))); /* Determine if the given INSN can throw an exception. */ extern bool can_throw_internal PARAMS ((rtx)); diff --git a/gcc/jump.c b/gcc/jump.c index a04a4f5..f32b831 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -91,13 +91,6 @@ rebuild_jump_labels (f) for (insn = forced_labels; insn; insn = XEXP (insn, 1)) if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL) LABEL_NUSES (XEXP (insn, 0))++; - - /* Keep track of labels used for marking handlers for exception - regions; they cannot usually be deleted. */ - - for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1)) - if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL) - LABEL_NUSES (XEXP (insn, 0))++; } /* Some old code expects exactly one BARRIER as the NEXT_INSN of a diff --git a/gcc/loop.c b/gcc/loop.c index b51b2a8..53b9caa 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -235,6 +235,7 @@ FILE *loop_dump_stream; /* Forward declarations. */ +static void invalidate_loops_containing_label PARAMS ((rtx)); static void find_and_verify_loops PARAMS ((rtx, struct loops *)); static void mark_loop_jump PARAMS ((rtx, struct loop *)); static void prescan_loop PARAMS ((struct loop *)); @@ -2609,6 +2610,17 @@ prescan_loop (loop) } } +/* Invalidate all loops containing LABEL. */ + +static void +invalidate_loops_containing_label (label) + rtx label; +{ + struct loop *loop; + for (loop = uid_loop[INSN_UID (label)]; loop; loop = loop->outer) + loop->invalid = 1; +} + /* Scan the function looking for loops. Record the start and end of each loop. Also mark as invalid loops any loops that contain a setjmp or are branched to from outside the loop. */ @@ -2695,23 +2707,12 @@ find_and_verify_loops (f, loops) /* Any loop containing a label used in an initializer must be invalidated, because it can be jumped into from anywhere. */ - for (label = forced_labels; label; label = XEXP (label, 1)) - { - for (loop = uid_loop[INSN_UID (XEXP (label, 0))]; - loop; loop = loop->outer) - loop->invalid = 1; - } + invalidate_loops_containing_label (XEXP (label, 0)); /* Any loop containing a label used for an exception handler must be invalidated, because it can be jumped into from anywhere. */ - - for (label = exception_handler_labels; label; label = XEXP (label, 1)) - { - for (loop = uid_loop[INSN_UID (XEXP (label, 0))]; - loop; loop = loop->outer) - loop->invalid = 1; - } + for_each_eh_label (invalidate_loops_containing_label); /* Now scan all insn's in the function. If any JUMP_INSN branches into a loop that it is not contained within, that loop is marked invalid. @@ -2735,11 +2736,7 @@ find_and_verify_loops (f, loops) { rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX); if (note) - { - for (loop = uid_loop[INSN_UID (XEXP (note, 0))]; - loop; loop = loop->outer) - loop->invalid = 1; - } + invalidate_loops_containing_label (XEXP (note, 0)); } if (GET_CODE (insn) != JUMP_INSN) diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 6ec2668..ab65e2c 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -339,7 +339,7 @@ is_cfg_nonregular () /* If we have exception handlers, then we consider the cfg not well structured. ?!? We should be able to handle this now that flow.c computes an accurate cfg for EH. */ - if (exception_handler_labels) + if (current_function_has_exception_handlers ()) return 1; /* If we have non-jumping insns which refer to labels, then we consider -- 2.7.4