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 pr30841 part 2, df bug (mainline only)


The bug here is that the bitmap_size in df->def_info and df->use_info tracks the number of valid defs and uses in the current function.

However, this is incorrect when DF_DEFS_SIZE and DF_USES_SIZE is used to walk on the array of references: when fwprop incrementally updates the df information, it removes some references and tacks the new ones at the end of the array. So, DF_DEFS_SIZE and DF_USES_SIZE must *not* be decreased when refs are deleted.

This patch arranges for this to happen, by changing the meaning of the refs_organized field: now, if it is non-zero, it is the number of references stored in the array, which is affected by creating new refs and not by deleting them. DF_DEFS_SIZE and DF_USES_SIZE will then use the new field.

All users of df need to reorganize the refs they walk: in the case of loop-iv and loop-invariant, this happens through the reaching definitions problem (df_rd_local_compute); other passes do this explicitly. Hence, the new definition of DF_DEFS_SIZE and DF_USES_SIZE works for all users.

Bootstrapped/regtested i686-pc-linux-gnu, ok for mainline? This is already fixed on dataflow-branch.

Paolo
2007-02-22  Paolo Bonzini  <bonzini@gnu.org>

	* df-problems.c (df_ru_local_compute, df_rd_local_compute, df_chain_alloc):
	Call df_reorganize_refs unconditionally.
	* df-scan.c (df_rescan_blocks, df_reorganize_refs): Change refs_organized to
	refs_organized_size.
	(df_ref_create_structure): Use refs_organized_size instead of bitmap_size
	if refs had been organized, and keep refs_organized_size up-to-date.
	* df.h (struct df_ref_info): Change refs_organized to refs_organized_size.
	(DF_DEFS_SIZE, DF_USES_SIZE): Use refs_organized_size instead of bitmap_size.

