public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Richard Biener <rguenth@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r12-6790] tree-optimization/104156 - fix unswitching compare-debug issue
Date: Fri, 21 Jan 2022 11:19:21 +0000 (GMT)	[thread overview]
Message-ID: <20220121111921.6469A385843E@sourceware.org> (raw)

https://gcc.gnu.org/g:f953c8bc5bf314a57a6ba347ee6f5f5e3f1dad53

commit r12-6790-gf953c8bc5bf314a57a6ba347ee6f5f5e3f1dad53
Author: Richard Biener <rguenther@suse.de>
Date:   Fri Jan 21 10:19:58 2022 +0100

    tree-optimization/104156 - fix unswitching compare-debug issue
    
    When hoisting guards the unswitching pass does not properly ignore
    debug stmts when looking for uses outside of the loop of defs
    produced in the skipped region.  The following rectifies this
    by instead collecting them and resetting them after the transform.
    
    2022-01-21  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/104156
            * tree-ssa-loop-unswitch.cc (tree_unswitch_outer_loop):
            Collect and reset debug stmts with out-of-loop uses when
            hoisting guards.
            (find_loop_guard): Adjust.
            (empty_bb_without_guard_p): Likewise.  Ignore debug stmts.
            (used_outside_loop_p): Push debug uses to a vector of
            debug stmts to reset.
            (hoist_guard): Adjust -fopt-info category.
    
            * gcc.dg/loop-unswitch-6.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/loop-unswitch-6.c | 32 ++++++++++++++++++++++
 gcc/tree-ssa-loop-unswitch.cc          | 50 +++++++++++++++++++++++-----------
 2 files changed, 66 insertions(+), 16 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-6.c b/gcc/testsuite/gcc.dg/loop-unswitch-6.c
new file mode 100644
index 00000000000..f70b629e054
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/loop-unswitch-6.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -funswitch-loops -g -fcompare-debug -fdump-tree-unswitch-details" } */
+
+short a, d;
+int b, c;
+static int e() {
+  int f = -2L, g = 9, h = 0;
+  for (; h < 2; h++)
+    if (a <= 5) {
+      g = 0;
+      if (c && a)
+        break;
+      if (c - 1)
+        goto i;
+    }
+  if (b) {
+    int *j[] = {&f};
+    if (d)
+      for (; f < 9; f++)
+        if (g)
+          for (; f; f++)
+            ;
+  i:
+    while (f) {
+      a--;
+      break;
+    }
+  }
+}
+int main() { e(); }
+
+/* { dg-final { scan-tree-dump-times "Guard hoisted" 1 "unswitch" } } */
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index a405119b58a..2927f308234 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -79,9 +79,10 @@ static class loop *tree_unswitch_loop (class loop *, basic_block, tree);
 static bool tree_unswitch_single_loop (class loop *, int);
 static tree tree_may_unswitch_on (basic_block, class loop *);
 static bool tree_unswitch_outer_loop (class loop *);
-static edge find_loop_guard (class loop *);
-static bool empty_bb_without_guard_p (class loop *, basic_block);
-static bool used_outside_loop_p (class loop *, tree);
+static edge find_loop_guard (class loop *, vec<gimple *>&);
+static bool empty_bb_without_guard_p (class loop *, basic_block,
+				      vec<gimple *>&);
+static bool used_outside_loop_p (class loop *, tree, vec<gimple *>&);
 static void hoist_guard (class loop *, edge);
 static bool check_exit_phi (class loop *);
 static tree get_vop_from_header (class loop *);
@@ -536,11 +537,18 @@ tree_unswitch_outer_loop (class loop *loop)
     }
 
   bool changed = false;
-  while ((guard = find_loop_guard (loop)))
+  auto_vec<gimple *> dbg_to_reset;
+  while ((guard = find_loop_guard (loop, dbg_to_reset)))
     {
       if (! changed)
 	rewrite_virtuals_into_loop_closed_ssa (loop);
       hoist_guard (loop, guard);
+      for (gimple *debug_stmt : dbg_to_reset)
+	{
+	  gimple_debug_bind_reset_value (debug_stmt);
+	  update_stmt (debug_stmt);
+	}
+      dbg_to_reset.truncate (0);
       changed = true;
     }
   return changed;
