This fixes the problems that became apparent from zdeneks patch.

Bootstrapped and regression tested against the version with zdenek's original code (since this directly tickled the failure and bootstrapped (and in the process of regression testing) against the current mainline. Both on i686-pc-linux-gnu.

Kenny


2005-01-20  Kenneth Zadeck <[EMAIL PROTECTED]>

   * df-scan.c (problem_SCAN): Added NULL reset function.
   (df_scan_reset_blocks): Added code to call reset block function
   (df_bb_refs_delete) Fixed comment.
   (df_insn_refs_delete): Made tolerant of deleting non existent info
   for dataflow problems that need to be reset.
   * df-core.c (df_set_blocks): Ditto.
   * df.h (struct df_problem): Added reset_fun.
   * df-problems.c (problem_RU, problem_RD, problem_LR, problem_UR,
   problem_UREC, problem_CHAIN, problem_RI): Initialized reset_fun field.
   (df_chain_insn_reset, df_chain_bb_reset, df_chain_reset): New
   functions to clear out all references to def-use or use-def chains.


Zdenek Dvorak wrote:
Hello,

The attached fixes *that*, but this just causes a crash deeper in trying to free some chains.
[...]
Sorry for the problems and thanks for looking into them.
Ken, please reread the email.  The issue is *not* fixed according to
Daniel, there's still another problem.  Could you look into it,
please?

I would like permission to revert zdenek's patch for a few days. There is nothing wrong with zdenek's patch, pe se, but it excercises a part of df that should work but does not.

I don't quite like this idea; as you yourself say, the problem is not in
that patch (in fact, mainline bootstraps and passes regtesting with it
without your patch); so I think that if we indeed want to go into
reverting patches, it should be the one causing the problem (and I have
a followup patch that I would like to be able to test).

Btw.: of course it may happen that some patch sometimes breaks
bootstrap, it happened to everyone of us.  But, with your patch, not
even libgcc builds.  This means that you did not even try to build gcc
before commiting your patch.  Please do that next time.  In fact,
running at least a partial bootstrap till gengtype is run helped me
avoid introducing bootstrap failures (caused by unexpected interaction
with patches commited since I tested the patch fully the last time)
several times, so it is a good idea even if you are quite sure that no
such problem may occur.

We could revert my storage patch, but the problem is much deeper than that. The storage patch only causes this problem to happen when bootstrapping. The problem will still be there and may cause random ices when running zdeneks code.

The problem is that when ever you delete any basic blocks, you need to get rid of the def use and use def chains that either start or end in the deleted block, furthermore, this has to be done before the instructions are deleted for those blocks. This will take me a day to get correct. Zdenek's patch is the only code that manipulates the blocks after use-def or def-use chains are built.

This analysis seems wrong to me -- the crash occurs when called from
estimate_probability, and we do not change CFG in branch prediction.

Zdenek

Index: df-scan.c
===================================================================
--- df-scan.c	(revision 110059)
+++ df-scan.c	(working copy)
@@ -304,6 +304,7 @@ static struct df_problem problem_SCAN =
   DF_SCAN,                    /* Problem id.  */
   DF_NONE,                    /* Direction.  */
   df_scan_alloc,              /* Allocate the problem specific data.  */
+  NULL,                       /* Reset global information.  */
   df_scan_free_bb_info,       /* Free basic block info.  */
   NULL,                       /* Local compute function.  */
   NULL,                       /* Init the solution specific data.  */
