This is the mail archive of the gcc-bugs@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]

[Bug middle-end/34884] [4.3 Regression] gfortran.dg/array_constructor_9.f90



------- Comment #28 from zadeck at naturalbridge dot com  2008-01-22 13:35 -------
Subject: Re:  [4.3 Regression] gfortran.dg/array_constructor_9.f90

zadeck at naturalbridge dot com wrote:
> ------- Comment #27 from zadeck at naturalbridge dot com  2008-01-21 15:36 -------
> Subject: Re:  [4.3 Regression] gfortran.dg/array_constructor_9.f90
>
> bonzini at gnu dot org wrote:
>   
>> ------- Comment #26 from bonzini at gnu dot org  2008-01-21 14:54 -------
>> Subject: Re:  [4.3 Regression] gfortran.dg/array_constructor_9.f90
>>
>> Agreed.  I think we'd better revert the patch now.
>>
>>
>>   
>>     
> i give.
>
> i will prepare a revert this afternoon.  i need to go run some errands now.
>
> kenny
>
>
>   
This patch reverses most of the rd2 patch that speeds up pr3400 and pr26854.
Unfortunately that patch caused some regressions that are very difficult
to resolved.  These were reported in pr34884.

This patch reverses most of rd2.diff.  It leaves in the fixes to the
comments and one fix to a latent bug.  The patch has been tested on
ia-64, ppc-32, x86-64 and x86-32. 

2008-01-22  Kenneth Zadeck <zadeck@naturalbridge.com>

    PR rtl-optimization/26854
    PR rtl-optimization/34400
    PR rtl-optimization/34884
    * ddg.c (create_ddg_dep_from_intra_loop_link): Use
    DF_RD->gen.
    * df.h (df_changeable_flags.DF_RD_NO_TRIM): Deleted
    (df_rd_bb_info.expanded_lr_out): Deleted
    * loop_invariant.c (find_defs): Deleted DF_RD_NO_TRIM flag.
    * loop_iv.c (iv_analysis_loop_init): Ditto.  * df-problems.c
    (df_rd_free_bb_info, df_rd_alloc, df_rd_confluence_n,
    df_rd_bb_local_compute, df_rd_transfer_function, df_rd_free):
    Removed code to allocate, initialize or free expanded_lr_out.
    (df_rd_bb_local_compute_process_def): Restructured to make more
    understandable.
    (df_rd_confluence_n): Removed code to no apply invalidate_by_call
    sets if the sets are being trimmed.


Ok to commit.
Index: ddg.c
===================================================================
--- ddg.c       (revision 131716)
+++ ddg.c       (working copy)
@@ -184,13 +184,12 @@ create_ddg_dep_from_intra_loop_link (ddg
         {
           int regno = REGNO (SET_DEST (set));
           struct df_ref *first_def;
-          struct df_ref *last_def;
+          struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb);

           first_def = df_bb_regno_first_def_find (g->bb, regno);
           gcc_assert (first_def);

-          last_def = df_bb_regno_last_def_find (g->bb, regno);
-          if (first_def == last_def)
+          if (bitmap_bit_p (bb_info->gen, first_def->id))
             return;
         }
     }
Index: df.h
===================================================================
--- df.h        (revision 131716)
+++ df.h        (working copy)
@@ -405,27 +405,20 @@ enum df_changeable_flags 
   DF_LR_RUN_DCE           = 1 << 0, /* Run DCE.  */
   DF_NO_HARD_REGS         = 1 << 1, /* Skip hard registers in RD and CHAIN
Building.  */

-  /* Do not trim the solution using the LR result.  This can make the
-     solution take much longer and take more memory.  This is
-     necessary for the loop optimizations, but has a very small time
-     and space penalty because the loop optimizations process only a
-     single loop at a time.  Any pass that looks at the entire
-     function should not set this flag.  */
-  DF_RD_NO_TRIM           = 1 << 2,
-  DF_EQ_NOTES             = 1 << 3, /* Build chains with uses present in
EQUIV/EQUAL notes. */
-  DF_NO_REGS_EVER_LIVE    = 1 << 4, /* Do not compute the regs_ever_live.  */
+  DF_EQ_NOTES             = 1 << 2, /* Build chains with uses present in
EQUIV/EQUAL notes. */
+  DF_NO_REGS_EVER_LIVE    = 1 << 3, /* Do not compute the regs_ever_live.  */

   /* Cause df_insn_rescan df_notes_rescan and df_insn_delete, to
   return immediately.  This is used by passes that know how to update
   the scanning them selves.  */
