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] Fix fallout of CFG scanning patch


Hi,

This is another fallout of Zdenek's CFG scanning patch, this time for the Ada 
compiler on the attached testcase:

eric@linux:~/build/gcc/native32> gcc/xgcc -Bgcc -S -O p.adb -I gcc/ada/rts
p.adb:11:07: warning: variable "Tmp_Res" is read but never assigned
+===========================GNAT BUG DETECTED==============================+
| 4.3.0 20070501 (experimental) (i586-suse-linux-gnu) GCC error:           |
| in iterate_fix_dominators, at dominance.c:1044                           |
| Error detected at p.adb:26:1                        

The ICE occurs at the end of the DOM pass, when EH edges are purged:

  /* Removal of statements may make some EH edges dead.  Purge
     such edges from the CFG as needed.  */
  if (!bitmap_empty_p (need_eh_cleanup))
    {
      cfg_altered |= tree_purge_all_dead_eh_edges (need_eh_cleanup);
      bitmap_zero (need_eh_cleanup);
    }

  if (cfg_altered)
    free_dominance_info (CDI_DOMINATORS);


The pass has already modified the CFG (threaded a jump) so my understanding is 
that the dominance info are outdated.  Before Zdenek's patch, purging EH edges
would automatically invalidate the info; after Zdenek's patch, the compiler 
will try to incrementally (and locally) update them.  The problem is that it 
now starts from wrong info so it cannot compute a consistent result.

Hence the proposed patch, which moves up the calls to free_dominance_info.
It also occured to me that cfg_altered is never reset throughout the code!

Bootstrapped/regtested on i586-suse-linux, OK for mainline?


2007-05-06  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-ssa-dom.c (tree_ssa_dominator_optimize): Reset cfg_altered.
	Free dominance info before purging EH edges as well as after.
	(eliminate_degenerate_phis): Likewise.
	(propagate_rhs_into_lhs): Set cfg_altered to true instead of 1.
	
	
2007-05-06  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/opt1.ad[sb]: New testcase.


-- 
Eric Botcazou
package P is

   type Dimention_Length is array (1 .. 16) of Natural;

   type Dimension_Indexes is array (Positive range <>) of Positive;

   function De_Linear_Index
     (Index       : Natural;
      D           : Natural;
      Ind_Lengths : Dimention_Length)
      return Dimension_Indexes;

end P;
-- { dg-do compile }
-- { dg-options "-O -gnatws" }

package body P is

   function De_Linear_Index
     (Index       : Natural;
      D           : Natural;
      Ind_Lengths : Dimention_Length)
      return        Dimension_Indexes
   is
      Len     : Natural := 1;
      Tmp_Ind : Natural := Index;
      Tmp_Res : Natural;
      Result  : Dimension_Indexes (1 .. D);
   begin
      for J in 1 .. D loop
         Len := Len * Ind_Lengths (J);
      end loop;

      for J in Result'Range loop
         Result (J) := Tmp_Res;
         Tmp_Ind := Tmp_Ind - Len * (Result (J) - 1);
      end loop;

      return Result;
   end;

end P;
Index: tree-ssa-dom.c
===================================================================
--- tree-ssa-dom.c	(revision 124378)
+++ tree-ssa-dom.c	(working copy)
@@ -275,6 +275,7 @@ tree_ssa_dominator_optimize (void)
   init_walk_dominator_tree (&walk_data);
 
   calculate_dominance_info (CDI_DOMINATORS);
+  cfg_altered = false;
 
   /* We need to know which edges exit loops so that we can
      aggressively thread through loop headers to an exit
@@ -320,17 +321,18 @@ tree_ssa_dominator_optimize (void)
   /* Thread jumps, creating duplicate blocks as needed.  */
   cfg_altered |= thread_through_all_blocks ();
 
+  if (cfg_altered)
+    free_dominance_info (CDI_DOMINATORS);
+
   /* Removal of statements may make some EH edges dead.  Purge
      such edges from the CFG as needed.  */
   if (!bitmap_empty_p (need_eh_cleanup))
     {
-      cfg_altered |= tree_purge_all_dead_eh_edges (need_eh_cleanup);
+      if (tree_purge_all_dead_eh_edges (need_eh_cleanup))
+	free_dominance_info (CDI_DOMINATORS);
       bitmap_zero (need_eh_cleanup);
     }
 
-  if (cfg_altered)
-    free_dominance_info (CDI_DOMINATORS);
-
   /* Finally, remove everything except invariants in SSA_NAME_VALUE.
 
      Long term we will be able to let everything in SSA_NAME_VALUE
@@ -2336,7 +2338,7 @@ propagate_rhs_into_lhs (tree stmt, tree 
 
 			  te->count += e->count;
 			  remove_edge (e);
-			  cfg_altered = 1;
+			  cfg_altered = true;
 			}
 		      else
 			ei_next (&ei);
@@ -2485,6 +2487,9 @@ eliminate_degenerate_phis (void)
   interesting_names = BITMAP_ALLOC (NULL);
   interesting_names1 = BITMAP_ALLOC (NULL);
 
+  calculate_dominance_info (CDI_DOMINATORS);
+  cfg_altered = false;
+
   /* First phase.  Eliminate degenerate PHIs via a dominator
      walk of the CFG.
 
@@ -2493,7 +2498,6 @@ eliminate_degenerate_phis (void)
      phase in dominator order.  Presumably this is because walking
      in dominator order leaves fewer PHIs for later examination
      by the worklist phase.  */
-  calculate_dominance_info (CDI_DOMINATORS);
   eliminate_degenerate_phis_1 (ENTRY_BLOCK_PTR, interesting_names);
 
   /* Second phase.  Eliminate second order degenerate PHIs as well
@@ -2522,18 +2526,20 @@ eliminate_degenerate_phis (void)
 	}
     }
 
+  if (cfg_altered)
+    free_dominance_info (CDI_DOMINATORS);
+
   /* Propagation of const and copies may make some EH edges dead.  Purge
      such edges from the CFG as needed.  */
   if (!bitmap_empty_p (need_eh_cleanup))
     {
-      cfg_altered |= tree_purge_all_dead_eh_edges (need_eh_cleanup);
+      if (tree_purge_all_dead_eh_edges (need_eh_cleanup))
+	free_dominance_info (CDI_DOMINATORS);
       BITMAP_FREE (need_eh_cleanup);
     }
 
   BITMAP_FREE (interesting_names);
   BITMAP_FREE (interesting_names1);
-  if (cfg_altered)
-    free_dominance_info (CDI_DOMINATORS);
   return 0;
 }
 

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