public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-3456] tree-optimization/97199 - fix virtual operand update in if-conversion
@ 2020-09-25 11:12 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2020-09-25 11:12 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4dcc7f03b54087638e084ac69d40d7507fe83bd8

commit r11-3456-g4dcc7f03b54087638e084ac69d40d7507fe83bd8
Author: Richard Biener <rguenther@suse.de>
Date:   Fri Sep 25 13:08:48 2020 +0200

    tree-optimization/97199 - fix virtual operand update in if-conversion
    
    This fixes a corner case with virtual operand update in if-conversion
    by re-organizing the code to remove edges only after the last point
    we need virtual PHI operands to be available.
    
    2020-09-25  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/97199
            * tree-if-conv.c (combine_blocks): Remove edges only
            after looking at virtual PHI args.

Diff:
---
 gcc/tree-if-conv.c | 107 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 63 insertions(+), 44 deletions(-)

diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 4b8d457867e..2062758f40f 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -2544,8 +2544,7 @@ combine_blocks (class loop *loop)
   if (need_to_predicate)
     predicate_statements (loop);
 
-  /* Merge basic blocks: first remove all the edges in the loop,
-     except for those from the exit block.  */
+  /* Merge basic blocks.  */
   exit_bb = NULL;
   bool *predicated = XNEWVEC (bool, orig_loop_num_nodes);
   for (i = 0; i < orig_loop_num_nodes; i++)
@@ -2561,43 +2560,6 @@ combine_blocks (class loop *loop)
     }
   gcc_assert (exit_bb != loop->latch);
 
-  for (i = 1; i < orig_loop_num_nodes; i++)
-    {
-      bb = ifc_bbs[i];
-
-      for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
-	{
-	  if (e->src == exit_bb)
-	    ei_next (&ei);
-	  else
-	    remove_edge (e);
-	}
-    }
-
-  if (exit_bb != NULL)
-    {
-      if (exit_bb != loop->header)
-	{
-	  /* Connect this node to loop header.  */
-	  make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU);
-	  set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
-	}
-
-      /* Redirect non-exit edges to loop->latch.  */
-      FOR_EACH_EDGE (e, ei, exit_bb->succs)
-	{
-	  if (!loop_exit_edge_p (loop, e))
-	    redirect_edge_and_branch (e, loop->latch);
-	}
-      set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
-    }
-  else
-    {
-      /* If the loop does not have an exit, reconnect header and latch.  */
-      make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
-      set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
-    }
-
   merge_target_bb = loop->header;
 
   /* Get at the virtual def valid for uses starting at the first block
@@ -2682,13 +2644,9 @@ combine_blocks (class loop *loop)
       last = gsi_last_bb (merge_target_bb);
       gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT);
       set_bb_seq (bb, NULL);
-
-      delete_basic_block (bb);
     }
 
-  /* If possible, merge loop header to the block with the exit edge.
-     This reduces the number of basic blocks to two, to please the
-     vectorizer that handles only loops with two nodes.  */
+  /* Fixup virtual operands in the exit block.  */
   if (exit_bb
       && exit_bb != loop->header)
     {
@@ -2698,6 +2656,11 @@ combine_blocks (class loop *loop)
       vphi = get_virtual_phi (exit_bb);
       if (vphi)
 	{
+	  /* When there's just loads inside the loop a stray virtual
+	     PHI merging the uses can appear, update last_vdef from
+	     it.  */
+	  if (!last_vdef)
+	    last_vdef = gimple_phi_arg_def (vphi, 0);
 	  imm_use_iterator iter;
 	  use_operand_p use_p;
 	  gimple *use_stmt;
@@ -2711,7 +2674,63 @@ combine_blocks (class loop *loop)
 	  gimple_stmt_iterator gsi = gsi_for_stmt (vphi); 
 	  remove_phi_node (&gsi, true);
 	}
+    }
+
+  /* Now remove all the edges in the loop, except for those from the exit
+     block and delete the blocks we elided.  */
+  for (i = 1; i < orig_loop_num_nodes; i++)
+    {
+      bb = ifc_bbs[i];
+
+      for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
+	{
+	  if (e->src == exit_bb)
+	    ei_next (&ei);
+	  else
+	    remove_edge (e);
+	}
+    }
+  for (i = 1; i < orig_loop_num_nodes; i++)
+    {
+      bb = ifc_bbs[i];
+
+      if (bb == exit_bb || bb == loop->latch)
+	continue;
+
+      delete_basic_block (bb);
+    }
+
+  /* Re-connect the exit block.  */
+  if (exit_bb != NULL)
+    {
+      if (exit_bb != loop->header)
+	{
+	  /* Connect this node to loop header.  */
+	  make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU);
+	  set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
+	}
 
+      /* Redirect non-exit edges to loop->latch.  */
+      FOR_EACH_EDGE (e, ei, exit_bb->succs)
+	{
+	  if (!loop_exit_edge_p (loop, e))
+	    redirect_edge_and_branch (e, loop->latch);
+	}
+      set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
+    }
+  else
+    {
+      /* If the loop does not have an exit, reconnect header and latch.  */
+      make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
+      set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
+    }
+
+  /* If possible, merge loop header to the block with the exit edge.
+     This reduces the number of basic blocks to two, to please the
+     vectorizer that handles only loops with two nodes.  */
+  if (exit_bb
+      && exit_bb != loop->header)
+    {
       if (can_merge_blocks_p (loop->header, exit_bb))
 	merge_blocks (loop->header, exit_bb);
     }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-25 11:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-25 11:12 [gcc r11-3456] tree-optimization/97199 - fix virtual operand update in if-conversion Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).