OSDN Git Service

2009-04-10 Paolo Bonzini <bonzini@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / df-problems.c
index 829698b..c0f79d8 100644 (file)
@@ -1,6 +1,6 @@
 /* Standard problems for dataflow support routines.
    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008 Free Software Foundation, Inc.
+   2008, 2009 Free Software Foundation, Inc.
    Originally contributed by Michael P. Hayes 
              (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
    Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
@@ -443,7 +443,7 @@ df_rd_local_compute (bitmap all_blocks)
     }
   
   /* Set up the knockout bit vectors to be applied across EH_EDGES.  */
-  EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, regno, bi)
+  EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, regno, bi)
     {
       if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD)
        bitmap_set_bit (sparse_invalidated, regno);
@@ -975,7 +975,7 @@ df_lr_confluence_n (edge e)
   /* ??? Abnormal call edges ignored for the moment, as this gets
      confused by sibling call edges, which crashes reg-stack.  */
   if (e->flags & EDGE_EH)
-    bitmap_ior_and_compl_into (op1, op2, df_invalidated_by_call);
+    bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset);
   else
     bitmap_ior_into (op1, op2);
 
@@ -1001,25 +1001,34 @@ df_lr_transfer_function (int bb_index)
 /* Run the fast dce as a side effect of building LR.  */
 
 static void
-df_lr_finalize (bitmap all_blocks ATTRIBUTE_UNUSED)
+df_lr_finalize (bitmap all_blocks)
 {
+  df_lr->solutions_dirty = false;
   if (df->changeable_flags & DF_LR_RUN_DCE)
     {
       run_fast_df_dce ();
-      if (df_lr->problem_data && df_lr->solutions_dirty)
+
+      /* If dce deletes some instructions, we need to recompute the lr
+        solution before proceeding further.  The problem is that fast
+        dce is a pessimestic dataflow algorithm.  In the case where
+        it deletes a statement S inside of a loop, the uses inside of
+        S may not be deleted from the dataflow solution because they
+        were carried around the loop.  While it is conservatively
+        correct to leave these extra bits, the standards of df
+        require that we maintain the best possible (least fixed
+        point) solution.  The only way to do that is to redo the
+        iteration from the beginning.  See PR35805 for an
+        example.  */
+      if (df_lr->solutions_dirty)
        {
-         /* If we are here, then it is because we are both verifying
-         the solution and the dce changed the function.  In that case
-         the verification info built will be wrong.  So we leave the
-         dirty flag true so that the verifier will skip the checking
-         part and just clean up.*/
-         df_lr->solutions_dirty = true;
+         df_clear_flags (DF_LR_RUN_DCE);
+         df_lr_alloc (all_blocks);
+         df_lr_local_compute (all_blocks);
+         df_worklist_dataflow (df_lr, all_blocks, df->postorder, df->n_blocks);
+         df_lr_finalize (all_blocks);
+         df_set_flags (DF_LR_RUN_DCE);
        }
-      else
-       df_lr->solutions_dirty = false;
     }
-  else
-    df_lr->solutions_dirty = false;
 }
 
 
@@ -2542,7 +2551,7 @@ df_byte_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   df_byte_lr_expand_bitmap (problem_data->hardware_regs_used, 
                            df->hardware_regs_used);
   df_byte_lr_expand_bitmap (problem_data->invalidated_by_call, 
-                           df_invalidated_by_call);
+                           regs_invalidated_by_call_regset);
 
   EXECUTE_IF_SET_IN_BITMAP (df_byte_lr->out_of_date_transfer_functions, 0, bb_index, bi)
     {