]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR rtl-optimization/87761
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Mar 2019 15:20:52 +0000 (15:20 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Mar 2019 15:20:52 +0000 (15:20 +0000)
* regcprop.c (copyprop_hardreg_forward_1): Check may_trap_p on SET,
not INSN.  Also check RTX_FRAME_RELATED_P.  Queue insns for DF rescan
as needed.
(pass_cprop_hardreg::execute): Add df note problem and defer insn
rescans.  Reprocess blocks as needed, calling df_analyze before
reprocessing.  Always call df_analyze before fixing up debug bind
insns.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@269896 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/regcprop.c

index 6b9f1c4a2b6206d3854a46130dc0ca90243fc185..4a5b122eedd45e409ea6ad7c47e5a6c70296a3e0 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-26  Jeff Law  <law@redhat.com>
+
+       PR rtl-optimization/87761
+       * regcprop.c (copyprop_hardreg_forward_1): Check may_trap_p on SET,
+       not INSN.  Also check RTX_FRAME_RELATED_P.  Queue insns for DF rescan
+       as needed.
+       (pass_cprop_hardreg::execute): Add df note problem and defer insn
+       rescans.  Reprocess blocks as needed, calling df_analyze before
+       reprocessing.  Always call df_analyze before fixing up debug bind
+       insns.
+       
 2019-03-23  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * config/rs6000/xmmintrin.h (_mm_movemask_pi8): Implement for 32-bit
@@ -8,7 +19,7 @@
        * config/aarch64/aarch64.md (zero_extendsidi2_aarch64): Fix type
        attrribute for uxtw.
 
-2019-02-26  Jeff Law  <law@redhat.com>
+2019-03-26  Jeff Law  <law@redhat.com>
 
        PR rtl-optimization/87761
        * config/mips/mips-protos.h (mips_split_move): Add new argument.
index 926df40f954fb840b3b0c004b91a022dc606d383..8ca523ffe23adba6be1cd3197c3f76e466a21b14 100644 (file)
@@ -800,8 +800,9 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
 
       /* Detect obviously dead sets (via REG_UNUSED notes) and remove them.  */
       if (set
+         && !may_trap_p (set)
+         && !RTX_FRAME_RELATED_P (insn)
          && INSN_P (insn)
-         && !may_trap_p (insn)
          && find_reg_note (insn, REG_UNUSED, SET_DEST (set))
          && !side_effects_p (SET_SRC (set))
          && !side_effects_p (SET_DEST (set)))
@@ -1034,6 +1035,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
             DEBUG_INSNs can be applied.  */
          if (vd->n_debug_insn_changes)
            note_uses (&PATTERN (insn), cprop_find_used_regs, vd);
+         df_insn_rescan (insn);
        }
 
       ksvd.vd = vd;
@@ -1112,7 +1114,10 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
 
          /* Notice copies.  */
          if (copy_p)
-           copy_value (SET_DEST (set), SET_SRC (set), vd);
+           {
+             df_insn_rescan (insn);
+             copy_value (SET_DEST (set), SET_SRC (set), vd);
+           }
        }
 
       if (insn == BB_END (bb))
@@ -1282,47 +1287,68 @@ pass_cprop_hardreg::execute (function *fun)
 {
   struct value_data *all_vd;
   basic_block bb;
-  bool analyze_called = false;
 
   all_vd = XNEWVEC (struct value_data, last_basic_block_for_fn (fun));
 
   auto_sbitmap visited (last_basic_block_for_fn (fun));
   bitmap_clear (visited);
 
+  df_note_add_problem ();
+
+  /* It is tempting to set DF_LR_RUN_DCE, but DCE may choose to delete
+     an insn and this pass would not have visibility into the removal.
+     This pass would then potentially use the source of that
+     INSN for propagation purposes, generating invalid code.
+
+     So we just ask for updated notes and handle trivial deletions
+     within this pass where we can update this passes internal
+     data structures appropriately.  */
+  df_set_flags (DF_DEFER_INSN_RESCAN);
+
   FOR_EACH_BB_FN (bb, fun)
     {
       bitmap_set_bit (visited, bb->index);
 
-      /* If a block has a single predecessor, that we've already
-        processed, begin with the value data that was live at
-        the end of the predecessor block.  */
-      /* ??? Ought to use more intelligent queuing of blocks.  */
-      if (single_pred_p (bb)
-         && bitmap_bit_p (visited, single_pred (bb)->index)
-         && ! (single_pred_edge (bb)->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
+      for (int pass = 0; pass < 2; pass++)
        {
-         all_vd[bb->index] = all_vd[single_pred (bb)->index];
-         if (all_vd[bb->index].n_debug_insn_changes)
+         /* If a block has a single predecessor, that we've already
+            processed, begin with the value data that was live at
+           the end of the predecessor block.  */
+         /* ??? Ought to use more intelligent queuing of blocks.  */
+         if (single_pred_p (bb)
+             && bitmap_bit_p (visited, single_pred (bb)->index)
+             && ! (single_pred_edge (bb)->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
            {
-             unsigned int regno;
-
-             for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+             all_vd[bb->index] = all_vd[single_pred (bb)->index];
+             if (all_vd[bb->index].n_debug_insn_changes)
                {
-                 if (all_vd[bb->index].e[regno].debug_insn_changes)
+                 unsigned int regno;
+
+                 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
                    {
-                     all_vd[bb->index].e[regno].debug_insn_changes = NULL;
-                     if (--all_vd[bb->index].n_debug_insn_changes == 0)
-                       break;
+                     if (all_vd[bb->index].e[regno].debug_insn_changes)
+                       {
+                         all_vd[bb->index].e[regno].debug_insn_changes = NULL;
+                         if (--all_vd[bb->index].n_debug_insn_changes == 0)
+                           break;
+                       }
                    }
                }
            }
-       }
-      else
-       init_value_data (all_vd + bb->index);
+         else
+           init_value_data (all_vd + bb->index);
 
-      copyprop_hardreg_forward_1 (bb, all_vd + bb->index);
+         /* If we were unable to propagate, then break the loop.  */
+         if (!copyprop_hardreg_forward_1 (bb, all_vd + bb->index))
+           break;
+         df_analyze ();
+       }
     }
 
+  /* We must call df_analyze here unconditionally to ensure that the
+     REG_UNUSED and REG_DEAD notes are consistent with and without -g.  */
+  df_analyze ();
+
   if (MAY_HAVE_DEBUG_BIND_INSNS)
     {
       FOR_EACH_BB_FN (bb, fun)
@@ -1332,11 +1358,6 @@ pass_cprop_hardreg::execute (function *fun)
            unsigned int regno;
            bitmap live;
 
-           if (!analyze_called)
-             {
-               df_analyze ();
-               analyze_called = true;
-             }
            live = df_get_live_out (bb);
            for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
              if (all_vd[bb->index].e[regno].debug_insn_changes)