diff mbox series

[PR82163/V2] New interface checking LCSSA for single loop

Message ID DB5PR0801MB274255B31C0E73C4288F13FEE7670@DB5PR0801MB2742.eurprd08.prod.outlook.com
State New
Headers show
Series [PR82163/V2] New interface checking LCSSA for single loop | expand

Commit Message

Bin Cheng Sept. 22, 2017, 11:37 a.m. UTC
Hi,
This is the V2 patch fixing PR82163.  It rewrites verify_loop_closed_ssa by checking
uses of all definitions inside of loop.  This gives advantage that we can check loop
closed ssa form for a specific loop, rather than for whole function.  The interface
is used in fixing this issue.
Bootstrap and test on x86_64, is it OK?

Thanks,
bin
2017-09-21  Bin Cheng  <bin.cheng@arm.com>

	PR tree-optimization/82163
	* tree-ssa-loop-manip.h (verify_loop_closed_ssa): New parameter.
	(checking_verify_loop_closed_ssa): New parameter.
	* tree-ssa-loop-manip.c (check_loop_closed_ssa_use): Delete.
	(check_loop_closed_ssa_stmt): Delete.
	(check_loop_closed_ssa_def, check_loop_closed_ssa_bb): New functions.
	(verify_loop_closed_ssa): Check loop closed ssa form for LOOP.
	(tree_transform_and_unroll_loop): Check loop closed ssa form only for
	changed loops.

gcc/testsuite
2017-09-21  Bin Cheng  <bin.cheng@arm.com>

	PR tree-optimization/82163
	* gcc.dg/tree-ssa/pr82163.c: New test.
From ef756285db3685bd97bbe7d144d58af477251416 Mon Sep 17 00:00:00 2001
From: Bin Cheng <binche01@e108451-lin.cambridge.arm.com>
Date: Thu, 21 Sep 2017 12:41:32 +0100
Subject: [PATCH] pr82163-20170921.txt

---
 gcc/testsuite/gcc.dg/tree-ssa/pr82163.c | 23 +++++++++
 gcc/tree-ssa-loop-manip.c               | 91 +++++++++++++++++++--------------
 gcc/tree-ssa-loop-manip.h               |  6 +--
 3 files changed, 80 insertions(+), 40 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr82163.c

Comments

Richard Biener Sept. 22, 2017, 12:47 p.m. UTC | #1
On Fri, Sep 22, 2017 at 1:37 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
> Hi,
> This is the V2 patch fixing PR82163.  It rewrites verify_loop_closed_ssa by checking
> uses of all definitions inside of loop.  This gives advantage that we can check loop
> closed ssa form for a specific loop, rather than for whole function.  The interface
> is used in fixing this issue.
> Bootstrap and test on x86_64, is it OK?

Looks good to me.

Thanks,
Richard.

> Thanks,
> bin
> 2017-09-21  Bin Cheng  <bin.cheng@arm.com>
>
>         PR tree-optimization/82163
>         * tree-ssa-loop-manip.h (verify_loop_closed_ssa): New parameter.
>         (checking_verify_loop_closed_ssa): New parameter.
>         * tree-ssa-loop-manip.c (check_loop_closed_ssa_use): Delete.
>         (check_loop_closed_ssa_stmt): Delete.
>         (check_loop_closed_ssa_def, check_loop_closed_ssa_bb): New functions.
>         (verify_loop_closed_ssa): Check loop closed ssa form for LOOP.
>         (tree_transform_and_unroll_loop): Check loop closed ssa form only for
>         changed loops.
>
> gcc/testsuite
> 2017-09-21  Bin Cheng  <bin.cheng@arm.com>
>
>         PR tree-optimization/82163
>         * gcc.dg/tree-ssa/pr82163.c: New test.
Bernhard Reutner-Fischer Sept. 23, 2017, 5:31 p.m. UTC | #2
On Fri, Sep 22, 2017 at 11:37:53AM +0000, Bin Cheng wrote:

> diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
> index d6ba305..6ad0b75 100644
> --- a/gcc/tree-ssa-loop-manip.c
> +++ b/gcc/tree-ssa-loop-manip.c
> @@ -690,48 +690,62 @@ rewrite_virtuals_into_loop_closed_ssa (struct loop *loop)
>    rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_VIRTUAL_USES, loop);
>  }