@@ -426,6 +427,8 @@ df_rescan_blocks (struct df *df, bitmap 
 
   if (blocks)
     {
+      int i;
+
       /* Need to assure that there are space in all of the tables.  */
       unsigned int insn_num = get_max_uid () + 1;
       insn_num += insn_num / 4;
@@ -443,6 +446,24 @@ df_rescan_blocks (struct df *df, bitmap 
       df->def_info.add_refs_inline = true;
       df->use_info.add_refs_inline = true;
 
+      for (i = df->num_problems_defined; i; i--)
+	{
+	  bitmap blocks_to_reset = NULL;
+	  if (*dflow->problem->reset_fun)
+	    {
+	      if (!blocks_to_reset)
+		{
+		  blocks_to_reset = BITMAP_ALLOC (NULL);
+		  bitmap_copy (blocks_to_reset, local_blocks_to_scan);
+		  if (df->blocks_to_scan)
+		    bitmap_ior_into (blocks_to_reset, df->blocks_to_scan);
+		}
+	      (*dflow->problem->reset_fun) (dflow, blocks_to_reset);
+	    }
+	  if (blocks_to_reset)
+	    BITMAP_FREE (blocks_to_reset);
+	}
+
       df_refs_delete (dflow, local_blocks_to_scan);
 
       /* This may be a mistake, but if an explicit blocks is passed in
@@ -727,11 +748,14 @@ df_insn_refs_delete (struct dataflow *df
 {
   struct df *df = dflow->df;
   unsigned int uid = INSN_UID (insn);
-  struct df_insn_info *insn_info = DF_INSN_UID_GET (df, uid);
+  struct df_insn_info *insn_info = NULL;
   struct df_ref *ref;
   struct df_scan_problem_data *problem_data =
     (struct df_scan_problem_data *) dflow->problem_data;
 
+  if (uid < df->insns_size)
+    insn_info = DF_INSN_UID_GET (df, uid);
+
   if (insn_info)
     {
       ref = insn_info->defs;
@@ -769,7 +793,7 @@ df_bb_refs_delete (struct dataflow *dflo
 	}
     }
   
-  /* Get rid of any artifical uses.  */
+  /* Get rid of any artifical uses or defs.  */
   if (bb_info)
     {
       def = bb_info->artificial_defs;
Index: df-core.c
===================================================================
--- df-core.c	(revision 110059)
+++ df-core.c	(working copy)
@@ -292,6 +292,8 @@ are write-only operations.  
 static struct df *ddf = NULL;
 struct df *shared_df = NULL;
 
+static void * df_get_bb_info (struct dataflow *, unsigned int);
+static void df_set_bb_info (struct dataflow *, unsigned int, void *);
 /*----------------------------------------------------------------------------
   Functions to create, destroy and manipulate an instance of df.
 ----------------------------------------------------------------------------*/
@@ -358,11 +360,14 @@ df_set_blocks (struct df *df, bitmap blo
 	{
 	  int p;
 	  bitmap diff = BITMAP_ALLOC (NULL);
+	  bitmap all = BITMAP_ALLOC (NULL);
 	  bitmap_and_compl (diff, df->blocks_to_analyze, blocks);
-	  for (p = 0; p < df->num_problems_defined; p++)
+	  for (p = df->num_problems_defined - 1; p >= 0 ;p--)
 	    {
 	      struct dataflow *dflow = df->problems_in_order[p];
-	      if (*dflow->problem->free_bb_fun)
+	      if (*dflow->problem->reset_fun)
+		(*dflow->problem->reset_fun) (dflow, df->blocks_to_analyze);
+	      else if (*dflow->problem->free_bb_fun)
 		{
 		  bitmap_iterator bi;
 		  unsigned int bb_index;
@@ -370,15 +375,50 @@ df_set_blocks (struct df *df, bitmap blo
 		  EXECUTE_IF_SET_IN_BITMAP (diff, 0, bb_index, bi)
 		    {
 		      basic_block bb = BASIC_BLOCK (bb_index);
-		      (*dflow->problem->free_bb_fun) (dflow, bb, diff);
+		      if (bb)
+			{
+			  (*dflow->problem->free_bb_fun) 
+			    (dflow, bb, df_get_bb_info (dflow, bb_index));
+			  df_set_bb_info (dflow, bb_index, NULL); 
+			}
 		    }
 		}
 	    }
 
+	  BITMAP_FREE (all);
 	  BITMAP_FREE (diff);
 	}
       else
-	df->blocks_to_analyze = BITMAP_ALLOC (NULL);
+	{
+	  /* If we have not actually run scanning before, do not try
+	     to clear anything.  */
+	  struct dataflow *scan_dflow = df->problems_by_index [DF_SCAN];
+	  if (scan_dflow->problem_data)
+	    {
+	      bitmap blocks_to_reset = NULL;
+	      int p;
+	      for (p = df->num_problems_defined - 1; p >= 0 ;p--)
+		{
+		  struct dataflow *dflow = df->problems_in_order[p];
+		  if (*dflow->problem->reset_fun)
+		    {
+		      if (!blocks_to_reset)
+			{
+			  basic_block bb;
+			  blocks_to_reset = BITMAP_ALLOC (NULL);
+			  FOR_ALL_BB(bb)
+			    {
+			      bitmap_set_bit (blocks_to_reset, bb->index); 
+			    }
+			}
+		      (*dflow->problem->reset_fun) (dflow, blocks_to_reset);
+		    }
+		}
+	      if (blocks_to_reset)
+		BITMAP_FREE (blocks_to_reset);
+	    }
+	  df->blocks_to_analyze = BITMAP_ALLOC (NULL);
+	}
       bitmap_copy (df->blocks_to_analyze, blocks);
     }
   else
Index: df.h
===================================================================
--- df.h	(revision 110059)
+++ df.h	(working copy)
@@ -67,6 +67,14 @@ enum df_flow_dir
 /* Allocate the problem specific data.  */
 typedef void (*df_alloc_function) (struct dataflow *, bitmap);
 
+/* This function is called if the problem has global data that needs
+   to be cleared when ever the set of blocks changes.  The bitmap
+   contains the set of blocks that may require special attention.
+   This call is only made if some of the blocks are going to change.
+   If everything is to be deleted, the wholesale deletion mechanisms
+   apply. */
+typedef void (*df_reset_function) (struct dataflow *, bitmap);
+
 /* Free the basic block info.  Called from the block reordering code
    to get rid of the blocks that have been squished down.   */
 typedef void (*df_free_bb_function) (struct dataflow *, basic_block, void *);
@@ -108,6 +116,7 @@ struct df_problem {
   unsigned int id;                        
   enum df_flow_dir dir;			/* Dataflow direction.  */
   df_alloc_function alloc_fun;
+  df_reset_function reset_fun;
   df_free_bb_function free_bb_fun;
   df_local_compute_function local_compute_fun;
   df_init_function init_fun;
@@ -216,7 +225,7 @@ struct df_ref
   basic_block bb;               /* Basic block containing the instruction. */
   rtx insn;			/* Insn containing ref.  NB: THIS MAY BE NULL.  */
   rtx *loc;			/* The location of the reg.  */
-  struct df_link *chain;	/* Head of def-use, use-def or bi chain.  */
+  struct df_link *chain;	/* Head of def-use, use-def.  */
   unsigned int id;		/* Location in table.  */
   enum df_ref_type type;	/* Type of ref.  */
   enum df_ref_flags flags;	/* Various flags.  */
Index: df-problems.c
===================================================================
--- df-problems.c	(revision 110059)
+++ df-problems.c	(working copy)
@@ -777,6 +777,7 @@ static struct df_problem problem_RU =
   DF_RU,                      /* Problem id.  */
   DF_BACKWARD,                /* Direction.  */
   df_ru_alloc,                /* Allocate the problem specific data.  */
+  NULL,                       /* Reset global information.  */
   df_ru_free_bb_info,         /* Free basic block info.  */
   df_ru_local_compute,        /* Local compute function.  */
   df_ru_init_solution,        /* Init the solution specific data.  */
@@ -1269,6 +1270,7 @@ static struct df_problem problem_RD =
   DF_RD,                      /* Problem id.  */
   DF_FORWARD,                 /* Direction.  */
   df_rd_alloc,                /* Allocate the problem specific data.  */
+  NULL,                       /* Reset global information.  */
   df_rd_free_bb_info,         /* Free basic block info.  */
   df_rd_local_compute,        /* Local compute function.  */
   df_rd_init_solution,        /* Init the solution specific data.  */
@@ -1655,6 +1657,7 @@ static struct df_problem problem_LR =
   DF_LR,                      /* Problem id.  */
   DF_BACKWARD,                /* Direction.  */
   df_lr_alloc,                /* Allocate the problem specific data.  */
+  NULL,                       /* Reset global information.  */
   df_lr_free_bb_info,         /* Free basic block info.  */
   df_lr_local_compute,        /* Local compute function.  */
   df_lr_init,                 /* Init the solution specific data.  */
@@ -1991,6 +1994,7 @@ static struct df_problem problem_UR =
   DF_UR,                      /* Problem id.  */
   DF_FORWARD,                 /* Direction.  */
   df_ur_alloc,                /* Allocate the problem specific data.  */
+  NULL,                       /* Reset global information.  */
   df_ur_free_bb_info,         /* Free basic block info.  */
   df_ur_local_compute,        /* Local compute function.  */
   df_ur_init,                 /* Init the solution specific data.  */
@@ -2615,6 +2619,7 @@ static struct df_problem problem_UREC =
   DF_UREC,                    /* Problem id.  */
   DF_FORWARD,                 /* Direction.  */
   df_urec_alloc,              /* Allocate the problem specific data.  */
+  NULL,                       /* Reset global information.  */
   df_urec_free_bb_info,       /* Free basic block info.  */
   df_urec_local_compute,      /* Local compute function.  */
   df_urec_init,               /* Init the solution specific data.  */
@@ -2702,6 +2707,114 @@ df_chain_alloc (struct dataflow *dflow, 
 }
 
 
+/* Reset all def_use and use_def chains in INSN.  */
+
+static void 
+df_chain_insn_reset (struct dataflow *dflow, rtx insn)
+{
+  struct df *df = dflow->df;
+  struct df_chain_problem_data *problem_data =
+    (struct df_chain_problem_data *) dflow->problem_data;
+  unsigned int uid = INSN_UID (insn);
+  struct df_insn_info *insn_info = NULL;
+  struct df_ref *ref;
+
+  if (uid < df->insns_size)
+    insn_info = DF_INSN_UID_GET (df, uid);
+
+  if (insn_info)
+    {
+      if (problem_data->flags & DF_DU_CHAIN)
+	{
+	  ref = insn_info->defs;
+	  while (ref)
+	    {
+	      ref->chain = NULL;
+	      ref = ref->next_ref;
+	    }
+	}
+
+      if (problem_data->flags & DF_UD_CHAIN)
+	{
+	  ref = insn_info->uses;
+	  while (ref) 
+	    {
+	      ref->chain = NULL;
+	      ref = ref->next_ref;
+	    }
+	}
+    }
+}
+
+
+/* Reset all def_use and use_def chains in basic block.  */
+
+static void 
+df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index)
+{
+  struct df *df = dflow->df; 
+  struct df_chain_problem_data *problem_data =
+    (struct df_chain_problem_data *) dflow->problem_data;
+  rtx insn;
+  basic_block bb = BASIC_BLOCK (bb_index);
+
+  /* Some one deleted the basic block out from under us.  */
+  if (!bb)
+    return;
+
+  FOR_BB_INSNS (bb, insn)
+    {
+      if (INSN_P (insn))
+	{
+	  /* Record defs within INSN.  */
+	  df_chain_insn_reset (dflow, insn);
+	}
+    }
+  
+  /* Get rid of any chains in artifical uses or defs.  */
+  if (problem_data->flags & DF_DU_CHAIN)
+    {
+      struct df_ref *def;
+      def = df_get_artificial_defs (df, bb_index);
+      while (def)
+	{
+	  def->chain = NULL;
+	  def = def->next_ref;
+	}
+    }
+
+  if (problem_data->flags & DF_UD_CHAIN)
+    {
+      struct df_ref *use;
+      use = df_get_artificial_uses (df, bb_index);
+      while (use)
+	{
+	  use->chain = NULL;
+	  use = use->next_ref;
+	}
+    }
+}
+
+
+/* Reset all of the chains when the set of basic blocks changes.  */
+
+
+static void
+df_chain_reset (struct dataflow *dflow, bitmap blocks_to_clear)
+{
+  bitmap_iterator bi;
+  unsigned int bb_index;
+  
+  EXECUTE_IF_SET_IN_BITMAP (blocks_to_clear, 0, bb_index, bi)
+    {
+      df_chain_bb_reset (dflow, bb_index);
+    }
+
+  free_alloc_pool (dflow->block_pool);
+  dflow->block_pool = NULL;
+}
+
+
 /* Create the chains for a list of USEs.  */
 
 static void
@@ -2917,6 +3030,7 @@ static struct df_problem problem_CHAIN =
   DF_CHAIN,                   /* Problem id.  */
   DF_NONE,                    /* Direction.  */
   df_chain_alloc,             /* Allocate the problem specific data.  */
+  df_chain_reset,             /* Reset global information.  */
   NULL,                       /* Free basic block info.  */
   NULL,                       /* Local compute function.  */
   NULL,                       /* Init the solution specific data.  */
@@ -3092,6 +3206,7 @@ static struct df_problem problem_RI =
   DF_RI,                      /* Problem id.  */
   DF_NONE,                    /* Direction.  */
   df_ri_alloc,                /* Allocate the problem specific data.  */
+  NULL,                       /* Reset global information.  */
   NULL,                       /* Free basic block info.  */
   df_ri_compute,              /* Local compute function.  */
   NULL,                       /* Init the solution specific data.  */

Reply via email to