OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / df-core.c
index 59602de..e9da8b6 100644 (file)
@@ -205,18 +205,23 @@ There are 4 ways to obtain access to refs:
    defs and uses are only there if DF_HARD_REGS was specified when the
    df instance was created.
  
-   Artificial defs and uses occur at the beginning blocks that are the
-   destination of eh edges.  The defs come from the registers
-   specified in EH_RETURN_DATA_REGNO and the uses come from the
-   registers specified in ED_USES.  Logically these defs and uses
-   should really occur along the eh edge, but there is no convienent
-   way to do this.  Artificial edges that occur at the beginning of
-   the block have the DF_REF_AT_TOP flag set.
-   
-   Artificial uses also occur at the end of all blocks.  These arise
-   from the hard registers that are always live, such as the stack
-   register and are put there to keep the code from forgetting about
-   them.
+   Artificial defs and uses occur both at the beginning and ends of blocks.
+
+     For blocks that area at the destination of eh edges, the
+     artificial uses and defs occur at the beginning.  The defs relate
+     to the registers specified in EH_RETURN_DATA_REGNO and the uses
+     relate to the registers specified in ED_USES.  Logically these
+     defs and uses should really occur along the eh edge, but there is
+     no convenient way to do this.  Artificial edges that occur at the
+     beginning of the block have the DF_REF_AT_TOP flag set.
+
+     Artificial uses occur at the end of all blocks.  These arise from
+     the hard registers that are always live, such as the stack
+     register and are put there to keep the code from forgetting about
+     them.
+
+     Artifical defs occur at the end of the entry block.  These arise
+     from registers that are live at entry to the function.
 
 2) All of the uses and defs associated with each pseudo or hard
    register are linked in a bidirectional chain.  These are called
@@ -292,6 +297,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.
 ----------------------------------------------------------------------------*/