-  DF_NO_INSN_RESCAN       = 1 << 5,
+  DF_NO_INSN_RESCAN       = 1 << 4,

   /* Cause df_insn_rescan df_notes_rescan and df_insn_delete, to
   return after marking the insn for later processing.  This allows all
   rescans to be batched.  */
-  DF_DEFER_INSN_RESCAN    = 1 << 6,
+  DF_DEFER_INSN_RESCAN    = 1 << 5,

-  DF_VERIFY_SCHEDULED     = 1 << 7
+  DF_VERIFY_SCHEDULED     = 1 << 6
 };

 /* Two of these structures are inline in df, one for the uses and one
@@ -719,37 +712,9 @@ struct df_rd_bb_info 
   /* Local sets to describe the basic blocks.   */
   bitmap kill;  
   bitmap sparse_kill;
+  bitmap gen;   /* The set of defs generated in this block.  */

-  /* Expanded version of the DF_LT->out bitmap to match the positions
-     of gen, in and out here.  Only allocated if DF_RD_NO_TRIM is
-     false.  */
-  bitmap expanded_lr_out;
-
-  /* The set of defs generated in this block.  This is not set unless
-     the def reaches the end of the block.  */
-  bitmap gen;
-
-  /* The results of the dataflow problem.  
-
-     If DF_RD_NO_TRIM is not set, these sets are SOMEWHAT trimmed by
-     the output of the DF_LR problem.  The out set is precisely
-     trimmed during propagation which means that the result is also
-     trimmed when the propagation terminates.  The in set is not
-     explicitly trimmed, because this is expensive (adding about 5% to
-     the cost of a bootstrap).  However since the out sets are trimmed
-     and the in sets are built from the out of the pred, the in set is
-     MOSTLY trimmed.
-
-     The counter case happens at a branch where the variable V is in
-     DF_LR->in the true branch but not the false branch.  If V is
-     defined before the branch, RD will propagate that into the
-     DF_RD_in sets of both branches.  When the block is processed, the
-     DF_RD->out set will have V trimmed out of it but it will still be
-     left in DF_RD->in.  
-
-     If this not a problem for the current optimizers since they were
-     designed before any trimming was available.  This can be fixed by
-     checking the DF_LR->in set directly.  */
+  /* The results of the dataflow problem.  */
   bitmap in;    /* At the top of the block.  */
   bitmap out;   /* At the bottom of the block.  */
 };
