re PR rtl-optimization/80818 (LRA clobbers live hard reg clobbered during remateriali...
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 29 Nov 2017 22:19:25 +0000 (22:19 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 29 Nov 2017 22:19:25 +0000 (22:19 +0000)
2017-11-29  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/80818
* lra.c (collect_non_operand_hard_regs): New arg insn.  Pass it
recursively.  Use insn code for clobber.
(lra_set_insn_recog_data): Pass the new arg to
collect_non_operand_hard_regs.
(add_regs_to_insn_regno_info): Pass insn instead of uid.  Use insn
code for clobber.
(lra_update_insn_regno_info): Pass insn to
add_regs_to_insn_regno_info.

From-SVN: r255258

gcc/ChangeLog
gcc/lra.c

index 877a4e8e248b3debd162597baf3279172e54416f..8bc4a063697a7f2e74067d673fee1391800607be 100644 (file)
@@ -1,3 +1,15 @@
+2017-11-29  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/80818
+       * lra.c (collect_non_operand_hard_regs): New arg insn.  Pass it
+       recursively.  Use insn code for clobber.
+       (lra_set_insn_recog_data): Pass the new arg to
+       collect_non_operand_hard_regs.
+       (add_regs_to_insn_regno_info): Pass insn instead of uid.  Use insn
+       code for clobber.
+       (lra_update_insn_regno_info): Pass insn to
+       add_regs_to_insn_regno_info.
+
 2017-11-29  Jim Wilson  <jimw@sifive.com>
            Andrew Waterman  <andrew@sifive.com>
 
index 66fbfd5477b37aabb5af02f80057cd552b93655e..f49c50a40362655431393190b059ade94ac5a2aa 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -807,7 +807,8 @@ setup_operand_alternative (lra_insn_recog_data_t data,
    to LIST.  X is a part of insn given by DATA.         Return the result
    list.  */
 static struct lra_insn_reg *
-collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
+collect_non_operand_hard_regs (rtx_insn *insn, rtx *x,
+                              lra_insn_recog_data_t data,
                               struct lra_insn_reg *list,
                               enum op_type type, bool early_clobber)
 {
@@ -881,25 +882,28 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
   switch (code)
     {
     case SET:
-      list = collect_non_operand_hard_regs (&SET_DEST (op), data,
+      list = collect_non_operand_hard_regs (insn, &SET_DEST (op), data,
                                            list, OP_OUT, false);
-      list = collect_non_operand_hard_regs (&SET_SRC (op), data,
+      list = collect_non_operand_hard_regs (insn, &SET_SRC (op), data,
                                            list, OP_IN, false);
       break;
     case CLOBBER:
-      /* We treat clobber of non-operand hard registers as early
-        clobber (the behavior is expected from asm).  */
-      list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
-                                           list, OP_OUT, true);
-      break;
+      {
+       int code = INSN_CODE (insn);
+       /* We treat clobber of non-operand hard registers as early
+          clobber (the behavior is expected from asm).  */
+       list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
+                                             list, OP_OUT, code < 0);
+       break;
+      }
     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
-      list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
+      list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
                                            list, OP_INOUT, false);
       break;
     case PRE_MODIFY: case POST_MODIFY:
-      list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
+      list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
                                            list, OP_INOUT, false);
-      list = collect_non_operand_hard_regs (&XEXP (op, 1), data,
+      list = collect_non_operand_hard_regs (insn, &XEXP (op, 1), data,
                                            list, OP_IN, false);
       break;
     default:
@@ -907,12 +911,12 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        {
          if (fmt[i] == 'e')
-           list = collect_non_operand_hard_regs (&XEXP (op, i), data,
+           list = collect_non_operand_hard_regs (insn, &XEXP (op, i), data,
                                                  list, OP_IN, false);
          else if (fmt[i] == 'E')
            for (j = XVECLEN (op, i) - 1; j >= 0; j--)
-             list = collect_non_operand_hard_regs (&XVECEXP (op, i, j), data,
-                                                   list, OP_IN, false);
+             list = collect_non_operand_hard_regs (insn, &XVECEXP (op, i, j),
+                                                   data, list, OP_IN, false);
        }
     }
   return list;
@@ -1055,7 +1059,7 @@ lra_set_insn_recog_data (rtx_insn *insn)
     insn_static_data->hard_regs = NULL;
   else
     insn_static_data->hard_regs
-      = collect_non_operand_hard_regs (&PATTERN (insn), data,
+      = collect_non_operand_hard_regs (insn, &PATTERN (insn), data,
                                       NULL, OP_IN, false);
   data->arg_hard_regs = NULL;
   if (CALL_P (insn))
@@ -1402,13 +1406,14 @@ lra_get_copy (int n)
 /* This page contains code dealing with info about registers in
    insns.  */
 
-/* Process X of insn UID recursively and add info (operand type is
+/* Process X of INSN recursively and add info (operand type is
    given by TYPE, flag of that it is early clobber is EARLY_CLOBBER)
    about registers in X to the insn DATA.  If X can be early clobbered,
    alternatives in which it can be early clobbered are given by
    EARLY_CLOBBER_ALTS.  */
 static void
-add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
+add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
+                            rtx_insn *insn,
                             enum op_type type, bool early_clobber,
                             alternative_mask early_clobber_alts)
 {
@@ -1436,7 +1441,7 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
       /* Process all regs even unallocatable ones as we need info about
         all regs for rematerialization pass.  */
       expand_reg_info ();
-      if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid))
+      if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn)))
        {
          data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
                                     early_clobber, early_clobber_alts,
@@ -1471,20 +1476,25 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
   switch (code)
     {
     case SET:
-      add_regs_to_insn_regno_info (data, SET_DEST (x), uid, OP_OUT, false, 0);
-      add_regs_to_insn_regno_info (data, SET_SRC (x), uid, OP_IN, false, 0);
+      add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, false, 0);
+      add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, false, 0);
       break;
     case CLOBBER:
-      /* We treat clobber of non-operand hard registers as early
-        clobber (the behavior is expected from asm).  */
-      add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_OUT, true, ALL_ALTERNATIVES);
-      break;
+      {
+       int code = INSN_CODE (insn);
+
+       /* We treat clobber of non-operand hard registers as early
+          clobber (the behavior is expected from asm).  */
+       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
+                                    code < 0, code < 0 ? ALL_ALTERNATIVES : 0);
+       break;
+      }
     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
-      add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false, 0);
+      add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
       break;
     case PRE_MODIFY: case POST_MODIFY:
-      add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false, 0);
-      add_regs_to_insn_regno_info (data, XEXP (x, 1), uid, OP_IN, false, 0);
+      add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
+      add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, false, 0);
       break;
     default:
       if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
@@ -1505,11 +1515,11 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        {
          if (fmt[i] == 'e')
-           add_regs_to_insn_regno_info (data, XEXP (x, i), uid, type, false, 0);
+           add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, false, 0);
          else if (fmt[i] == 'E')
            {
              for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-               add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), uid,
+               add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn,
                                             type, false, 0);
            }
        }
@@ -1585,7 +1595,7 @@ setup_insn_reg_info (lra_insn_recog_data_t data, int freq)
 void
 lra_update_insn_regno_info (rtx_insn *insn)
 {
-  int i, uid, freq;
+  int i, freq;
   lra_insn_recog_data_t data;
   struct lra_static_insn_data *static_data;
   enum rtx_code code;
@@ -1597,14 +1607,13 @@ lra_update_insn_regno_info (rtx_insn *insn)
   static_data = data->insn_static_data;
   freq = get_insn_freq (insn);
   invalidate_insn_data_regno_info (data, insn, freq);
-  uid = INSN_UID (insn);
   for (i = static_data->n_operands - 1; i >= 0; i--)
-    add_regs_to_insn_regno_info (data, *data->operand_loc[i], uid,
+    add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn,
                                 static_data->operand[i].type,
                                 static_data->operand[i].early_clobber,
                                 static_data->operand[i].early_clobber_alts);
   if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
-    add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), uid,
+    add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn,
                                 code == USE ? OP_IN : OP_OUT, false, 0);
   if (CALL_P (insn))
     /* On some targets call insns can refer to pseudos in memory in
@@ -1616,7 +1625,7 @@ lra_update_insn_regno_info (rtx_insn *insn)
         link = XEXP (link, 1))
       if (((code = GET_CODE (XEXP (link, 0))) == USE || code == CLOBBER)
          && MEM_P (XEXP (XEXP (link, 0), 0)))
-       add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), uid,
+       add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn,
                                     code == USE ? OP_IN : OP_OUT, false, 0);
   if (NONDEBUG_INSN_P (insn))
     setup_insn_reg_info (data, freq);