]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
df-scan.c (problem_SCAN): Added NULL reset function.
authorKenneth Zadeck <zadeck@naturalbridge.com>
Sat, 21 Jan 2006 14:58:40 +0000 (14:58 +0000)
committerKenneth Zadeck <zadeck@gcc.gnu.org>
Sat, 21 Jan 2006 14:58:40 +0000 (14:58 +0000)
2005-01-21  Kenneth Zadeck <zadeck@naturalbridge.com>

* 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.

From-SVN: r110066

gcc/ChangeLog
gcc/df-core.c
gcc/df-problems.c
gcc/df-scan.c
gcc/df.h

index e3ebf98c1b19de0344abd4f2af17298be0c7390b..8874f87c856cb5eb5134c7d91a7186589509c38d 100644 (file)
@@ -1,3 +1,17 @@
+2005-01-21  Kenneth Zadeck <zadeck@naturalbridge.com>
+
+       * 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.
+
 2006-01-21  Ben Elliston  <bje@au.ibm.com>
 
        * varasm.c (assemble_real): Initialise data array.
index 87d9324d80f3c9a83da4e6b742bf4de127d7404c..a0ed23caa169e00da43e8e0d94dc3e397f2d97b7 100644 (file)
@@ -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 blocks)
        {
          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 blocks)
                  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 ecc8eab6627f35365e42076dfd15259497feb4b2..fdba180906eb13cf65e28bb16a42cf138691319a 100644 (file)
@@ -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.  */
index 8f1995660a3c3d0e494dfdbf139c709f2e808571..bba89e7c891717d9b0550634b6278fce152b0c82 100644 (file)
@@ -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 blocks)
 
   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 blocks)
       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 *dflow, rtx insn)
 {
   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 *dflow, int bb_index)
        }
     }
   
-  /* Get rid of any artifical uses.  */
+  /* Get rid of any artifical uses or defs.  */
   if (bb_info)
     {
       def = bb_info->artificial_defs;
index a353d36ce11eac02d2d475d41e22d97d6ac238d0..f2e7bef787a08e4b0b3d39c6694c6a8aead7a992 100644 (file)
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -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.  */