Index: loop-invariant.c
===================================================================
--- loop-invariant.c    (revision 131716)
+++ loop-invariant.c    (working copy)
@@ -639,7 +639,6 @@ find_defs (struct loop *loop, basic_bloc
   df_remove_problem (df_chain);
   df_process_deferred_rescans ();
   df_chain_add_problem (DF_UD_CHAIN);
-  df_set_flags (DF_RD_NO_TRIM);
   df_set_blocks (blocks);
   df_analyze ();

Index: loop-iv.c
===================================================================
--- loop-iv.c   (revision 131716)
+++ loop-iv.c   (working copy)
@@ -278,7 +278,6 @@ iv_analysis_loop_init (struct loop *loop
   df_remove_problem (df_chain);
   df_process_deferred_rescans ();
   df_chain_add_problem (DF_UD_CHAIN);
-  df_set_flags (DF_RD_NO_TRIM);
   df_set_blocks (blocks);
   df_analyze ();
   if (dump_file)
Index: df-problems.c
===================================================================
--- df-problems.c       (revision 131716)
+++ df-problems.c       (working copy)
@@ -245,8 +245,6 @@ df_rd_free_bb_info (basic_block bb ATTRI
   struct df_rd_bb_info *bb_info = (struct df_rd_bb_info *) vbb_info;
   if (bb_info)
     {
-      if (bb_info->expanded_lr_out)
-       BITMAP_FREE (bb_info->expanded_lr_out);
       BITMAP_FREE (bb_info->kill);
       BITMAP_FREE (bb_info->sparse_kill);
       BITMAP_FREE (bb_info->gen);
@@ -300,8 +298,6 @@ df_rd_alloc (bitmap all_blocks)
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
       if (bb_info)
        { 
-         if (bb_info->expanded_lr_out)
-           bitmap_clear (bb_info->expanded_lr_out);
          bitmap_clear (bb_info->kill);
          bitmap_clear (bb_info->sparse_kill);
          bitmap_clear (bb_info->gen);
@@ -310,10 +306,6 @@ df_rd_alloc (bitmap all_blocks)
        { 
          bb_info = (struct df_rd_bb_info *) pool_alloc (df_rd->block_pool);
          df_rd_set_bb_info (bb_index, bb_info);
-         if (df->changeable_flags & DF_RD_NO_TRIM)
-           bb_info->expanded_lr_out = NULL;
-         else
-           bb_info->expanded_lr_out = BITMAP_ALLOC
(&problem_data->rd_bitmaps);
          bb_info->kill = BITMAP_ALLOC (&problem_data->rd_bitmaps);
          bb_info->sparse_kill = BITMAP_ALLOC (&problem_data->rd_bitmaps);
          bb_info->gen = BITMAP_ALLOC (&problem_data->rd_bitmaps);
@@ -328,53 +320,56 @@ df_rd_alloc (bitmap all_blocks)
 /* Process a list of DEFs for df_rd_bb_local_compute.  */

 static void
-df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info,
+df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info, 
                                    struct df_ref **def_rec,
                                    enum df_ref_flags top_flag)
 {
-  for (; *def_rec; def_rec++)
+  while (*def_rec)
     {
       struct df_ref *def = *def_rec;
-      unsigned int regno = DF_REF_REGNO (def);
-
-      /* This makes sure we do the artificial defs in the right order
-        since they are all in the same list.  */
-      if (top_flag != (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
-       continue;
-
-      /* Skip over the hard regs if we do not care about them.  */
-      if ((df->changeable_flags & DF_NO_HARD_REGS) && 
-         (regno < FIRST_PSEUDO_REGISTER))
-       continue;
-
-      /* Only the last def(s) for a regno in the block has any
-        effect.  */ 
-      if (bitmap_bit_p (seen_in_block, regno))
-       continue;
-
-      /* The first def for regno in insn gets to knock out the
-        defs from other instructions.  */
-      if ((!bitmap_bit_p (seen_in_insn, regno))
-         /* If the def is to only part of the reg, it does
-            not kill the other defs that reach here.  */
-         && (!(DF_REF_FLAGS (def) & 
-               (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER))))
+      if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
        {
+         unsigned int regno = DF_REF_REGNO (def);
          unsigned int begin = DF_DEFS_BEGIN (regno);
          unsigned int n_defs = DF_DEFS_COUNT (regno);
-         if (n_defs > DF_SPARSE_THRESHOLD)
-           bitmap_set_bit (bb_info->sparse_kill, regno);
-         else
-           bitmap_set_range (bb_info->kill, begin, n_defs);
-         bitmap_clear_range(bb_info->gen, begin, n_defs);
+         
+         if ((!(df->changeable_flags & DF_NO_HARD_REGS))
+             || (regno >= FIRST_PSEUDO_REGISTER))
+           {
+             /* Only the last def(s) for a regno in the block has any
+                effect.  */ 
+             if (!bitmap_bit_p (seen_in_block, regno))
+               {
+                 /* The first def for regno in insn gets to knock out the
+                    defs from other instructions.  */
+                 if ((!bitmap_bit_p (seen_in_insn, regno))
+                     /* If the def is to only part of the reg, it does
+                        not kill the other defs that reach here.  */
+                     && (!(DF_REF_FLAGS (def) & 
+                           (DF_REF_PARTIAL | DF_REF_CONDITIONAL |
DF_REF_MAY_CLOBBER))))
+                   {
+                     if (n_defs > DF_SPARSE_THRESHOLD)
+                       {
+                         bitmap_set_bit (bb_info->sparse_kill, regno);
+                         bitmap_clear_range(bb_info->gen, begin, n_defs);
+                       }
+                     else
+                       {
+                         bitmap_set_range (bb_info->kill, begin, n_defs);
+                         bitmap_clear_range (bb_info->gen, begin, n_defs);
+                       }
+                   }
+                 
+                 bitmap_set_bit (seen_in_insn, regno);
+                 /* All defs for regno in the instruction may be put into
+                    the gen set.  */
+                 if (!(DF_REF_FLAGS (def) 
+                       & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
+                   bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
+               }
+           }
        }
-      
-      bitmap_set_bit (seen_in_insn, regno);
-      /* All defs for regno in the instruction may be put into
-        the gen set.  */
-      if (!(DF_REF_FLAGS (def) 
-           & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
-       bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
+      def_rec++;
     }
 }

@@ -385,28 +380,14 @@ df_rd_bb_local_compute (unsigned int bb_
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
-  struct df_lr_bb_info *lr_bb_info = df_lr_get_bb_info (bb_index);
   rtx insn;

   bitmap_clear (seen_in_block);
   bitmap_clear (seen_in_insn);

-  if (!(df->changeable_flags & DF_RD_NO_TRIM))
-    {
-      unsigned int regno;
-      bitmap_iterator bi;
-      int first_reg = (df->changeable_flags & DF_NO_HARD_REGS) ?
FIRST_PSEUDO_REGISTER : 0;
-      EXECUTE_IF_SET_IN_BITMAP (lr_bb_info->out, first_reg, regno, bi)
-       {
-         unsigned int begin = DF_DEFS_BEGIN (regno);
-         unsigned int n_defs = DF_DEFS_COUNT (regno);
-         bitmap_set_range (bb_info->expanded_lr_out, begin, n_defs);
-       }
-    }
-
   /* Artificials are only hard regs.  */
   if (!(df->changeable_flags & DF_NO_HARD_REGS))
-    df_rd_bb_local_compute_process_def (bb_info,
+    df_rd_bb_local_compute_process_def (bb_info, 
                                        df_get_artificial_defs (bb_index),
                                        0);

@@ -504,10 +485,7 @@ df_rd_confluence_n (edge e)
   if (e->flags & EDGE_FAKE) 
     return;

-  /* If we are trimming the solution, the invalidated_by_call code in
-     the lr problem makes this unnecessary.  However, if we do not
-     trim, we must take this into account.  */
-  if ((df->changeable_flags & DF_RD_NO_TRIM) && e->flags & EDGE_EH)
+  if (e->flags & EDGE_EH)
     {
       struct df_rd_problem_data *problem_data
        = (struct df_rd_problem_data *) df_rd->problem_data;
@@ -515,7 +493,7 @@ df_rd_confluence_n (edge e)
       bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
       bitmap_iterator bi;
       unsigned int regno;
-      bitmap tmp = BITMAP_ALLOC (&problem_data->rd_bitmaps);
+      bitmap tmp = BITMAP_ALLOC (&df_bitmap_obstack);

       bitmap_copy (tmp, op2);
       bitmap_and_compl_into (tmp, dense_invalidated);
@@ -547,13 +525,13 @@ df_rd_transfer_function (int bb_index)
   bitmap gen = bb_info->gen;
   bitmap kill = bb_info->kill;
   bitmap sparse_kill = bb_info->sparse_kill;
-  bool changed = false;

-  if ((df->changeable_flags & DF_RD_NO_TRIM) && bitmap_empty_p (sparse_kill))
-    changed = bitmap_ior_and_compl (out, gen, in, kill);
+  if (bitmap_empty_p (sparse_kill))
+    return  bitmap_ior_and_compl (out, gen, in, kill);
   else 
     {
       struct df_rd_problem_data *problem_data;
+      bool changed = false;
       bitmap tmp;

       /* Note that TMP is _not_ a temporary bitmap if we end up replacing
@@ -570,8 +548,6 @@ df_rd_transfer_function (int bb_index)
        }
       bitmap_and_compl_into (tmp, kill);
       bitmap_ior_into (tmp, gen);
-      if (!(df->changeable_flags & DF_RD_NO_TRIM))
-       bitmap_and_into (tmp, bb_info->expanded_lr_out);
       changed = !bitmap_equal_p (tmp, out);
       if (changed)
        {
@@ -579,10 +555,9 @@ df_rd_transfer_function (int bb_index)
          bb_info->out = tmp;
        }
       else 
-       BITMAP_FREE (tmp);
+         BITMAP_FREE (tmp);
+      return changed;
     }
-
-  return changed;
 }


@@ -602,8 +577,6 @@ df_rd_free (void)
          struct df_rd_bb_info *bb_info = df_rd_get_bb_info (i);
          if (bb_info)
            {
-             if (bb_info->expanded_lr_out)
-               BITMAP_FREE (bb_info->expanded_lr_out);
              BITMAP_FREE (bb_info->kill);
              BITMAP_FREE (bb_info->sparse_kill);
              BITMAP_FREE (bb_info->gen);


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34884


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