> -/* Checks invariants of loop closed ssa form in statement STMT in BB.  */
> +/* Checks invariants of loop closed ssa form in BB.  */
>  
>  static void
> -check_loop_closed_ssa_stmt (basic_block bb, gimple *stmt)
> +check_loop_closed_ssa_bb (basic_block bb)
>  {
> -  ssa_op_iter iter;
> -  tree var;
> +  for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
> +       gsi_next (&bsi))
> +    {
> +      gphi *phi = bsi.phi ();
>  
> -  if (is_gimple_debug (stmt))
> -    return;
> +      if (!virtual_operand_p (PHI_RESULT (phi)))
> +	check_loop_closed_ssa_def (bb, PHI_RESULT (phi));
> +    }
> +
> +  for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
> +       gsi_next (&bsi))
> +    {
> +      ssa_op_iter iter;
> +      tree var;
> +      gimple *stmt = gsi_stmt (bsi);
> +
> +      if (is_gimple_debug (stmt))
> +	continue;

for (gimple_stmt_iterator bsi = gsi_start_nondebug_after_labels_bb (bb);
     !gsi_end_p (bsi);
     gsi_next_nondebug (&bsi))

?
>  
> -  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
> -    check_loop_closed_ssa_use (bb, var);
> +      FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
> +	check_loop_closed_ssa_def (bb, var);
> +    }
>  }
Bin.Cheng Sept. 25, 2017, 4:55 p.m. UTC | #3
On Sat, Sep 23, 2017 at 6:31 PM, Bernhard Reutner-Fischer
<rep.dot.nop@gmail.com> wrote:
> On Fri, Sep 22, 2017 at 11:37:53AM +0000, Bin Cheng wrote:
>
>> diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
>> index d6ba305..6ad0b75 100644
>> --- a/gcc/tree-ssa-loop-manip.c
>> +++ b/gcc/tree-ssa-loop-manip.c
>> @@ -690,48 +690,62 @@ rewrite_virtuals_into_loop_closed_ssa (struct loop *loop)
>>    rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_VIRTUAL_USES, loop);
>>  }
>
>> -/* Checks invariants of loop closed ssa form in statement STMT in BB.  */
>> +/* Checks invariants of loop closed ssa form in BB.  */
>>
>>  static void
>> -check_loop_closed_ssa_stmt (basic_block bb, gimple *stmt)
>> +check_loop_closed_ssa_bb (basic_block bb)
>>  {
>> -  ssa_op_iter iter;
>> -  tree var;
>> +  for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
>> +       gsi_next (&bsi))
>> +    {
>> +      gphi *phi = bsi.phi ();
>>
>> -  if (is_gimple_debug (stmt))
>> -    return;
>> +      if (!virtual_operand_p (PHI_RESULT (phi)))
>> +     check_loop_closed_ssa_def (bb, PHI_RESULT (phi));
>> +    }
>> +
>> +  for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
>> +       gsi_next (&bsi))
>> +    {
>> +      ssa_op_iter iter;
>> +      tree var;
>> +      gimple *stmt = gsi_stmt (bsi);
>> +
>> +      if (is_gimple_debug (stmt))
>> +     continue;
>
> for (gimple_stmt_iterator bsi = gsi_start_nondebug_after_labels_bb (bb);
>      !gsi_end_p (bsi);
>      gsi_next_nondebug (&bsi))
>
> ?
Thanks for the suggestion, patch updated.  I will commit it later
since it's an obvious update.

Thanks,
bin
>>
>> -  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
>> -    check_loop_closed_ssa_use (bb, var);
>> +      FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
>> +     check_loop_closed_ssa_def (bb, var);
>> +    }
>>  }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr82163.c b/gcc/testsuite/gcc.dg/tree-ssa/pr82163.c
new file mode 100644
index 0000000..389d5c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr82163.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, b, c[4], d, e, f, g;
+
+void h ()
+{
+  for (; a; a++)
+    {
+      c[a + 3] = g;
+      if (b)
+        c[a] = f;
+      else
+        {
+          for (; d; d++)
+            c[d + 3] = c[d];
+          for (e = 1; e == 2; e++)
+            ;
+          if (e)
+            break;
+        }
+    }
+}
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index d6ba305..b08b8b9 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -690,48 +690,59 @@ rewrite_virtuals_into_loop_closed_ssa (struct loop *loop)
   rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_VIRTUAL_USES, loop);
 }
 
