]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/26854 (Inordinate compile times on large routines)
authorKenneth Zadeck <zadeck@naturalbridge.com>
Tue, 22 Jan 2008 13:57:01 +0000 (13:57 +0000)
committerKenneth Zadeck <zadeck@gcc.gnu.org>
Tue, 22 Jan 2008 13:57:01 +0000 (13:57 +0000)
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.

From-SVN: r131719

gcc/ChangeLog
gcc/ddg.c
gcc/df-problems.c
gcc/df.h
gcc/loop-invariant.c
gcc/loop-iv.c

index 7a33a50ae00c9fae3dbccbceea54f1745a33322e..639b0fbedcd3b80969c49b2e0d4091a4f7cba75d 100644 (file)
@@ -1,3 +1,22 @@
+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.
+
 2008-01-22  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR bootstrap/32287
index c67b6c2486989f545a89436a0907ece8007d77a4..14b18745823752615eeeb264eaf23121f3f83f59 100644 (file)
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -184,13 +184,12 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
         {
           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 f45c6d2ff36db0917c93be6de87cc6e1ea3401ee..46aa9e03f4c07df2ce0ae5d72b9408eb4e13ae29 100644 (file)
@@ -245,8 +245,6 @@ df_rd_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
   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_index)
 {
   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);
index e5c6870cac37894b85517bc6d0b2c8912342d4d2..8beadc98d4c88ac85910d0e77db11c2b9c985c58 100644 (file)
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -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 f056a776958d6211f26b9c777ee4cc1443585c80..ba1f2888b009677bdaf01e91171d67395bcfea86 100644 (file)
@@ -639,7 +639,6 @@ find_defs (struct loop *loop, basic_block *body)
   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 824629c0f6cc2dc2d46f73a934e1c7b9d0543815..b7b1cd32ec0a76e72f6ca426becb54ac138e562a 100644 (file)
@@ -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)