]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
params.def (PARAM_MAX_COMBINE_INSNS): New.
authorRichard Biener <rguenther@suse.de>
Wed, 23 Jul 2014 09:10:37 +0000 (09:10 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 23 Jul 2014 09:10:37 +0000 (09:10 +0000)
2014-07-23  Richard Biener  <rguenther@suse.de>

* params.def (PARAM_MAX_COMBINE_INSNS): New.
* combine.c: Include statistics.h and params.h.
(combine_instructions): Guard three and four insn combines
with max-combine-insns value.  Record statistics for combines
performed.
* doc/invoke.texi (max-combine-insns): Document new param.

From-SVN: r212923

gcc/ChangeLog
gcc/combine.c
gcc/doc/invoke.texi
gcc/params.def

index 96764719d275e4f76419db15a43ffb9574517c8a..61dfe55e99ad352a5ecaa450085bf7ee9d9eca2e 100644 (file)
@@ -1,3 +1,12 @@
+2014-07-23  Richard Biener  <rguenther@suse.de>
+
+       * params.def (PARAM_MAX_COMBINE_INSNS): New.
+       * combine.c: Include statistics.h and params.h.
+       (combine_instructions): Guard three and four insn combines
+       with max-combine-insns value.  Record statistics for combines
+       performed.
+       * doc/invoke.texi (max-combine-insns): Document new param.
+
 2014-07-23  Roman Gareev  <gareevroman@gmail.com>
 
        * graphite-isl-ast-to-gimple.c:
index d44b411b27cab251a6ef8ac1c3107a1cd6ec9a4b..53ac1d6cca05d15daae7a534d2817a6b42296a36 100644 (file)
@@ -104,6 +104,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "valtrack.h"
 #include "cgraph.h"
 #include "obstack.h"
+#include "statistics.h"
+#include "params.h"
 
 /* Number of attempts to combine instructions in this function.  */
 
@@ -1209,6 +1211,7 @@ combine_instructions (rtx f, unsigned int nregs)
   init_reg_last ();
   setup_incoming_promotions (first);
   last_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
+  int max_combine = PARAM_VALUE (PARAM_MAX_COMBINE_INSNS);
 
   FOR_EACH_BB_FN (this_basic_block, cfun)
     {
@@ -1229,218 +1232,246 @@ combine_instructions (rtx f, unsigned int nregs)
           insn = next ? next : NEXT_INSN (insn))
        {
          next = 0;
-         if (NONDEBUG_INSN_P (insn))
-           {
-             while (last_combined_insn
-                    && INSN_DELETED_P (last_combined_insn))
-               last_combined_insn = PREV_INSN (last_combined_insn);
-             if (last_combined_insn == NULL_RTX
-                 || BARRIER_P (last_combined_insn)
-                 || BLOCK_FOR_INSN (last_combined_insn) != this_basic_block
-                 || DF_INSN_LUID (last_combined_insn) <= DF_INSN_LUID (insn))
-               last_combined_insn = insn;
-
-             /* See if we know about function return values before this
-                insn based upon SUBREG flags.  */
-             check_promoted_subreg (insn, PATTERN (insn));
-
-             /* See if we can find hardregs and subreg of pseudos in
-                narrower modes.  This could help turning TRUNCATEs
-                into SUBREGs.  */
-             note_uses (&PATTERN (insn), record_truncated_values, NULL);
-
-             /* Try this insn with each insn it links back to.  */
-
-             FOR_EACH_LOG_LINK (links, insn)
-               if ((next = try_combine (insn, links->insn, NULL_RTX,
-                                        NULL_RTX, &new_direct_jump_p,
-                                        last_combined_insn)) != 0)
-                 goto retry;
+         if (!NONDEBUG_INSN_P (insn))
+           continue;
+
+         while (last_combined_insn
+                && INSN_DELETED_P (last_combined_insn))
+           last_combined_insn = PREV_INSN (last_combined_insn);
+         if (last_combined_insn == NULL_RTX
+             || BARRIER_P (last_combined_insn)
+             || BLOCK_FOR_INSN (last_combined_insn) != this_basic_block
+             || DF_INSN_LUID (last_combined_insn) <= DF_INSN_LUID (insn))
+           last_combined_insn = insn;
+
+         /* See if we know about function return values before this
+            insn based upon SUBREG flags.  */
+         check_promoted_subreg (insn, PATTERN (insn));
+
+         /* See if we can find hardregs and subreg of pseudos in
+            narrower modes.  This could help turning TRUNCATEs
+            into SUBREGs.  */
+         note_uses (&PATTERN (insn), record_truncated_values, NULL);
+
+         /* Try this insn with each insn it links back to.  */
+
+         FOR_EACH_LOG_LINK (links, insn)
+           if ((next = try_combine (insn, links->insn, NULL_RTX,
+                                    NULL_RTX, &new_direct_jump_p,
+                                    last_combined_insn)) != 0)
+             {
+               statistics_counter_event (cfun, "two-insn combine", 1);
+               goto retry;
+             }
 
-             /* Try each sequence of three linked insns ending with this one.  */
+         /* Try each sequence of three linked insns ending with this one.  */
 
-             FOR_EACH_LOG_LINK (links, insn)
-               {
-                 rtx link = links->insn;
+         if (max_combine >= 3)
+           FOR_EACH_LOG_LINK (links, insn)
+             {
+               rtx link = links->insn;
 
-                 /* If the linked insn has been replaced by a note, then there
-                    is no point in pursuing this chain any further.  */
-                 if (NOTE_P (link))
-                   continue;
+               /* If the linked insn has been replaced by a note, then there
+                  is no point in pursuing this chain any further.  */
+               if (NOTE_P (link))
+                 continue;
 
-                 FOR_EACH_LOG_LINK (nextlinks, link)
-                   if ((next = try_combine (insn, link, nextlinks->insn,
-                                            NULL_RTX, &new_direct_jump_p,
-                                            last_combined_insn)) != 0)
+               FOR_EACH_LOG_LINK (nextlinks, link)
+                 if ((next = try_combine (insn, link, nextlinks->insn,
+                                          NULL_RTX, &new_direct_jump_p,
+                                          last_combined_insn)) != 0)
+                   {
+                     statistics_counter_event (cfun, "three-insn combine", 1);
                      goto retry;
-               }
+                   }
+             }
 
 #ifdef HAVE_cc0
-             /* Try to combine a jump insn that uses CC0
-                with a preceding insn that sets CC0, and maybe with its
-                logical predecessor as well.
-                This is how we make decrement-and-branch insns.
-                We need this special code because data flow connections
-                via CC0 do not get entered in LOG_LINKS.  */
-
-             if (JUMP_P (insn)
-                 && (prev = prev_nonnote_insn (insn)) != 0
-                 && NONJUMP_INSN_P (prev)
-                 && sets_cc0_p (PATTERN (prev)))
-               {
-                 if ((next = try_combine (insn, prev, NULL_RTX, NULL_RTX,
-                                          &new_direct_jump_p,
+         /* Try to combine a jump insn that uses CC0
+            with a preceding insn that sets CC0, and maybe with its
+            logical predecessor as well.
+            This is how we make decrement-and-branch insns.
+            We need this special code because data flow connections
+            via CC0 do not get entered in LOG_LINKS.  */
+
+         if (JUMP_P (insn)
+             && (prev = prev_nonnote_insn (insn)) != 0
+             && NONJUMP_INSN_P (prev)
+             && sets_cc0_p (PATTERN (prev)))
+           {
+             if ((next = try_combine (insn, prev, NULL_RTX, NULL_RTX,
+                                      &new_direct_jump_p,
+                                      last_combined_insn)) != 0)
+               goto retry;
+
+             FOR_EACH_LOG_LINK (nextlinks, prev)
+                 if ((next = try_combine (insn, prev, nextlinks->insn,
+                                          NULL_RTX, &new_direct_jump_p,
                                           last_combined_insn)) != 0)
                    goto retry;
+           }
 
-                 FOR_EACH_LOG_LINK (nextlinks, prev)
-                   if ((next = try_combine (insn, prev, nextlinks->insn,
-                                            NULL_RTX, &new_direct_jump_p,
-                                            last_combined_insn)) != 0)
-                     goto retry;
-               }
+         /* Do the same for an insn that explicitly references CC0.  */
+         if (NONJUMP_INSN_P (insn)
+             && (prev = prev_nonnote_insn (insn)) != 0
+             && NONJUMP_INSN_P (prev)
+             && sets_cc0_p (PATTERN (prev))
+             && GET_CODE (PATTERN (insn)) == SET
+             && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
+           {
+             if ((next = try_combine (insn, prev, NULL_RTX, NULL_RTX,
+                                      &new_direct_jump_p,
+                                      last_combined_insn)) != 0)
+               goto retry;
 
-             /* Do the same for an insn that explicitly references CC0.  */
-             if (NONJUMP_INSN_P (insn)
-                 && (prev = prev_nonnote_insn (insn)) != 0
-                 && NONJUMP_INSN_P (prev)
-                 && sets_cc0_p (PATTERN (prev))
-                 && GET_CODE (PATTERN (insn)) == SET
-                 && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
-               {
-                 if ((next = try_combine (insn, prev, NULL_RTX, NULL_RTX,
-                                          &new_direct_jump_p,
+             FOR_EACH_LOG_LINK (nextlinks, prev)
+                 if ((next = try_combine (insn, prev, nextlinks->insn,
+                                          NULL_RTX, &new_direct_jump_p,
                                           last_combined_insn)) != 0)
                    goto retry;
+           }
 
-                 FOR_EACH_LOG_LINK (nextlinks, prev)
-                   if ((next = try_combine (insn, prev, nextlinks->insn,
-                                            NULL_RTX, &new_direct_jump_p,
-                                            last_combined_insn)) != 0)
-                     goto retry;
-               }
-
-             /* Finally, see if any of the insns that this insn links to
-                explicitly references CC0.  If so, try this insn, that insn,
-                and its predecessor if it sets CC0.  */
-             FOR_EACH_LOG_LINK (links, insn)
-               if (NONJUMP_INSN_P (links->insn)
-                   && GET_CODE (PATTERN (links->insn)) == SET
-                   && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (links->insn)))
-                   && (prev = prev_nonnote_insn (links->insn)) != 0
-                   && NONJUMP_INSN_P (prev)
-                   && sets_cc0_p (PATTERN (prev))
-                   && (next = try_combine (insn, links->insn,
-                                           prev, NULL_RTX, &new_direct_jump_p,
-                                           last_combined_insn)) != 0)
-                 goto retry;
+         /* Finally, see if any of the insns that this insn links to
+            explicitly references CC0.  If so, try this insn, that insn,
+            and its predecessor if it sets CC0.  */
+         FOR_EACH_LOG_LINK (links, insn)
+             if (NONJUMP_INSN_P (links->insn)
+                 && GET_CODE (PATTERN (links->insn)) == SET
+                 && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (links->insn)))
+                 && (prev = prev_nonnote_insn (links->insn)) != 0
+                 && NONJUMP_INSN_P (prev)
+                 && sets_cc0_p (PATTERN (prev))
+                 && (next = try_combine (insn, links->insn,
+                                         prev, NULL_RTX, &new_direct_jump_p,
+                                         last_combined_insn)) != 0)
+               goto retry;
 #endif
 
-             /* Try combining an insn with two different insns whose results it
-                uses.  */
-             FOR_EACH_LOG_LINK (links, insn)
-               for (nextlinks = links->next; nextlinks;
-                    nextlinks = nextlinks->next)
-                 if ((next = try_combine (insn, links->insn,
-                                          nextlinks->insn, NULL_RTX,
-                                          &new_direct_jump_p,
-                                          last_combined_insn)) != 0)
+         /* Try combining an insn with two different insns whose results it
+            uses.  */
+         if (max_combine >= 3)
+           FOR_EACH_LOG_LINK (links, insn)
+             for (nextlinks = links->next; nextlinks;
+                  nextlinks = nextlinks->next)
+               if ((next = try_combine (insn, links->insn,
+                                        nextlinks->insn, NULL_RTX,
+                                        &new_direct_jump_p,
+                                        last_combined_insn)) != 0)
+
+                 {
+                   statistics_counter_event (cfun, "three-insn combine", 1);
                    goto retry;
+                 }
 
-             /* Try four-instruction combinations.  */
-             FOR_EACH_LOG_LINK (links, insn)
-               {
-                 struct insn_link *next1;
-                 rtx link = links->insn;
+         /* Try four-instruction combinations.  */
+         if (max_combine >= 4)
+           FOR_EACH_LOG_LINK (links, insn)
+             {
+               struct insn_link *next1;
+               rtx link = links->insn;
 
-                 /* If the linked insn has been replaced by a note, then there
-                    is no point in pursuing this chain any further.  */
-                 if (NOTE_P (link))
-                   continue;
+               /* If the linked insn has been replaced by a note, then there
+                  is no point in pursuing this chain any further.  */
+               if (NOTE_P (link))
+                 continue;
 
-                 FOR_EACH_LOG_LINK (next1, link)
-                   {
-                     rtx link1 = next1->insn;
-                     if (NOTE_P (link1))
-                       continue;
-                     /* I0 -> I1 -> I2 -> I3.  */
-                     FOR_EACH_LOG_LINK (nextlinks, link1)
-                       if ((next = try_combine (insn, link, link1,
-                                                nextlinks->insn,
-                                                &new_direct_jump_p,
-                                                last_combined_insn)) != 0)
+               FOR_EACH_LOG_LINK (next1, link)
+                 {
+                   rtx link1 = next1->insn;
+                   if (NOTE_P (link1))
+                     continue;
+                   /* I0 -> I1 -> I2 -> I3.  */
+                   FOR_EACH_LOG_LINK (nextlinks, link1)
+                     if ((next = try_combine (insn, link, link1,
+                                              nextlinks->insn,
+                                              &new_direct_jump_p,
+                                              last_combined_insn)) != 0)
+                       {
+                         statistics_counter_event (cfun, "four-insn combine", 1);
                          goto retry;
-                     /* I0, I1 -> I2, I2 -> I3.  */
-                     for (nextlinks = next1->next; nextlinks;
-                          nextlinks = nextlinks->next)
-                       if ((next = try_combine (insn, link, link1,
-                                                nextlinks->insn,
-                                                &new_direct_jump_p,
-                                                last_combined_insn)) != 0)
+                       }
+                   /* I0, I1 -> I2, I2 -> I3.  */
+                   for (nextlinks = next1->next; nextlinks;
+                        nextlinks = nextlinks->next)
+                     if ((next = try_combine (insn, link, link1,
+                                              nextlinks->insn,
+                                              &new_direct_jump_p,
+                                              last_combined_insn)) != 0)
+                       {
+                         statistics_counter_event (cfun, "four-insn combine", 1);
                          goto retry;
-                   }
+                       }
+                 }
 
-                 for (next1 = links->next; next1; next1 = next1->next)
-                   {
-                     rtx link1 = next1->insn;
-                     if (NOTE_P (link1))
-                       continue;
-                     /* I0 -> I2; I1, I2 -> I3.  */
-                     FOR_EACH_LOG_LINK (nextlinks, link)
-                       if ((next = try_combine (insn, link, link1,
-                                                nextlinks->insn,
-                                                &new_direct_jump_p,
-                                                last_combined_insn)) != 0)
+               for (next1 = links->next; next1; next1 = next1->next)
+                 {
+                   rtx link1 = next1->insn;
+                   if (NOTE_P (link1))
+                     continue;
+                   /* I0 -> I2; I1, I2 -> I3.  */
+                   FOR_EACH_LOG_LINK (nextlinks, link)
+                     if ((next = try_combine (insn, link, link1,
+                                              nextlinks->insn,
+                                              &new_direct_jump_p,
+                                              last_combined_insn)) != 0)
+                       {
+                         statistics_counter_event (cfun, "four-insn combine", 1);
                          goto retry;
-                     /* I0 -> I1; I1, I2 -> I3.  */
-                     FOR_EACH_LOG_LINK (nextlinks, link1)
-                       if ((next = try_combine (insn, link, link1,
-                                                nextlinks->insn,
-                                                &new_direct_jump_p,
-                                                last_combined_insn)) != 0)
+                       }
+                   /* I0 -> I1; I1, I2 -> I3.  */
+                   FOR_EACH_LOG_LINK (nextlinks, link1)
+                     if ((next = try_combine (insn, link, link1,
+                                              nextlinks->insn,
+                                              &new_direct_jump_p,
+                                              last_combined_insn)) != 0)
+                       {
+                         statistics_counter_event (cfun, "four-insn combine", 1);
                          goto retry;
-                   }
-               }
+                       }
+                 }
+             }
 
-             /* Try this insn with each REG_EQUAL note it links back to.  */
-             FOR_EACH_LOG_LINK (links, insn)
+         /* Try this insn with each REG_EQUAL note it links back to.  */
+         FOR_EACH_LOG_LINK (links, insn)
+           {
+             rtx set, note;
+             rtx temp = links->insn;
+             if ((set = single_set (temp)) != 0
+                 && (note = find_reg_equal_equiv_note (temp)) != 0
+                 && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
+                 /* Avoid using a register that may already been marked
+                    dead by an earlier instruction.  */
+                 && ! unmentioned_reg_p (note, SET_SRC (set))
+                 && (GET_MODE (note) == VOIDmode
+                     ? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))
+                     : GET_MODE (SET_DEST (set)) == GET_MODE (note)))
                {
-                 rtx set, note;
-                 rtx temp = links->insn;
-                 if ((set = single_set (temp)) != 0
-                     && (note = find_reg_equal_equiv_note (temp)) != 0
-                     && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
-                     /* Avoid using a register that may already been marked
-                        dead by an earlier instruction.  */
-                     && ! unmentioned_reg_p (note, SET_SRC (set))
-                     && (GET_MODE (note) == VOIDmode
-                         ? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))
-                         : GET_MODE (SET_DEST (set)) == GET_MODE (note)))
+                 /* Temporarily replace the set's source with the
+                    contents of the REG_EQUAL note.  The insn will
+                    be deleted or recognized by try_combine.  */
+                 rtx orig = SET_SRC (set);
+                 SET_SRC (set) = note;
+                 i2mod = temp;
+                 i2mod_old_rhs = copy_rtx (orig);
+                 i2mod_new_rhs = copy_rtx (note);
+                 next = try_combine (insn, i2mod, NULL_RTX, NULL_RTX,
+                                     &new_direct_jump_p,
+                                     last_combined_insn);
+                 i2mod = NULL_RTX;
+                 if (next)
                    {
-                     /* Temporarily replace the set's source with the
-                        contents of the REG_EQUAL note.  The insn will
-                        be deleted or recognized by try_combine.  */
-                     rtx orig = SET_SRC (set);
-                     SET_SRC (set) = note;
-                     i2mod = temp;
-                     i2mod_old_rhs = copy_rtx (orig);
-                     i2mod_new_rhs = copy_rtx (note);
-                     next = try_combine (insn, i2mod, NULL_RTX, NULL_RTX,
-                                         &new_direct_jump_p,
-                                         last_combined_insn);
-                     i2mod = NULL_RTX;
-                     if (next)
-                       goto retry;
-                     SET_SRC (set) = orig;
+                     statistics_counter_event (cfun, "insn-with-note combine", 1);
+                     goto retry;
                    }
+                 SET_SRC (set) = orig;
                }
+           }
 
-             if (!NOTE_P (insn))
-               record_dead_and_set_regs (insn);
+         if (!NOTE_P (insn))
+           record_dead_and_set_regs (insn);
 
-           retry:
-             ;
-           }
+retry:
+         ;
        }
     }
 