-/* Check invariants of the loop closed ssa form for the USE in BB.  */
+/* Check invariants of the loop closed ssa form for the def in DEF_BB.  */
 
 static void
-check_loop_closed_ssa_use (basic_block bb, tree use)
+check_loop_closed_ssa_def (basic_block def_bb, tree def)
 {
-  gimple *def;
-  basic_block def_bb;
+  use_operand_p use_p;
+  imm_use_iterator iterator;
+  FOR_EACH_IMM_USE_FAST (use_p, iterator, def)
+    {
+      if (is_gimple_debug (USE_STMT (use_p)))
+	continue;
 
-  if (TREE_CODE (use) != SSA_NAME || virtual_operand_p (use))
-    return;
+      basic_block use_bb = gimple_bb (USE_STMT (use_p));
+      if (is_a <gphi *> (USE_STMT (use_p)))
+	use_bb = EDGE_PRED (use_bb, PHI_ARG_INDEX_FROM_USE (use_p))->src;
 
-  def = SSA_NAME_DEF_STMT (use);
-  def_bb = gimple_bb (def);
-  gcc_assert (!def_bb
-	      || flow_bb_inside_loop_p (def_bb->loop_father, bb));
+      gcc_assert (flow_bb_inside_loop_p (def_bb->loop_father, use_bb));
+    }
 }
 
-/* Checks invariants of loop closed ssa form in statement STMT in BB.  */
+/* Checks invariants of loop closed ssa form in BB.  */
 
 static void
-check_loop_closed_ssa_stmt (basic_block bb, gimple *stmt)
+check_loop_closed_ssa_bb (basic_block bb)
 {
-  ssa_op_iter iter;
-  tree var;
+  for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
+       gsi_next (&bsi))
+    {
+      gphi *phi = bsi.phi ();
 
-  if (is_gimple_debug (stmt))
-    return;
+      if (!virtual_operand_p (PHI_RESULT (phi)))
+	check_loop_closed_ssa_def (bb, PHI_RESULT (phi));
+    }
 
-  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
-    check_loop_closed_ssa_use (bb, var);
+  for (gimple_stmt_iterator bsi = gsi_start_nondebug_bb (bb); !gsi_end_p (bsi);
+       gsi_next_nondebug (&bsi))
+    {
+      ssa_op_iter iter;
+      tree var;
+      gimple *stmt = gsi_stmt (bsi);
+
+      FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
+	check_loop_closed_ssa_def (bb, var);
+    }
 }
 
 /* Checks that invariants of the loop closed ssa form are preserved.
-   Call verify_ssa when VERIFY_SSA_P is true.  */
+   Call verify_ssa when VERIFY_SSA_P is true.  Note all loops are checked
+   if LOOP is NULL, otherwise, only LOOP is checked.  */
 
 DEBUG_FUNCTION void
-verify_loop_closed_ssa (bool verify_ssa_p)
+verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop)
 {
-  basic_block bb;
-  edge e;
-  edge_iterator ei;
-
   if (number_of_loops (cfun) <= 1)
     return;
 
@@ -740,20 +751,22 @@ verify_loop_closed_ssa (bool verify_ssa_p)
 
   timevar_push (TV_VERIFY_LOOP_CLOSED);
 
-  FOR_EACH_BB_FN (bb, cfun)
+  if (loop == NULL)
     {
-      for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
-	   gsi_next (&bsi))
-	{
-	  gphi *phi = bsi.phi ();
-	  FOR_EACH_EDGE (e, ei, bb->preds)
-	    check_loop_closed_ssa_use (e->src,
-				       PHI_ARG_DEF_FROM_EDGE (phi, e));
-	}
+      basic_block bb;
 
-      for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
-	   gsi_next (&bsi))
-	check_loop_closed_ssa_stmt (bb, gsi_stmt (bsi));
+      FOR_EACH_BB_FN (bb, cfun)
+	if (bb->loop_father && bb->loop_father->num > 0)
+	  check_loop_closed_ssa_bb (bb);
+    }
+  else
+    {
+      basic_block *bbs = get_loop_body (loop);
+
+      for (unsigned i = 0; i < loop->num_nodes; ++i)
+	check_loop_closed_ssa_bb (bbs[i]);
+
+      free (bbs);
     }
 
   timevar_pop (TV_VERIFY_LOOP_CLOSED);
