Commit 6a58eee9 by Richard Henderson Committed by Richard Henderson

basic-block.h (flow_delete_block_noexpunge): Declare.

	* 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.

From-SVN: r52100
parent 4fc4e478
2002-04-09 Richard Henderson <rth@redhat.com> 2002-04-09 Richard Henderson <rth@redhat.com>
* 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 <rth@redhat.com>
* sbitmap.c (sbitmap_union_of_diff, sbitmap_a_and_b, sbitmap_a_xor_b, * 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): sbitmap_a_or_b, sbitmap_a_or_b_and_c, sbitmap_a_and_b_or_c):
Do not return changed status. Do not return changed status.
......
/* Define control and data flow tables, and regsets. /* 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. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -316,6 +316,7 @@ extern void redirect_edge_pred PARAMS ((edge, basic_block)); ...@@ -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_structure PARAMS ((int, rtx, rtx, rtx));
extern basic_block create_basic_block PARAMS ((int, 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 PARAMS ((basic_block));
extern int flow_delete_block_noexpunge PARAMS ((basic_block));
extern void clear_bb_flags PARAMS ((void)); extern void clear_bb_flags PARAMS ((void));
extern void merge_blocks_nomove PARAMS ((basic_block, basic_block)); extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
extern void tidy_fallthru_edge PARAMS ((edge, basic_block, extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
...@@ -637,6 +638,7 @@ extern void debug_regset PARAMS ((regset)); ...@@ -637,6 +638,7 @@ extern void debug_regset PARAMS ((regset));
extern void allocate_reg_life_data PARAMS ((void)); extern void allocate_reg_life_data PARAMS ((void));
extern void allocate_bb_life_data PARAMS ((void)); extern void allocate_bb_life_data PARAMS ((void));
extern void expunge_block PARAMS ((basic_block)); extern void expunge_block PARAMS ((basic_block));
extern void expunge_block_nocompact PARAMS ((basic_block));
extern basic_block alloc_block PARAMS ((void)); extern basic_block alloc_block PARAMS ((void));
extern void find_unreachable_blocks PARAMS ((void)); extern void find_unreachable_blocks PARAMS ((void));
extern int delete_noop_moves PARAMS ((rtx)); extern int delete_noop_moves PARAMS ((rtx));
......
...@@ -223,6 +223,17 @@ alloc_block () ...@@ -223,6 +223,17 @@ alloc_block ()
/* Remove block B from the basic block array and compact behind it. */ /* Remove block B from the basic block array and compact behind it. */
void 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) expunge_block (b)
basic_block b; basic_block b;
{ {
...@@ -235,13 +246,10 @@ expunge_block (b) ...@@ -235,13 +246,10 @@ expunge_block (b)
x->index = i; 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--; n_basic_blocks--;
b->succ = (edge) first_deleted_block; basic_block_info->num_elements--;
first_deleted_block = (basic_block) b;
expunge_block_nocompact (b);
} }
/* Create an edge connecting SRC and DST with FLAGS optionally using /* Create an edge connecting SRC and DST with FLAGS optionally using
......
/* Control flow optimization code for GNU compiler. /* Control flow optimization code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 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. This file is part of GCC.
...@@ -1751,22 +1751,33 @@ try_optimize_cfg (mode) ...@@ -1751,22 +1751,33 @@ try_optimize_cfg (mode)
static bool static bool
delete_unreachable_blocks () delete_unreachable_blocks ()
{ {
int i; int i, j;
bool changed = false; bool changed = false;
find_unreachable_blocks (); find_unreachable_blocks ();
/* Delete all unreachable basic blocks. Count down so that we /* Delete all unreachable basic blocks. Do compaction concurrently,
don't interfere with the block renumbering that happens in as otherwise we can wind up with O(N^2) behaviour here when we
flow_delete_block. */ 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); basic_block b = BASIC_BLOCK (i);
if (!(b->flags & BB_REACHABLE)) 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) if (changed)
tidy_fallthru_edges (); tidy_fallthru_edges ();
......
/* Control flow graph manipulation code for GNU compiler. /* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 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. This file is part of GCC.
...@@ -102,8 +102,7 @@ can_delete_label_p (label) ...@@ -102,8 +102,7 @@ can_delete_label_p (label)
/* User declared labels must be preserved. */ /* User declared labels must be preserved. */
&& LABEL_NAME (label) == 0 && LABEL_NAME (label) == 0
&& !in_expr_list_p (forced_labels, label) && !in_expr_list_p (forced_labels, label)
&& !in_expr_list_p (label_value_list, label) && !in_expr_list_p (label_value_list, label));
&& !in_expr_list_p (exception_handler_labels, label));
} }
/* Delete INSN by patching it out. Return the next insn. */ /* Delete INSN by patching it out. Return the next insn. */
...@@ -363,7 +362,7 @@ create_basic_block (index, head, end) ...@@ -363,7 +362,7 @@ create_basic_block (index, head, end)
to post-process the stream to remove empty blocks, loops, ranges, etc. */ to post-process the stream to remove empty blocks, loops, ranges, etc. */
int int
flow_delete_block (b) flow_delete_block_noexpunge (b)
basic_block b; basic_block b;
{ {
int deleted_handler = 0; int deleted_handler = 0;
...@@ -412,6 +411,15 @@ flow_delete_block (b) ...@@ -412,6 +411,15 @@ flow_delete_block (b)
b->pred = NULL; b->pred = NULL;
b->succ = 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. */ /* Remove the basic block from the array, and compact behind it. */
expunge_block (b); expunge_block (b);
......
/* Exception Handling interface routines. /* 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. Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>. Contributed by Mike Stump <mrs@cygnus.com>.
...@@ -83,8 +83,9 @@ extern void expand_eh_region_end_throw PARAMS ((tree)); ...@@ -83,8 +83,9 @@ extern void expand_eh_region_end_throw PARAMS ((tree));
destroying an object twice. */ destroying an object twice. */
extern void expand_eh_region_end_fixup PARAMS ((tree)); extern void expand_eh_region_end_fixup PARAMS ((tree));
/* A list of labels used for exception handlers. */ /* Invokes CALLBACK for every exception handler label. Only used by old
extern rtx exception_handler_labels; 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. */ /* Determine if the given INSN can throw an exception. */
extern bool can_throw_internal PARAMS ((rtx)); extern bool can_throw_internal PARAMS ((rtx));
......
...@@ -91,13 +91,6 @@ rebuild_jump_labels (f) ...@@ -91,13 +91,6 @@ rebuild_jump_labels (f)
for (insn = forced_labels; insn; insn = XEXP (insn, 1)) for (insn = forced_labels; insn; insn = XEXP (insn, 1))
if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL) if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL)
LABEL_NUSES (XEXP (insn, 0))++; 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 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
......
...@@ -235,6 +235,7 @@ FILE *loop_dump_stream; ...@@ -235,6 +235,7 @@ FILE *loop_dump_stream;
/* Forward declarations. */ /* Forward declarations. */
static void invalidate_loops_containing_label PARAMS ((rtx));
static void find_and_verify_loops PARAMS ((rtx, struct loops *)); static void find_and_verify_loops PARAMS ((rtx, struct loops *));
static void mark_loop_jump PARAMS ((rtx, struct loop *)); static void mark_loop_jump PARAMS ((rtx, struct loop *));
static void prescan_loop PARAMS ((struct loop *)); static void prescan_loop PARAMS ((struct loop *));
...@@ -2609,6 +2610,17 @@ prescan_loop (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. /* 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 Also mark as invalid loops any loops that contain a setjmp or are branched
to from outside the loop. */ to from outside the loop. */
...@@ -2695,23 +2707,12 @@ find_and_verify_loops (f, loops) ...@@ -2695,23 +2707,12 @@ find_and_verify_loops (f, loops)
/* Any loop containing a label used in an initializer must be invalidated, /* Any loop containing a label used in an initializer must be invalidated,
because it can be jumped into from anywhere. */ because it can be jumped into from anywhere. */
for (label = forced_labels; label; label = XEXP (label, 1)) for (label = forced_labels; label; label = XEXP (label, 1))
{ invalidate_loops_containing_label (XEXP (label, 0));
for (loop = uid_loop[INSN_UID (XEXP (label, 0))];
loop; loop = loop->outer)
loop->invalid = 1;
}
/* Any loop containing a label used for an exception handler must be /* Any loop containing a label used for an exception handler must be
invalidated, because it can be jumped into from anywhere. */ invalidated, because it can be jumped into from anywhere. */
for_each_eh_label (invalidate_loops_containing_label);
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;
}
/* Now scan all insn's in the function. If any JUMP_INSN branches into a /* 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. loop that it is not contained within, that loop is marked invalid.
...@@ -2735,11 +2736,7 @@ find_and_verify_loops (f, loops) ...@@ -2735,11 +2736,7 @@ find_and_verify_loops (f, loops)
{ {
rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX); rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
if (note) if (note)
{ invalidate_loops_containing_label (XEXP (note, 0));
for (loop = uid_loop[INSN_UID (XEXP (note, 0))];
loop; loop = loop->outer)
loop->invalid = 1;
}
} }
if (GET_CODE (insn) != JUMP_INSN) if (GET_CODE (insn) != JUMP_INSN)
......
...@@ -339,7 +339,7 @@ is_cfg_nonregular () ...@@ -339,7 +339,7 @@ is_cfg_nonregular ()
/* If we have exception handlers, then we consider the cfg not well /* If we have exception handlers, then we consider the cfg not well
structured. ?!? We should be able to handle this now that flow.c structured. ?!? We should be able to handle this now that flow.c
computes an accurate cfg for EH. */ computes an accurate cfg for EH. */
if (exception_handler_labels) if (current_function_has_exception_handlers ())
return 1; return 1;
/* If we have non-jumping insns which refer to labels, then we consider /* If we have non-jumping insns which refer to labels, then we consider
......
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