]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cprop.c
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / cprop.c
index e315e53b695fedf562c628028ae8b79889b4f20a..aca319aafa5396766a7dd11d37e95460cabe8549 100644 (file)
@@ -1,5 +1,5 @@
 /* Global constant/copy propagation for RTL.
-   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   Copyright (C) 1997-2021 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -34,7 +34,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfganal.h"
 #include "lcm.h"
 #include "cfgcleanup.h"
-#include "params.h"
 #include "cselib.h"
 #include "intl.h"
 #include "tree-pass.h"
@@ -839,7 +838,7 @@ find_avail_set (int regno, rtx_insn *insn, struct cprop_expr *set_ret[2])
        (set (reg X) (reg Y))
        (set (reg Y) (reg X))
 
-     This can not happen since the set of (reg Y) would have killed the
+     This cannot happen since the set of (reg Y) would have killed the
      set of (reg X) making it unavailable at the start of this block.  */
   while (1)
     {
@@ -964,15 +963,11 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src)
        remove_note (jump, note);
      }
 
-  /* Delete the cc0 setter.  */
-  if (HAVE_cc0 && setcc != NULL && CC0_P (SET_DEST (single_set (setcc))))
-    delete_insn (setcc);
-
   global_const_prop_count++;
   if (dump_file != NULL)
     {
       fprintf (dump_file,
-              "GLOBAL CONST-PROP: Replacing reg %d in jump_insn %d with"
+              "GLOBAL CONST-PROP: Replacing reg %d in jump_insn %d with "
               "constant ", REGNO (from), INSN_UID (jump));
       print_rtl (dump_file, src);
       fprintf (dump_file, "\n");
@@ -1008,16 +1003,18 @@ static int
 constprop_register (rtx from, rtx src, rtx_insn *insn)
 {
   rtx sset;
+  rtx_insn *next_insn;
 
-  /* Check for reg or cc0 setting instructions followed by
-     conditional branch instructions first.  */
+  /* Check for reg setting instructions followed by conditional branch
+     instructions first.  */
   if ((sset = single_set (insn)) != NULL
-      && NEXT_INSN (insn)
-      && any_condjump_p (NEXT_INSN (insn)) && onlyjump_p (NEXT_INSN (insn)))
+      && (next_insn = next_nondebug_insn (insn)) != NULL
+      && any_condjump_p (next_insn)
+      && onlyjump_p (next_insn))
     {
       rtx dest = SET_DEST (sset);
-      if ((REG_P (dest) || CC0_P (dest))
-         && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn),
+      if (REG_P (dest)
+         && cprop_jump (BLOCK_FOR_INSN (insn), insn, next_insn,
                         from, src))
        return 1;
     }
@@ -1161,7 +1158,7 @@ local_cprop_find_used_regs (rtx *xptr, void *data)
       return;
 
     case SUBREG:
-      if (df_read_modify_subreg_p (x))
+      if (read_modify_subreg_p (x))
        return;
       break;
 
@@ -1635,8 +1632,7 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn *jump)
          /* Avoid unification of the edge with other edges from original
             branch.  We would end up emitting the instruction on "both"
             edges.  */
-         if (dest && setcc && !CC0_P (SET_DEST (PATTERN (setcc)))
-             && find_edge (e->src, dest))
+         if (dest && setcc && find_edge (e->src, dest))
            dest = NULL;
 
          old_dest = e->dest;
@@ -1646,13 +1642,11 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn *jump)
             {
              redirect_edge_and_branch_force (e, dest);
 
-             /* Copy the register setter to the redirected edge.
-                Don't copy CC0 setters, as CC0 is dead after jump.  */
+             /* Copy the register setter to the redirected edge.  */
              if (setcc)
                {
                  rtx pat = PATTERN (setcc);
-                 if (!CC0_P (SET_DEST (pat)))
-                   insert_insn_on_edge (copy_insn (pat), e);
+                 insert_insn_on_edge (copy_insn (pat), e);
                }
 
              if (dump_file != NULL)
@@ -1718,7 +1712,7 @@ bypass_conditional_jumps (void)
                  break;
 
                dest = SET_DEST (PATTERN (insn));
-               if (REG_P (dest) || CC0_P (dest))
+               if (REG_P (dest))
                  setcc = insn;
                else
                  break;
@@ -1852,12 +1846,22 @@ one_cprop_pass (void)
                if (! NOTE_P (insn) && ! insn->deleted ())
                  mark_oprs_set (insn);
 
-               if (!was_uncond_trap && !seen_uncond_trap
+               if (!was_uncond_trap
                    && GET_CODE (PATTERN (insn)) == TRAP_IF
                    && XEXP (PATTERN (insn), 0) == const1_rtx)
                  {
-                   seen_uncond_trap = true;
-                   uncond_traps.safe_push (insn);
+                   /* If we have already seen an unconditional trap
+                      earlier, the rest of the bb is going to be removed
+                      as unreachable.  Just turn it into a note, so that
+                      RTL verification doesn't complain about it before
+                      it is finally removed.  */
+                   if (seen_uncond_trap)
+                     set_insn_deleted (insn);
+                   else
+                     {
+                       seen_uncond_trap = true;
+                       uncond_traps.safe_push (insn);
+                     }
                  }
              }
        }