Index: df-problems.c
===================================================================
--- df-problems.c	(revision 121883)
+++ df-problems.c	(working copy)
@@ -586,9 +586,7 @@ df_ru_local_compute (struct dataflow *df
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
   df_set_seen ();
-
-  if (!df->use_info.refs_organized)
-    df_reorganize_refs (&df->use_info);
+  df_reorganize_refs (&df->use_info);
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
@@ -1109,9 +1107,7 @@ df_rd_local_compute (struct dataflow *df
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
   df_set_seen ();
-
-  if (!df->def_info.refs_organized)
-    df_reorganize_refs (&df->def_info);
+  df_reorganize_refs (&df->def_info);
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
@@ -2771,8 +2767,7 @@ df_chain_alloc (struct dataflow *dflow, 
 
   if (dflow->flags & DF_DU_CHAIN)
     {
-      if (!df->def_info.refs_organized)
-	df_reorganize_refs (&df->def_info);
+      df_reorganize_refs (&df->def_info);
       
       /* Clear out the pointers from the refs.  */
       for (i = 0; i < DF_DEFS_SIZE (df); i++)
@@ -2784,8 +2779,7 @@ df_chain_alloc (struct dataflow *dflow, 
   
   if (dflow->flags & DF_UD_CHAIN)
     {
-      if (!df->use_info.refs_organized)
-	df_reorganize_refs (&df->use_info);
+      df_reorganize_refs (&df->use_info);
       for (i = 0; i < DF_USES_SIZE (df); i++)
 	{
 	  struct df_ref *ref = df->use_info.refs[i];
Index: df-scan.c
===================================================================
--- df-scan.c	(revision 121883)
+++ df-scan.c	(working copy)
@@ -435,8 +435,8 @@ df_rescan_blocks (struct df *df, bitmap 
   struct dataflow *dflow = df->problems_by_index[DF_SCAN];
   basic_block bb;
 
-  df->def_info.refs_organized = false;
-  df->use_info.refs_organized = false;
+  df->def_info.refs_organized_size = 0;
+  df->use_info.refs_organized_size = 0;
 
   if (blocks)
     {
@@ -882,7 +882,7 @@ df_reorganize_refs (struct df_ref_info *
   unsigned int offset = 0;
   unsigned int size = 0;
 
-  if (ref_info->refs_organized)
+  if (ref_info->refs_organized_size)
     return;
 
   if (ref_info->refs_size < ref_info->bitmap_size)
@@ -915,7 +915,7 @@ df_reorganize_refs (struct df_ref_info *
      reset it now that we have squished out all of the empty
      slots.  */
   ref_info->bitmap_size = size;
-  ref_info->refs_organized = true;
+  ref_info->refs_organized_size = size;
   ref_info->add_refs_inline = true;
 }
 
@@ -958,21 +958,24 @@ df_ref_create_structure (struct dataflow
       {
 	struct df_reg_info *reg_info = DF_REG_DEF_GET (df, regno);
 	reg_info->n_refs++;
+	int size = df->def_info.refs_organized_size
+		   ? df->def_info.refs_organized_size
+		   : df->def_info.bitmap_size;
 	
 	/* Add the ref to the reg_def chain.  */
 	df_reg_chain_create (reg_info, this_ref);
-	DF_REF_ID (this_ref) = df->def_info.bitmap_size;
+	DF_REF_ID (this_ref) = size;
 	if (df->def_info.add_refs_inline)
 	  {
-	    if (DF_DEFS_SIZE (df) >= df->def_info.refs_size)
+	    if (size >= df->def_info.refs_size)
 	      {
-		int new_size = df->def_info.bitmap_size 
-		  + df->def_info.bitmap_size / 4;
+		int new_size = size + size / 4;
 		df_grow_ref_info (&df->def_info, new_size);
 	      }
 	    /* Add the ref to the big array of defs.  */
-	    DF_DEFS_SET (df, df->def_info.bitmap_size, this_ref);
-	    df->def_info.refs_organized = false;
+	    DF_DEFS_SET (df, size, this_ref);
+	    if (df->def_info.refs_organized_size)
+	      df->def_info.refs_organized_size++;
 	  }
 	
 	df->def_info.bitmap_size++;
@@ -998,21 +1001,24 @@ df_ref_create_structure (struct dataflow
       {
 	struct df_reg_info *reg_info = DF_REG_USE_GET (df, regno);
 	reg_info->n_refs++;
+	int size = df->use_info.refs_organized_size
+		   ? df->use_info.refs_organized_size
+		   : df->use_info.bitmap_size;
 	
 	/* Add the ref to the reg_use chain.  */
 	df_reg_chain_create (reg_info, this_ref);
-	DF_REF_ID (this_ref) = df->use_info.bitmap_size;
+	DF_REF_ID (this_ref) = size;
 	if (df->use_info.add_refs_inline)
 	  {
-	    if (DF_USES_SIZE (df) >= df->use_info.refs_size)
+	    if (size >= df->use_info.refs_size)
 	      {
-		int new_size = df->use_info.bitmap_size 
-		  + df->use_info.bitmap_size / 4;
+		int new_size = size + size / 4;
 		df_grow_ref_info (&df->use_info, new_size);
 	      }
 	    /* Add the ref to the big array of defs.  */
-	    DF_USES_SET (df, df->use_info.bitmap_size, this_ref);
-	    df->use_info.refs_organized = false;
+	    DF_USES_SET (df, size, this_ref);
+	    if (df->def_info.refs_organized_size)
+	      df->def_info.refs_organized_size++;
 	  }
 	
 	df->use_info.bitmap_size++;
Index: df.h
===================================================================
--- df.h	(revision 121883)
+++ df.h	(working copy)
@@ -323,9 +323,9 @@ struct df_ref_info
   unsigned int refs_size;       /* Size of currently allocated refs table.  */
   unsigned int bitmap_size;	/* Number of refs seen.  */
 
-  /* True if refs table is organized so that every reference for a
+  /* >0 if refs table is organized so that every reference for a
      pseudo is contiguous.  */
-  bool refs_organized;
+  unsigned int refs_organized_size;
   /* True if the next refs should be added immediately or false to
      defer to later to reorganize the table.  */
   bool add_refs_inline; 
@@ -433,10 +433,10 @@ struct df
                                || DF_REF_REG_MEM_LOAD_P (REF))
 
 /* Macros to get the refs out of def_info or use_info refs table.  */
-#define DF_DEFS_SIZE(DF) ((DF)->def_info.bitmap_size)
+#define DF_DEFS_SIZE(DF) ((DF)->def_info.refs_organized_size)
 #define DF_DEFS_GET(DF,ID) ((DF)->def_info.refs[(ID)])
 #define DF_DEFS_SET(DF,ID,VAL) ((DF)->def_info.refs[(ID)]=(VAL))
-#define DF_USES_SIZE(DF) ((DF)->use_info.bitmap_size)
+#define DF_USES_SIZE(DF) ((DF)->use_info.refs_organized_size)
 #define DF_USES_GET(DF,ID) ((DF)->use_info.refs[(ID)])
 #define DF_USES_SET(DF,ID,VAL) ((DF)->use_info.refs[(ID)]=(VAL))
 

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