index b5e8d98631d49f7206ca50694a77578dbedcb937..fc2d78a055602007e487a1e7740e9592720a4643 100644 (file)
@@ -10006,6 +10006,10 @@ The maximum size measured as number of RTLs that can be recorded in an expressio
 in combiner for a pseudo register as last known value of that register.  The default
 is 10000.
 
+@item max-combine-insns
+The maximum number of instructions the RTL combiner tries to combine.
+The default value is 2 at @option{-Og} and 4 otherwise.
+
 @item integer-share-limit
 Small integer constants can use a shared data structure, reducing the
 compiler's memory usage and increasing its speed.  This sets the maximum
index aa1e88dd8d1c6fabc393bdc9bb809508323bb0c3..595a093a88c78783e29e41a3c822a7635fef4eb8 100644 (file)
@@ -673,6 +673,11 @@ DEFPARAM(PARAM_MAX_LAST_VALUE_RTL,
         "The maximum number of RTL nodes that can be recorded as combiner's last value",
         10000, 0, 0)
 
+DEFPARAM(PARAM_MAX_COMBINE_INSNS,
+        "max-combine-insns",
+        "The maximum number of insns combine tries to combine",
+        4, 2, 4)
+
 /* INTEGER_CST nodes are shared for values [{-1,0} .. N) for
    {signed,unsigned} integral types.  This determines N.
    Experimentation shows 251 to be a good value that generates the