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]

Fix for GCSE and abnormal edges


Hi,

attached is a patch which is supposed to fix the problem with GCSE and
abnormal edges. It's using Jeff's idea to make all trapping expressions
dead on blocks which are destinations of an abnormal edge.

It survives boostrap. and produces no regressions on i386-linux and Brad's
alpha-something. Brad says, now his tests which were exhibiting the
problem are working.

To be sure even further we could also abort in pre_edge_insert(), when
it's trying to write on an abnormal edge.


Ciao,
Michael.
2000-12-06  Michael Matz  <matzmich@cs.tu-berlin.de>

	* gcse.c (compute_pre_data): New locals abnormal_dests, trapping_expr.
	Use them to kill trapping expressions in destination blocks of
	abnormal edges.

Index: gcse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcse.c,v
retrieving revision 1.111
diff -u -r1.111 gcse.c
--- gcse.c	2000/11/21 21:00:20	1.111
+++ gcse.c	2000/12/06 09:58:04
@@ -4158,10 +4158,45 @@
 compute_pre_data ()
 {
   int i;
+  unsigned int ui;
+  /* Bit I is set, if basic block I is the destination of any abnormal
+     edge.  */
+  sbitmap abnormal_dests;
+  /* Bit I is set, if expr with bitmap-index I might trap.  */
+  sbitmap trapping_expr;
+  struct expr *expr;
+  int any_abnormal = 0;
 
   compute_local_properties (transp, comp, antloc, 0);
   sbitmap_vector_zero (ae_kill, n_basic_blocks);
 
+  abnormal_dests = sbitmap_alloc (n_basic_blocks);
+  trapping_expr = sbitmap_alloc (n_exprs);
+
+  /* Calculate which blocks are destinations of abnormal edges.  */
+  sbitmap_zero (abnormal_dests);
+  for (i = 0; i < n_basic_blocks; i++)
+    {
+      edge e;
+      basic_block b = BASIC_BLOCK (i);
+      for (e = b->pred; e; e = e->pred_next)
+        /*if ( (e->flags & (EDGE_ABNORMAL | EDGE_CRITICAL))
+	    == (EDGE_ABNORMAL | EDGE_CRITICAL))*/
+        if ( (e->flags & EDGE_ABNORMAL) == EDGE_ABNORMAL)
+	  {
+	    any_abnormal = 1;
+	    SET_BIT (abnormal_dests, i);
+	    break;
+	  }
+    }
+
+  /* Collect expression which might trap.  */
+  sbitmap_zero (trapping_expr);
+  for (ui = 0; ui < expr_hash_table_size; ui++)
+    for (expr = expr_hash_table[ui]; expr != NULL; expr = expr->next_same_hash)
+      if (may_trap_p (expr->expr))
+        SET_BIT (trapping_expr, expr->bitmap_index);
+
   /* Compute ae_kill for each basic block using:
 
      ~(TRANSP | COMP)
@@ -4170,6 +4205,15 @@
 
   for (i = 0; i < n_basic_blocks; i++)
     {
+      /* If the current block is the dest of an abnormal edge,
+         all trapable expression are dead here (because later we can't
+	 split that edge), so it's neither anticipatable nor transparent.
+	 This is fairly conservative.  */
+      if (any_abnormal && TEST_BIT (abnormal_dests, i))
+        {
+          sbitmap_difference (antloc[i], antloc[i], trapping_expr);
+	  sbitmap_difference (transp[i], transp[i], trapping_expr);
+	}
       sbitmap_a_or_b (ae_kill[i], transp[i], comp[i]);
       sbitmap_not (ae_kill[i], ae_kill[i]);
     }
@@ -4180,6 +4224,9 @@
   antloc = NULL;
   free (ae_kill);
   ae_kill = NULL; 
+
+  free (abnormal_dests);
+  free (trapping_expr);
 }
 
 /* PRE utilities */

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