]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cprop.c
gcc-changelog: come up with GitInfo wrapper.
[thirdparty/gcc.git] / gcc / cprop.c
index b6c2bc431fd77a59c3f8cae6be495b8626581b0d..169ca804e33e89086f944ed730f0d8967bd19866 100644 (file)
@@ -1,5 +1,5 @@
 /* Global constant/copy propagation for RTL.
-   Copyright (C) 1997-2017 Free Software Foundation, Inc.
+   Copyright (C) 1997-2020 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)
     {
@@ -972,7 +971,7 @@ cprop_jump (basic_block bb, rtx_insn *setcc, rtx_insn *jump, rtx from, rtx src)
   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");
@@ -1161,7 +1160,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;
 
@@ -1248,6 +1247,8 @@ local_cprop_pass (void)
   bool changed = false;
   unsigned i;
 
+  auto_vec<rtx_insn *> uncond_traps;
+
   cselib_init (0);
   FOR_EACH_BB_FN (bb, cfun)
     {
@@ -1255,6 +1256,9 @@ local_cprop_pass (void)
        {
          if (INSN_P (insn))
            {
+             bool was_uncond_trap
+               = (GET_CODE (PATTERN (insn)) == TRAP_IF
+                  && XEXP (PATTERN (insn), 0) == const1_rtx);
              rtx note = find_reg_equal_equiv_note (insn);
              do
                {
@@ -1273,6 +1277,13 @@ local_cprop_pass (void)
                          break;
                        }
                    }
+                 if (!was_uncond_trap
+                     && GET_CODE (PATTERN (insn)) == TRAP_IF
+                     && XEXP (PATTERN (insn), 0) == const1_rtx)
+                   {
+                     uncond_traps.safe_push (insn);
+                     break;
+                   }
                  if (insn->deleted ())
                    break;
                }
@@ -1287,6 +1298,14 @@ local_cprop_pass (void)
 
   cselib_finish ();
 
+  while (!uncond_traps.is_empty ())
+    {
+      rtx_insn *insn = uncond_traps.pop ();
+      basic_block to_split = BLOCK_FOR_INSN (insn);
+      remove_edge (split_block (to_split, insn));
+      emit_barrier_after_bb (to_split);
+    }
+
   return changed;
 }
 
@@ -1677,7 +1696,6 @@ bypass_conditional_jumps (void)
   if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
     return 0;
 
-  bypass_last_basic_block = last_basic_block_for_fn (cfun);
   mark_dfs_back_edges ();
 
   changed = 0;
@@ -1833,17 +1851,30 @@ 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);
+                     }
                  }
              }
        }
 
-      changed |= bypass_conditional_jumps ();
+      /* Make sure bypass_conditional_jumps will ignore not just its new
+        basic blocks, but also the ones after unconditional traps (those are
+        unreachable and will be eventually removed as such).  */
+      bypass_last_basic_block = last_basic_block_for_fn (cfun);
 
       while (!uncond_traps.is_empty ())
        {
@@ -1853,6 +1884,8 @@ one_cprop_pass (void)
          emit_barrier_after_bb (to_split);
        }
 
+      changed |= bypass_conditional_jumps ();
+
       FREE_REG_SET (reg_set_bitmap);
       free_cprop_mem ();
     }