This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] for "Re: Compilation at -O3 Still Broken"


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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]