@@ -303,7 +310,7 @@ struct df *shared_df = NULL;
 struct df *
 df_init (int flags)
 {
-  struct df *df = xcalloc (1, sizeof (struct df));
+  struct df *df = XCNEW (struct df);
   df->flags = flags;
 
   /* This is executed once per compilation to initialize platform
@@ -335,7 +342,7 @@ df_add_problem (struct df *df, struct df_problem *problem)
     return dflow;
 
   /* Make a new one and add it to the end.  */
-  dflow = xcalloc (1, sizeof (struct dataflow));
+  dflow = XCNEW (struct dataflow);
   dflow->df = df;
   dflow->problem = problem;
   df->problems_in_order[df->num_problems_defined++] = dflow;
@@ -354,8 +361,67 @@ df_set_blocks (struct df *df, bitmap blocks)
 {
   if (blocks)
     {
-      if (!df->blocks_to_analyze)
-       df->blocks_to_analyze = BITMAP_ALLOC (NULL);
+      if (df->blocks_to_analyze)
+       {
+         int p;
+         bitmap diff = BITMAP_ALLOC (NULL);
+         bitmap_and_compl (diff, df->blocks_to_analyze, blocks);
+         for (p = df->num_problems_defined - 1; p >= 0 ;p--)
+           {
+             struct dataflow *dflow = df->problems_in_order[p];
+             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;
+                 
+                 EXECUTE_IF_SET_IN_BITMAP (diff, 0, bb_index, bi)
+                   {
+                     basic_block bb = BASIC_BLOCK (bb_index);
+                     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 (diff);
+       }
+      else
+       {
+         /* 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
@@ -378,7 +444,7 @@ df_finish1 (struct df *df)
   int i;
 
   for (i = 0; i < df->num_problems_defined; i++)
-    (*df->problems_in_order[i]->problem->free_fun) (df->problems_in_order[i]); 
+    df->problems_in_order[i]->problem->free_fun (df->problems_in_order[i]); 
 
   free (df);
 }
@@ -413,12 +479,12 @@ df_hybrid_search_forward (basic_block bb,
        if (!TEST_BIT (dataflow->considered, e->src->index))
          continue;
        
-       (*dataflow->problem->con_fun_n) (dataflow, e);
+       dataflow->problem->con_fun_n (dataflow, e);
       }
-  else if (*dataflow->problem->con_fun_0)
-    (*dataflow->problem->con_fun_0) (dataflow, bb);
+  else if (dataflow->problem->con_fun_0)
+    dataflow->problem->con_fun_0 (dataflow, bb);
   
-  result_changed = (*dataflow->problem->trans_fun) (dataflow, i);
+  result_changed = dataflow->problem->trans_fun (dataflow, i);
   
   if (!result_changed || single_pass)
     return;
@@ -465,12 +531,12 @@ df_hybrid_search_backward (basic_block bb,
        if (!TEST_BIT (dataflow->considered, e->dest->index))           
          continue;                                                     
        
-       (*dataflow->problem->con_fun_n) (dataflow, e);
+       dataflow->problem->con_fun_n (dataflow, e);
       }                                                                
-  else if (*dataflow->problem->con_fun_0)
-    (*dataflow->problem->con_fun_0) (dataflow, bb);
+  else if (dataflow->problem->con_fun_0)
+    dataflow->problem->con_fun_0 (dataflow, bb);
 
-  result_changed = (*dataflow->problem->trans_fun) (dataflow, i);
+  result_changed = dataflow->problem->trans_fun (dataflow, i);
   
   if (!result_changed || single_pass)
     return;
@@ -539,7 +605,7 @@ df_iterative_dataflow (struct dataflow *dataflow,
       SET_BIT (pending, idx);
     };
 
-  (*dataflow->problem->init_fun) (dataflow, blocks_to_init);
+  dataflow->problem->init_fun (dataflow, blocks_to_init);
 
   while (1)
     {
@@ -638,24 +704,24 @@ df_analyze_problem (struct dataflow *dflow,
                    int *postorder, int n_blocks, bool single_pass)
 {
   /* (Re)Allocate the datastructures necessary to solve the problem.  */ 
-  if (*dflow->problem->alloc_fun)
-    (*dflow->problem->alloc_fun) (dflow, blocks_to_scan);
+  if (dflow->problem->alloc_fun)
+    dflow->problem->alloc_fun (dflow, blocks_to_scan);
 
   /* Set up the problem and compute the local information.  This
      function is passed both the blocks_to_consider and the
      blocks_to_scan because the RD and RU problems require the entire
      function to be rescanned if they are going to be updated.  */
-  if (*dflow->problem->local_compute_fun)
-    (*dflow->problem->local_compute_fun) (dflow, blocks_to_consider, blocks_to_scan);
+  if (dflow->problem->local_compute_fun)
+    dflow->problem->local_compute_fun (dflow, blocks_to_consider, blocks_to_scan);
 
   /* Solve the equations.  */
-  if (*dflow->problem->dataflow_fun)
-    (*dflow->problem->dataflow_fun) (dflow, blocks_to_consider, blocks_to_init,
-                                   postorder, n_blocks, single_pass);
+  if (dflow->problem->dataflow_fun)
+    dflow->problem->dataflow_fun (dflow, blocks_to_consider, blocks_to_init,
+                                 postorder, n_blocks, single_pass);
 
   /* Massage the solution.  */
-  if (*dflow->problem->finalize_fun)
-    (*dflow->problem->finalize_fun) (dflow, blocks_to_consider);
+  if (dflow->problem->finalize_fun)
+    dflow->problem->finalize_fun (dflow, blocks_to_consider);
 }
 
 
@@ -665,7 +731,7 @@ df_analyze_problem (struct dataflow *dflow,
 void
 df_analyze (struct df *df)
 {
-  int *postorder = xmalloc (sizeof (int) *last_basic_block);
+  int *postorder = XNEWVEC (int, last_basic_block);
   bitmap current_all_blocks = BITMAP_ALLOC (NULL);
   int n_blocks;
   int i;
@@ -716,6 +782,7 @@ df_analyze (struct df *df)
 
   BITMAP_FREE (df->blocks_to_scan);
   df->blocks_to_scan = NULL;
+  free (postorder);
 }
 
 
@@ -759,7 +826,7 @@ df_compact_blocks (struct df *df)
   for (p = 0; p < df->num_problems_defined; p++)
     {
       struct dataflow *dflow = df->problems_in_order[p];
-      if (*dflow->problem->free_bb_fun)
+      if (dflow->problem->free_bb_fun)
        {
          df_grow_bb_info (dflow);
          memcpy (problem_temps, dflow->block_info, size);
@@ -781,8 +848,10 @@ df_compact_blocks (struct df *df)
             These are from orphaned blocks.  */
          for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
            {
-             if (problem_temps[i])
-               (*dflow->problem->free_bb_fun) (dflow, problem_temps[i]);
+             basic_block bb = BASIC_BLOCK (i); 
+             if (problem_temps[i] && bb)
+               dflow->problem->free_bb_fun
+                 (dflow, bb, problem_temps[i]);
            }
        }
     }
@@ -995,7 +1064,7 @@ df_dump (struct df *df, FILE *file)
           df->def_info.bitmap_size, df->use_info.bitmap_size);
 
   for (i = 0; i < df->num_problems_defined; i++)
-    (*df->problems_in_order[i]->problem->dump_fun) (df->problems_in_order[i], file); 
+    df->problems_in_order[i]->problem->dump_fun (df->problems_in_order[i], file); 
 
   fprintf (file, "\n");
 }