rtl.h (replace_label_data): Delete.
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 28 Aug 2014 06:24:27 +0000 (06:24 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 28 Aug 2014 06:24:27 +0000 (06:24 +0000)
gcc/
* rtl.h (replace_label_data): Delete.
(replace_label): Take the old label, new label and update-nuses flag
as direct arguments.  Return void.
* cfgcleanup.c (outgoing_edges_match): Update accordingly.
* rtlanal.c (replace_label): Update interface as above.  Handle
JUMP_TABLE_DATA as a special case.  Handle JUMPs outside the
iterator.  Use FOR_EACH_SUBRTX_PTR.

From-SVN: r214655

gcc/ChangeLog
gcc/cfgcleanup.c
gcc/rtl.h
gcc/rtlanal.c

index 9481150135bb8c2887138e86d4b97fc0a8c84586..57a30853dc49db4df88ccd5e9185698039bb3dc0 100644 (file)
@@ -1,3 +1,13 @@
+2014-08-28  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * rtl.h (replace_label_data): Delete.
+       (replace_label): Take the old label, new label and update-nuses flag
+       as direct arguments.  Return void.
+       * cfgcleanup.c (outgoing_edges_match): Update accordingly.
+       * rtlanal.c (replace_label): Update interface as above.  Handle
+       JUMP_TABLE_DATA as a special case.  Handle JUMPs outside the
+       iterator.  Use FOR_EACH_SUBRTX_PTR.
+
 2014-08-28  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * rtl.h (get_pool_constant, rtx_referenced_p): Replace rtx parameters
index 7dfed098eaf868d4e6b35286d8732e6ae669ab51..a00816887535fc338816506c252e0f55379d7f26 100644 (file)
@@ -1719,15 +1719,11 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
 
              if (identical)
                {
-                 replace_label_data rr;
                  bool match;
 
                  /* Temporarily replace references to LABEL1 with LABEL2
                     in BB1->END so that we could compare the instructions.  */
-                 rr.r1 = label1;
-                 rr.r2 = label2;
-                 rr.update_label_nuses = false;
-                 for_each_rtx_in_insn (&BB_END (bb1), replace_label, &rr);
+                 replace_label_in_insn (BB_END (bb1), label1, label2, false);
 
                  match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2))
                           == dir_both);
@@ -1739,9 +1735,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
                  /* Set the original label in BB1->END because when deleting
                     a block whose end is a tablejump, the tablejump referenced
                     from the instruction is deleted too.  */
-                 rr.r1 = label2;
-                 rr.r2 = label1;
-                 for_each_rtx_in_insn (&BB_END (bb1), replace_label, &rr);
+                 replace_label_in_insn (BB_END (bb1), label2, label1, false);
 
                  return match;
                }
@@ -1988,20 +1982,16 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
          && tablejump_p (BB_END (osrc2), &label2, &table2)
          && label1 != label2)
        {
-         replace_label_data rr;
          rtx_insn *insn;
 
          /* Replace references to LABEL1 with LABEL2.  */
-         rr.r1 = label1;
-         rr.r2 = label2;
-         rr.update_label_nuses = true;
          for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
            {
              /* Do not replace the label in SRC1->END because when deleting
                 a block whose end is a tablejump, the tablejump referenced
                 from the instruction is deleted too.  */
              if (insn != BB_END (osrc1))
-               for_each_rtx_in_insn (&insn, replace_label, &rr);
+               replace_label_in_insn (insn, label1, label2, true);
            }
        }
     }
index 925c384c63a6142edbbd9bb3f2a35441f2ff873c..9d27256f42c31548744c55577e6f10492417b0c7 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2723,14 +2723,6 @@ extern void set_insn_deleted (rtx);
                       : NULL_RTX)
 #define single_set_1(I) single_set_2 (I, PATTERN (I))
 
-/* Structure used for passing data to REPLACE_LABEL.  */
-struct replace_label_data
-{
-  rtx r1;
-  rtx r2;
-  bool update_label_nuses;
-};
-
 extern enum machine_mode get_address_mode (rtx mem);
 extern int rtx_addr_can_trap_p (const_rtx);
 extern bool nonzero_address_p (const_rtx);
@@ -2799,7 +2791,8 @@ extern void copy_reg_eh_region_note_forward (rtx, rtx, rtx);
 extern void copy_reg_eh_region_note_backward (rtx, rtx, rtx);
 extern int inequality_comparisons_p (const_rtx);
 extern rtx replace_rtx (rtx, rtx, rtx);
-extern int replace_label (rtx *, void *);
+extern void replace_label (rtx *, rtx, rtx, bool);
+extern void replace_label_in_insn (rtx_insn *, rtx, rtx, bool);
 extern bool rtx_referenced_p (const_rtx, const_rtx);
 extern bool tablejump_p (const_rtx, rtx *, rtx_jump_table_data **);
 extern int computed_jump_p (const_rtx);
index 0e80426391fc482ea412878dae3e174ff4d011e8..f1cb2246d7d7bbfce4eb21bbadd9db7fa6baba09 100644 (file)
@@ -2770,65 +2770,88 @@ replace_rtx (rtx x, rtx from, rtx to)
   return x;
 }
 \f
