This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] for "Re: Compilation at -O3 Still Broken"
- From: Steven Bosscher <stevenb at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Ranjit Mathew <rmathew at gmail dot com>, rth at redhat dot com
- Date: Tue, 1 Jun 2004 01:44:37 +0200
- Subject: [PATCH] for "Re: Compilation at -O3 Still Broken"
- Organization: SUSE Labs
- References: <c9ekr8$bkl$1@sea.gmane.org> <200405312329.34253.stevenb@suse.de> <200405312336.32244.stevenb@suse.de>
Hi,
This fixes libjava's PR4766.java test case.
We were removing labels that were still referenced
from exception region structs. rth, are there other
places you can think if that I've missed?
Bootstrapped and tested on x86_64-unknown-linux-gnu.
OK for mainline?
Gr.
Steven
* except.c (for_each_eh_region): New function.
* except.h (for_each_eh_region): Add a prototype for it.
* tree-cfg.c (update_eh_labels): New function, callback for
for_each_eh_region.
(label_for_bb): Make global static, unfortunately.
(cleanup_dead_labels): Also update label references for
exception regions.
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.271
diff -c -3 -p -r1.271 except.c
*** except.c 30 May 2004 07:12:48 -0000 1.271
--- except.c 31 May 2004 21:53:42 -0000
*************** for_each_eh_label_1 (void **pentry, void
*** 2766,2771 ****
--- 2766,2784 ----
(*callback) (entry->label);
return 1;
}
+
+ /* Invoke CALLBACK for every exception region in the current function. */
+
+ void
+ for_each_eh_region (void (*callback) (struct eh_region *))
+ {
+ int i, n = cfun->eh->last_region_number;
+ for (i = 1; i <= n; ++i)
+ {
+ struct eh_region *region = cfun->eh->region_array[i];
+ (*callback) (region);
+ }
+ }
/* This section describes CFG exception edges for flow. */
Index: except.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.h,v
retrieving revision 1.75
diff -c -3 -p -r1.75 except.h
*** except.h 13 May 2004 06:39:38 -0000 1.75
--- except.h 31 May 2004 21:53:42 -0000
*************** extern void note_current_region_may_cont
*** 90,95 ****
--- 90,98 ----
loop hackery; should not be used by new code. */
extern void for_each_eh_label (void (*) (rtx));
+ /* Invokes CALLBACK for every exception region in the current function. */
+ extern void for_each_eh_region (void (*) (struct eh_region *));
+
/* Determine if the given INSN can throw an exception. */
extern bool can_throw_internal_1 (int);
extern bool can_throw_internal (rtx);
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.6
diff -c -3 -p -r2.6 tree-cfg.c
*** tree-cfg.c 30 May 2004 18:32:28 -0000 2.6
--- tree-cfg.c 31 May 2004 21:53:42 -0000
*************** cleanup_tree_cfg (void)
*** 762,774 ****
}
! /* Cleanup useless labels from the flow graph. */
static void
cleanup_dead_labels (void)
{
basic_block bb;
! tree *label_for_bb = xcalloc (last_basic_block, sizeof (tree));
/* Find a suitable label for each block. We use the first user-defined
label is there is one, or otherwise just the first label we see. */
--- 762,796 ----
}
! /* Cleanup useless labels in basic blocks. This is something we wish
! to do early because it allows us to group case labels before creating
! the edges for the CFG, and it speeds up block statement iterators in
! all passes later on.
! We only run this pass once, running it more than once is probably not
! profitable. */
!
! /* A map from basic block index to the leading label of that block. */
! static tree *label_for_bb;
!
! /* Callback for for_each_eh_region. Helper for cleanup_dead_labels. */
! static void
! update_eh_label (struct eh_region *region)
! {
! tree old_label = get_eh_region_tree_label (region);
! tree new_label = label_for_bb[label_to_block (old_label)->index];
! set_eh_region_tree_label (region, new_label);
! }
!
! /* Cleanup redundant labels. This is a three-steo process:
! 1) Find the leading label for each block.
! 2) Redirect all references to labels to the leading labels.
! 3) Cleanup all useless labels. */
static void
cleanup_dead_labels (void)
{
basic_block bb;
! label_for_bb = xcalloc (last_basic_block, sizeof (tree));
/* Find a suitable label for each block. We use the first user-defined
label is there is one, or otherwise just the first label we see. */
*************** cleanup_dead_labels (void)
*** 805,811 ****
}
}
! /* Now redirect all jumps/branches to the selected label for each block. */
FOR_EACH_BB (bb)
{
tree stmt = last_stmt (bb);
--- 827,834 ----
}
}
! /* Now redirect all jumps/branches to the selected label.
! First do so for each block ending in a control statement. */
FOR_EACH_BB (bb)
{
tree stmt = last_stmt (bb);
*************** cleanup_dead_labels (void)
*** 864,869 ****
--- 887,894 ----
}
}
+ for_each_eh_region (update_eh_label);
+
/* Finally, purge dead labels. All user-defined labels and labels that
can be the target of non-local gotos are preserved. */
FOR_EACH_BB (bb)