Don't double-count early-clobber matches.
authorAndrew Stubbs <ams@codesourcery.com>
Mon, 22 Oct 2018 14:23:37 +0000 (14:23 +0000)
committerAndrew Stubbs <ams@gcc.gnu.org>
Mon, 22 Oct 2018 14:23:37 +0000 (14:23 +0000)
Given a pattern with a number of operands:

(match_operand 0 "" "=&v")
(match_operand 1 "" " v0")
(match_operand 2 "" " v0")
(match_operand 3 "" " v0")

GCC will currently increment "reject" once, for operand 0, and then decrement
it once for each of the other operands, ending with reject == -2 and an
assertion failure.  If there's a conflict then it might try to decrement reject
yet again.

Incidentally, what these patterns are trying to achieve is an allocation in
which operand 0 may match one of the other operands, but may not partially
overlap any of them.  Ideally there'd be a better way to do this.

In any case, it will affect any pattern in which multiple operands may (or
must) match an early-clobber operand.

The patch only allows a reject-- when one has not already occurred, for that
operand.

2018-10-22  Andrew Stubbs  <ams@codesourcery.com>

gcc/
* lra-constraints.c (process_alt_operands): New local array,
matching_early_clobber.  Check matching_early_clobber before
decrementing reject, and set matching_early_clobber after.

From-SVN: r265393

gcc/ChangeLog
gcc/lra-constraints.c

index d799af2aa2a632373d849a02369cbefc70cae3a2..6c05108197191352fe3933fcf7243dfd1c77fc91 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-22  Andrew Stubbs  <ams@codesourcery.com>
+
+       * lra-constraints.c (process_alt_operands): New local array,
+       matching_early_clobber.  Check matching_early_clobber before
+       decrementing reject, and set matching_early_clobber after.
+
 2018-10-22  Segher Boessenkool  <segher@kernel.crashing.org>
 
        PR target/87598
index 3cbe0465a87d54c5d142e84c398d950efbbb7390..ab61989734d419e28d27b5d2412dec0f9a34fd2d 100644 (file)
@@ -1969,6 +1969,7 @@ process_alt_operands (int only_alternative)
       if (!TEST_BIT (preferred, nalt))
        continue;
 
+      bool matching_early_clobber[MAX_RECOG_OPERANDS];
       curr_small_class_check++;
       overall = losers = addr_losers = 0;
       static_reject = reject = reload_nregs = reload_sum = 0;
@@ -1980,6 +1981,7 @@ process_alt_operands (int only_alternative)
            fprintf (lra_dump_file,
                     "            Staticly defined alt reject+=%d\n", inc);
          static_reject += inc;
+         matching_early_clobber[nop] = 0;
        }
       reject += static_reject;
       early_clobbered_regs_num = 0;
@@ -2175,7 +2177,11 @@ process_alt_operands (int only_alternative)
                                 "            %d Matching earlyclobber alt:"
                                 " reject--\n",
                                 nop);
-                           reject--;
+                           if (!matching_early_clobber[m])
+                             {
+                               reject--;
+                               matching_early_clobber[m] = 1;
+                             }
                          }
                        /* Otherwise we prefer no matching
                           alternatives because it gives more freedom
@@ -2921,15 +2927,11 @@ process_alt_operands (int only_alternative)
              curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++]
                = last_conflict_j;
              losers++;
-             /* Early clobber was already reflected in REJECT. */
-             lra_assert (reject > 0);
              if (lra_dump_file != NULL)
                fprintf
                  (lra_dump_file,
                   "            %d Conflict early clobber reload: reject--\n",
                   i);
-             reject--;
-             overall += LRA_LOSER_COST_FACTOR - 1;
            }
          else
            {
@@ -2953,17 +2955,21 @@ process_alt_operands (int only_alternative)
                }
              curr_alt_win[i] = curr_alt_match_win[i] = false;
              losers++;
-             /* Early clobber was already reflected in REJECT. */
-             lra_assert (reject > 0);
              if (lra_dump_file != NULL)
                fprintf
                  (lra_dump_file,
                   "            %d Matched conflict early clobber reloads: "
                   "reject--\n",
                   i);
+           }
+         /* Early clobber was already reflected in REJECT. */
+         if (!matching_early_clobber[i])
+           {
+             lra_assert (reject > 0);
              reject--;
-             overall += LRA_LOSER_COST_FACTOR - 1;
+             matching_early_clobber[i] = 1;
            }
+         overall += LRA_LOSER_COST_FACTOR - 1;
        }
       if (lra_dump_file != NULL)
        fprintf (lra_dump_file, "          alt=%d,overall=%d,losers=%d,rld_nregs=%d\n",