@@ -1405,7 +1418,8 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
 
   checking_verify_flow_info ();
   checking_verify_loop_structure ();
-  checking_verify_loop_closed_ssa (true);
+  checking_verify_loop_closed_ssa (true, loop);
+  checking_verify_loop_closed_ssa (true, new_loop);
 }
 
 /* Wrapper over tree_transform_and_unroll_loop for case we do not
diff --git a/gcc/tree-ssa-loop-manip.h b/gcc/tree-ssa-loop-manip.h
index a139050..3f5b3ee 100644
--- a/gcc/tree-ssa-loop-manip.h
+++ b/gcc/tree-ssa-loop-manip.h
@@ -28,13 +28,13 @@ extern void rewrite_into_loop_closed_ssa_1 (bitmap, unsigned, int,
 					    struct loop *);
 extern void rewrite_into_loop_closed_ssa (bitmap, unsigned);
 extern void rewrite_virtuals_into_loop_closed_ssa (struct loop *);
-extern void verify_loop_closed_ssa (bool);
+extern void verify_loop_closed_ssa (bool, struct loop * = NULL);
 
 static inline void
-checking_verify_loop_closed_ssa (bool verify_ssa_p)
+checking_verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop = NULL)
 {
   if (flag_checking)
-    verify_loop_closed_ssa (verify_ssa_p);
+    verify_loop_closed_ssa (verify_ssa_p, loop);
 }
 
 extern basic_block split_loop_exit_edge (edge);
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr82163.c b/gcc/testsuite/gcc.dg/tree-ssa/pr82163.c
new file mode 100644
index 0000000..fef2b1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr82163.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, b, c[4], d, e, f, g;
+
+void h ()
+{
+  for (; a; a++)
+    {
+      c[a + 3] = g;
+      if (b)
+        c[a] = f;
+      else
+        {
+          for (; d; d++)
+            c[d + 3] = c[d];
+          for (e = 1; e == 2; e++)
+            ;
+          if (e)
+            break;
+        }
+    }
+}
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index d6ba305..6ad0b75 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -690,48 +690,62 @@  rewrite_virtuals_into_loop_closed_ssa (struct loop *loop)
   rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_VIRTUAL_USES, loop);
 }
 
-/* Check invariants of the loop closed ssa form for the USE in BB.  */
+/* Check invariants of the loop closed ssa form for the def in DEF_BB.  */
 
 static void
-check_loop_closed_ssa_use (basic_block bb, tree use)
+check_loop_closed_ssa_def (basic_block def_bb, tree def)
 {
-  gimple *def;
-  basic_block def_bb;
+  use_operand_p use_p;
+  imm_use_iterator iterator;
+  FOR_EACH_IMM_USE_FAST (use_p, iterator, def)
+    {
+      if (is_gimple_debug (USE_STMT (use_p)))
+	continue;
 
-  if (TREE_CODE (use) != SSA_NAME || virtual_operand_p (use))
-    return;
+      basic_block use_bb = gimple_bb (USE_STMT (use_p));
+      if (is_a <gphi *> (USE_STMT (use_p)))
+	use_bb = EDGE_PRED (use_bb, PHI_ARG_INDEX_FROM_USE (use_p))->src;
 
-  def = SSA_NAME_DEF_STMT (use);
-  def_bb = gimple_bb (def);
-  gcc_assert (!def_bb
-	      || flow_bb_inside_loop_p (def_bb->loop_father, bb));
+      gcc_assert (flow_bb_inside_loop_p (def_bb->loop_father, use_bb));
+    }
 }
 
-/* Checks invariants of loop closed ssa form in statement STMT in BB.  */
+/* Checks invariants of loop closed ssa form in BB.  */
 
 static void
