[rtlanal] Do a better job of costing parallel sets containing flag-setting operations.
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 30 Jun 2017 16:36:57 +0000 (16:36 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 30 Jun 2017 16:36:57 +0000 (16:36 +0000)
Many parallel set insns are of the form of a single set that also sets
the condition code flags.  In this case the cost of such an insn is
normally the cost of the part that doesn't set the flags, since
updating the condition flags is simply a side effect.

At present all such insns are treated as having unknown cost (ie 0)
and combine assumes that such insns are infinitely more expensive than
any other insn sequence with a non-zero cost.

This patch addresses this problem by allowing insn_rtx_cost to ignore
the condition setting part of a PARALLEL iff there is exactly one
comparison set and one non-comparison set.  If the only set operation
is a comparison we still use that as the basis of the insn cost.

* rtlanal.c (insn_rtx_cost): If a parallel contains exactly one
comparison set and one other set, use the cost of the non-comparison
set.

Bootstrapped on aarch64-none-linuxgnu

From-SVN: r249850

gcc/ChangeLog
gcc/rtlanal.c

index 594b2472eaaf25c9a8d5ce440f0b3707d56d812c..e0a9cc009aa38107952ce4b65c4fd1b60d1af66c 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-30  Richard Earnshaw  <rearnsha@arm.com>
+
+       * rtlanal.c (insn_rtx_cost): If a parallel contains exactly one
+       comparison set and one other set, use the cost of the non-comparison
+       set.
+
 2017-06-30  Nathan Sidwell  <nathan@acm.org>
 
        * ggc.h: Replace all 'static inline' with plain 'inline'.  Fix
index bf4183e793dcb07ecdc511b8fdff3560141cf8e8..9bfae8cb9b03d70469cc3b151563284840b3c6d7 100644 (file)
@@ -5263,23 +5263,41 @@ insn_rtx_cost (rtx pat, bool speed)
   int i, cost;
   rtx set;
 
-  /* Extract the single set rtx from the instruction pattern.
-     We can't use single_set since we only have the pattern.  */
+  /* Extract the single set rtx from the instruction pattern.  We
+     can't use single_set since we only have the pattern.  We also
+     consider PARALLELs of a normal set and a single comparison.  In
+     that case we use the cost of the non-comparison SET operation,
+     which is most-likely to be the real cost of this operation.  */
   if (GET_CODE (pat) == SET)
     set = pat;
   else if (GET_CODE (pat) == PARALLEL)
     {
       set = NULL_RTX;
+      rtx comparison = NULL_RTX;
+
       for (i = 0; i < XVECLEN (pat, 0); i++)
        {
          rtx x = XVECEXP (pat, 0, i);
          if (GET_CODE (x) == SET)
            {
-             if (set)
-               return 0;
-             set = x;
+             if (GET_CODE (SET_SRC (x)) == COMPARE)
+               {
+                 if (comparison)
+                   return 0;
+                 comparison = x;
+               }
+             else
+               {
+                 if (set)
+                   return 0;
+                 set = x;
+               }
            }
        }
+
+      if (!set && comparison)
+       set = comparison;
+
       if (!set)
        return 0;
     }