-/* Replace occurrences of the old label in *X with the new one.
-   DATA is a REPLACE_LABEL_DATA containing the old and new labels.  */
+/* Replace occurrences of the OLD_LABEL in *LOC with NEW_LABEL.  Also track
+   the change in LABEL_NUSES if UPDATE_LABEL_NUSES.  */
 
-int
-replace_label (rtx *x, void *data)
+void
+replace_label (rtx *loc, rtx old_label, rtx new_label, bool update_label_nuses)
 {
-  rtx l = *x;
-  rtx old_label = ((replace_label_data *) data)->r1;
-  rtx new_label = ((replace_label_data *) data)->r2;
-  bool update_label_nuses = ((replace_label_data *) data)->update_label_nuses;
-
-  if (l == NULL_RTX)
-    return 0;
-
-  if (GET_CODE (l) == SYMBOL_REF
-      && CONSTANT_POOL_ADDRESS_P (l))
+  /* Handle jump tables specially, since ADDR_{DIFF_,}VECs can be long.  */
+  rtx x = *loc;
+  if (JUMP_TABLE_DATA_P (x))
     {
-      rtx c = get_pool_constant (l);
-      if (rtx_referenced_p (old_label, c))
+      x = PATTERN (x);
+      rtvec vec = XVEC (x, GET_CODE (x) == ADDR_DIFF_VEC);
+      int len = GET_NUM_ELEM (vec);
+      for (int i = 0; i < len; ++i)
        {
-         rtx new_c, new_l;
-         replace_label_data *d = (replace_label_data *) data;
-
-         /* Create a copy of constant C; replace the label inside
-            but do not update LABEL_NUSES because uses in constant pool
-            are not counted.  */
-         new_c = copy_rtx (c);
-         d->update_label_nuses = false;
-         for_each_rtx (&new_c, replace_label, data);
-         d->update_label_nuses = update_label_nuses;
-
-         /* Add the new constant NEW_C to constant pool and replace
-            the old reference to constant by new reference.  */
-         new_l = XEXP (force_const_mem (get_pool_mode (l), new_c), 0);
-         *x = replace_rtx (l, l, new_l);
+         rtx ref = RTVEC_ELT (vec, i);
+         if (XEXP (ref, 0) == old_label)
+           {
+             XEXP (ref, 0) = new_label;
+             if (update_label_nuses)
+               {
+                 ++LABEL_NUSES (new_label);
+                 --LABEL_NUSES (old_label);
+               }
+           }
        }
-      return 0;
+      return;
     }
 
   /* If this is a JUMP_INSN, then we also need to fix the JUMP_LABEL
-     field.  This is not handled by for_each_rtx because it doesn't
+     field.  This is not handled by the iterator because it doesn't
      handle unprinted ('0') fields.  */
-  if (JUMP_P (l) && JUMP_LABEL (l) == old_label)
-    JUMP_LABEL (l) = new_label;
+  if (JUMP_P (x) && JUMP_LABEL (x) == old_label)
+    JUMP_LABEL (x) = new_label;
 
-  if ((GET_CODE (l) == LABEL_REF
-       || GET_CODE (l) == INSN_LIST)
-      && XEXP (l, 0) == old_label)
+  subrtx_ptr_iterator::array_type array;
+  FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
     {
-      XEXP (l, 0) = new_label;
-      if (update_label_nuses)
+      rtx *loc = *iter;
+      if (rtx x = *loc)
        {
-         ++LABEL_NUSES (new_label);
-         --LABEL_NUSES (old_label);
+         if (GET_CODE (x) == SYMBOL_REF
+             && CONSTANT_POOL_ADDRESS_P (x))
+           {
+             rtx c = get_pool_constant (x);
+             if (rtx_referenced_p (old_label, c))
+               {
+                 /* Create a copy of constant C; replace the label inside
+                    but do not update LABEL_NUSES because uses in constant pool
+                    are not counted.  */
+                 rtx new_c = copy_rtx (c);
+                 replace_label (&new_c, old_label, new_label, false);
+
+                 /* Add the new constant NEW_C to constant pool and replace
+                    the old reference to constant by new reference.  */
+                 rtx new_mem = force_const_mem (get_pool_mode (x), new_c);
+                 *loc = replace_rtx (x, x, XEXP (new_mem, 0));
+               }
+           }
+
+         if ((GET_CODE (x) == LABEL_REF
+              || GET_CODE (x) == INSN_LIST)
+             && XEXP (x, 0) == old_label)
+           {
+             XEXP (x, 0) = new_label;
+             if (update_label_nuses)
+               {
+                 ++LABEL_NUSES (new_label);
+                 --LABEL_NUSES (old_label);
+               }
+           }
        }
-      return 0;
     }
+}
 
-  return 0;
+void
+replace_label_in_insn (rtx_insn *insn, rtx old_label, rtx new_label,
+                      bool update_label_nuses)
+{
+  rtx insn_as_rtx = insn;
+  replace_label (&insn_as_rtx, old_label, new_label, update_label_nuses);
+  gcc_checking_assert (insn_as_rtx == insn);
 }
 
 /* Return true if X is referenced in BODY.  */