-check_loop_closed_ssa_stmt (basic_block bb, gimple *stmt)
+check_loop_closed_ssa_bb (basic_block bb)
 {
-  ssa_op_iter iter;
-  tree var;
+  for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
+       gsi_next (&bsi))
+    {
+      gphi *phi = bsi.phi ();
 
-  if (is_gimple_debug (stmt))
-    return;
+      if (!virtual_operand_p (PHI_RESULT (phi)))
+	check_loop_closed_ssa_def (bb, PHI_RESULT (phi));
+    }
+
+  for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
+       gsi_next (&bsi))
+    {
+      ssa_op_iter iter;
+      tree var;
+      gimple *stmt = gsi_stmt (bsi);
+
+      if (is_gimple_debug (stmt))
+	continue;
 
-  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
-    check_loop_closed_ssa_use (bb, var);
+      FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
+	check_loop_closed_ssa_def (bb, var);
+    }
 }
 
 /* Checks that invariants of the loop closed ssa form are preserved.
-   Call verify_ssa when VERIFY_SSA_P is true.  */
+   Call verify_ssa when VERIFY_SSA_P is true.  Note all loops are checked
+   if LOOP is NULL, otherwise, only LOOP is checked.  */
 
 DEBUG_FUNCTION void
-verify_loop_closed_ssa (bool verify_ssa_p)
+verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop)
 {
-  basic_block bb;
-  edge e;
-  edge_iterator ei;
-
   if (number_of_loops (cfun) <= 1)
     return;
 
@@ -740,20 +754,22 @@  verify_loop_closed_ssa (bool verify_ssa_p)
 
   timevar_push (TV_VERIFY_LOOP_CLOSED);
 
-  FOR_EACH_BB_FN (bb, cfun)
+  if (loop == NULL)
     {
-      for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
-	   gsi_next (&bsi))
-	{
-	  gphi *phi = bsi.phi ();
-	  FOR_EACH_EDGE (e, ei, bb->preds)
-	    check_loop_closed_ssa_use (e->src,
-				       PHI_ARG_DEF_FROM_EDGE (phi, e));
-	}
+      basic_block bb;
 
-      for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
-	   gsi_next (&bsi))
-	check_loop_closed_ssa_stmt (bb, gsi_stmt (bsi));
+      FOR_EACH_BB_FN (bb, cfun)
+	if (bb->loop_father && bb->loop_father->num > 0)
+	  check_loop_closed_ssa_bb (bb);
+    }
+  else
+    {
+      basic_block *bbs = get_loop_body (loop);
+
+      for (unsigned i = 0; i < loop->num_nodes; ++i)
+	check_loop_closed_ssa_bb (bbs[i]);
+
+      free (bbs);
     }
 
   timevar_pop (TV_VERIFY_LOOP_CLOSED);
@@ -1405,7 +1421,8 @@  tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
 
   checking_verify_flow_info ();
   checking_verify_loop_structure ();
-  checking_verify_loop_closed_ssa (true);
+  checking_verify_loop_closed_ssa (true, loop);
+  checking_verify_loop_closed_ssa (true, new_loop);
 }
 
 /* Wrapper over tree_transform_and_unroll_loop for case we do not
diff --git a/gcc/tree-ssa-loop-manip.h b/gcc/tree-ssa-loop-manip.h
index a139050..3f5b3ee 100644
--- a/gcc/tree-ssa-loop-manip.h
+++ b/gcc/tree-ssa-loop-manip.h
@@ -28,13 +28,13 @@  extern void rewrite_into_loop_closed_ssa_1 (bitmap, unsigned, int,
 					    struct loop *);
 extern void rewrite_into_loop_closed_ssa (bitmap, unsigned);
 extern void rewrite_virtuals_into_loop_closed_ssa (struct loop *);
-extern void verify_loop_closed_ssa (bool);
+extern void verify_loop_closed_ssa (bool, struct loop * = NULL);
 
 static inline void
-checking_verify_loop_closed_ssa (bool verify_ssa_p)
+checking_verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop = NULL)
 {
   if (flag_checking)
-    verify_loop_closed_ssa (verify_ssa_p);
+    verify_loop_closed_ssa (verify_ssa_p, loop);
 }
 
 extern basic_block split_loop_exit_edge (edge);