[LRA] Don't make eliminable registers live (PR91957)
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 2 Oct 2019 07:37:10 +0000 (07:37 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 2 Oct 2019 07:37:10 +0000 (07:37 +0000)
One effect of https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00802.html
was to strengthen the sanity check in lra_assigns so that it checks
whether reg_renumber is consistent with the whole conflict set.
This duly tripped on csky for a pseudo that had been allocated
to the eliminated frame pointer.  (csky doesn't have a separate
hard frame pointer.)

lra-lives uses:

/* Set of hard regs (except eliminable ones) currently live.  */
static HARD_REG_SET hard_regs_live;

to track the set of live directly-referenced hard registers, and it
correctly implements the exclusion when setting up the initial set:

  hard_regs_live &= ~eliminable_regset;

But later calls to make_hard_regno_live and make_hard_regno_dead
would process eliminable registers like other registers, recording
conflicts for them and potentially making them live.  (Note that
after r266086, make_hard_regno_dead adds conflicts for registers
that are already marked dead.)  I think this would have had the
effect of pessimising targets without a separate hard frame pointer.

2019-10-02  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR middle-end/91957
* lra-lives.c (make_hard_regno_dead): Don't record conflicts for
eliminable registers.
(make_hard_regno_live): Likewise, and don't make them live.

From-SVN: r276440

gcc/ChangeLog
gcc/lra-lives.c

index b3a42ae4ef2008606f1f7c77aa1fe193a6ada75a..69f5d7153c9f623c54a984e863e15f1038225981 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-02  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR middle-end/91957
+       * lra-lives.c (make_hard_regno_dead): Don't record conflicts for
+       eliminable registers.
+       (make_hard_regno_live): Likewise, and don't make them live.
+
 2019-10-01  David Malcolm  <dmalcolm@redhat.com>
 
        * diagnostic-show-locus.c (layout::print_gap_in_line_numbering):
index 389a79d701dab5f7da566c3c62a2a9e5d75d7e1b..1d1525ca2e541c105cbe2ee0254d6e3d1043c04b 100644 (file)
@@ -281,7 +281,8 @@ static void
 make_hard_regno_live (int regno)
 {
   lra_assert (HARD_REGISTER_NUM_P (regno));
-  if (TEST_HARD_REG_BIT (hard_regs_live, regno))
+  if (TEST_HARD_REG_BIT (hard_regs_live, regno)
+      || TEST_HARD_REG_BIT (eliminable_regset, regno))
     return;
   SET_HARD_REG_BIT (hard_regs_live, regno);
   sparseset_set_bit (start_living, regno);
@@ -295,6 +296,9 @@ make_hard_regno_live (int regno)
 static void
 make_hard_regno_dead (int regno)
 {
+  if (TEST_HARD_REG_BIT (eliminable_regset, regno))
+    return;
+
   lra_assert (HARD_REGISTER_NUM_P (regno));
   unsigned int i;
   EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i)