@@ -551,7 +559,7 @@ tree_unswitch_outer_loop (class loop *loop)
    otherwise returns NULL.  */
 
 static edge
-find_loop_guard (class loop *loop)
+find_loop_guard (class loop *loop, vec<gimple *> &dbg_to_reset)
 {
   basic_block header = loop->header;
   edge guard_edge, te, fe;
@@ -688,7 +696,7 @@ find_loop_guard (class loop *loop)
 	  guard_edge = NULL;
 	  goto end;
 	}
-      if (!empty_bb_without_guard_p (loop, bb))
+      if (!empty_bb_without_guard_p (loop, bb, dbg_to_reset))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
@@ -699,7 +707,7 @@ find_loop_guard (class loop *loop)
     }
 
   if (dump_enabled_p ())
-    dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+    dump_printf_loc (MSG_NOTE, loc,
 		     "suitable to hoist\n");
 end:
   if (body)
@@ -713,10 +721,12 @@ end:
       are noy used outside of the loop.
    KNOWN_INVARIANTS is a set of ssa names we know to be invariant, and
    PROCESSED is a set of ssa names for that we already tested whether they
-   are invariant or not.  */
+   are invariant or not.  Uses in debug stmts outside of the loop are
+   pushed to DBG_TO_RESET.  */
 
 static bool
-empty_bb_without_guard_p (class loop *loop, basic_block bb)
+empty_bb_without_guard_p (class loop *loop, basic_block bb,
+			  vec<gimple *> &dbg_to_reset)
 {
   basic_block exit_bb = single_exit (loop)->src;
   bool may_be_used_outside = (bb == exit_bb
@@ -736,7 +746,7 @@ empty_bb_without_guard_p (class loop *loop, basic_block bb)
 	  if (virtual_operand_p (name))
 	    continue;
 
-	  if (used_outside_loop_p (loop, name))
+	  if (used_outside_loop_p (loop, name, dbg_to_reset))
 	    return false;
 	}
     }
@@ -745,6 +755,9 @@ empty_bb_without_guard_p (class loop *loop, basic_block bb)
        !gsi_end_p (gsi); gsi_next (&gsi))
     {
       gimple *stmt = gsi_stmt (gsi);
+      if (is_gimple_debug (stmt))
+	continue;
+
       if (gimple_has_side_effects (stmt))
 	return false;
 
@@ -754,17 +767,18 @@ empty_bb_without_guard_p (class loop *loop, basic_block bb)
       FOR_EACH_SSA_TREE_OPERAND (name, stmt, op_iter, SSA_OP_DEF)
 	{
 	  if (may_be_used_outside
-	      && used_outside_loop_p (loop, name))
+	      && used_outside_loop_p (loop, name, dbg_to_reset))
 	    return false;
 	}
     }
   return true;
 }
 
-/* Return true if NAME is used outside of LOOP.  */
+/* Return true if NAME is used outside of LOOP.  Pushes debug stmts that
+   have such uses to DBG_TO_RESET but do not consider such uses.  */
 
 static bool
-used_outside_loop_p (class loop *loop, tree name)
+used_outside_loop_p (class loop *loop, tree name, vec<gimple *> &dbg_to_reset)
 {
   imm_use_iterator it;
   use_operand_p use;
@@ -773,7 +787,11 @@ used_outside_loop_p (class loop *loop, tree name)
     {
       gimple *stmt = USE_STMT (use);
       if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
-	return true;
+	{
+	  if (!is_gimple_debug (stmt))
+	    return true;
+	  dbg_to_reset.safe_push (stmt);
+	}
     }
 
   return false;
@@ -847,7 +865,7 @@ hoist_guard (class loop *loop, edge guard)
       char buffer[64];
       guard->probability.dump (buffer);
 
-      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+      dump_printf_loc (MSG_NOTE, loc,
 		       "Moving guard %i->%i (prob %s) to bb %i, "
 		       "new preheader is %i\n",
 		       guard->src->index, guard->dest->index,
@@ -949,7 +967,7 @@ hoist_guard (class loop *loop, edge guard)
     }
 
   if (dump_enabled_p ())
-    dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
+    dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
 		     "Guard hoisted\n");
 
   free (body);


                 reply	other threads:[~2022-01-21 11:19 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220121111921.6469A385843E@sourceware.org \
    --to=rguenth@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).