diff mbox

[1/2] Make SCCVN use conditional equivalences

Message ID alpine.LSU.2.11.1508120929480.19642@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Aug. 12, 2015, 7:32 a.m. UTC
This is the first patch in the series to make SCCVN able to remove
redundant comparisons by recording conditionals being true on
visited edges.  This part of the series fully transitions the
toplevel walk gathering entries to SCCs we value-number to the
DOM walk which at the moment only visits last stmts of BBs.
After this series we can safely insert expressions into the
SCCVN tables temporarily for uses dominated by the stmt generating
them.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-08-12  Richard Biener  <rguenther@suse.de>

	* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
	Eliminate edges marked as not executable by SCCVN.
	* tree-ssa-sccvn.c: Include gimple-iterator.h.
	(cond_dom_walker): Rename to sccvn_dom_walker.
	(sccvn_dom_walker::before_dom_children): Value-number defs
	of all stmts.
	(run_scc_vn): Remove loop value-numbering all SSA names.
	Drop not visited SSA names to varying.

	* gcc.dg/tree-ssa/ssa-fre-43.c: Adjust.

Comments

Markus Trippelsdorf Aug. 12, 2015, 2:32 p.m. UTC | #1
On 2015.08.12 at 09:32 +0200, Richard Biener wrote:
> 
> This is the first patch in the series to make SCCVN able to remove
> redundant comparisons by recording conditionals being true on
> visited edges.  This part of the series fully transitions the
> toplevel walk gathering entries to SCCs we value-number to the
> DOM walk which at the moment only visits last stmts of BBs.
> After this series we can safely insert expressions into the
> SCCVN tables temporarily for uses dominated by the stmt generating
> them.

This patch caused: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67191
diff mbox

Patch

Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	(revision 226777)
+++ gcc/tree-ssa-pre.c	(working copy)
@@ -4291,7 +4291,31 @@  eliminate_dom_walker::before_dom_childre
               el_to_remove.safe_push (stmt);
 	      continue;
             }
-        }
+	}
+
+      /* If this is a control statement value numbering left edges
+	 unexecuted on force the condition in a way consistent with
+	 that.  */
+      if (gcond *cond = dyn_cast <gcond *> (stmt))
+	{
+	  if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE)
+	      ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE))
+	    {
+              if (dump_file && (dump_flags & TDF_DETAILS))
+                {
+                  fprintf (dump_file, "Removing unexecutable edge from ");
+                  print_gimple_stmt (dump_file, stmt, 0, 0);
+                }
+	      if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0)
+		  == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0))
+		gimple_cond_make_true (cond);
+	      else
+		gimple_cond_make_false (cond);
+	      update_stmt (cond);
+	      el_todo |= TODO_cleanup_cfg;
+	      continue;
+	    }
+	}
 
       bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
       bool was_noreturn = (is_gimple_call (stmt)
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 226777)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -57,6 +57,7 @@  along with GCC; see the file COPYING3.
 #include "tree-cfg.h"
 #include "domwalk.h"
 #include "cgraph.h"
+#include "gimple-iterator.h"
 
 /* This algorithm is based on the SCC algorithm presented by Keith
    Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
@@ -4277,18 +4278,20 @@  set_hashtable_value_ids (void)
     set_value_id_for_result (vr->result, &vr->value_id);
 }
 
-class cond_dom_walker : public dom_walker
+class sccvn_dom_walker : public dom_walker
 {
 public:
-  cond_dom_walker () : dom_walker (CDI_DOMINATORS), fail (false) {}
+  sccvn_dom_walker () : dom_walker (CDI_DOMINATORS), fail (false) {}
 
   virtual void before_dom_children (basic_block);
 
   bool fail;
 };
 
+/* Value number all statements in BB.  */
+
 void
-cond_dom_walker::before_dom_children (basic_block bb)
+sccvn_dom_walker::before_dom_children (basic_block bb)
 {
   edge e;
   edge_iterator ei;
@@ -4317,6 +4320,34 @@  cond_dom_walker::before_dom_children (ba
       return;
     }
 
+  /* Value-number all defs in the basic-block.  */
+  for (gphi_iterator gsi = gsi_start_phis (bb);
+       !gsi_end_p (gsi); gsi_next (&gsi))
+    {
+      gphi *phi = gsi.phi ();
+      tree res = PHI_RESULT (phi);
+      if (!VN_INFO (res)->visited
+	  && !DFS (res))
+	{
+	  fail = true;
+	  return;
+	}
+    }
+  for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
+       !gsi_end_p (gsi); gsi_next (&gsi))
+    {
+      ssa_op_iter i;
+      tree op;
+      FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS)
+	if (!VN_INFO (op)->visited
+	    && !DFS (op))
+	  {
+	    fail = true;
+	    return;
+	  }
+    }
+
+  /* Finally look at the last stmt.  */
   gimple stmt = last_stmt (bb);
   if (!stmt)
     return;
@@ -4329,8 +4360,7 @@  cond_dom_walker::before_dom_children (ba
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
-      fprintf (dump_file, "Value-numbering operands of stmt ending BB %d: ",
-	       bb->index);
+      fprintf (dump_file, "Visiting stmt ending BB %d: ", bb->index);
       print_gimple_stmt (dump_file, stmt, 0, 0);
     }
 
@@ -4338,12 +4368,8 @@  cond_dom_walker::before_dom_children (ba
   ssa_op_iter i;
   tree op;
   FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
-    if (VN_INFO (op)->visited == false
-	&& !DFS (op))
-      {
-	fail = true;
-	return;
-      }
+    gcc_assert (VN_INFO (op)->visited
+		|| SSA_NAME_IS_DEFAULT_DEF (op));
 
   /* ???  We can even handle stmts with outgoing EH or ABNORMAL edges
      if value-numbering can prove they are not reachable.  Handling
@@ -4427,9 +4453,9 @@  run_scc_vn (vn_lookup_kind default_vn_wa
 	e->flags |= EDGE_EXECUTABLE;
     }
 
-  /* Walk all blocks in dominator order, value-numbering the last stmts
-     SSA uses and decide whether outgoing edges are not executable.  */
-  cond_dom_walker walker;
+  /* Walk all blocks in dominator order, value-numbering stmts
+     SSA defs and decide whether outgoing edges are not executable.  */
+  sccvn_dom_walker walker;
   walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
   if (walker.fail)
     {
@@ -4437,22 +4463,8 @@  run_scc_vn (vn_lookup_kind default_vn_wa
       return false;
     }
 
-  /* Value-number remaining SSA names.  */
-  for (i = 1; i < num_ssa_names; ++i)
-    {
-      tree name = ssa_name (i);
-      if (name
-	  && VN_INFO (name)->visited == false
-	  && !has_zero_uses (name))
-	if (!DFS (name))
-	  {
-	    free_scc_vn ();
-	    return false;
-	  }
-    }
-
-  /* Initialize the value ids.  */
-
+  /* Initialize the value ids and prune out remaining VN_TOPs
+     from dead code.  */
   for (i = 1; i < num_ssa_names; ++i)
     {
       tree name = ssa_name (i);
@@ -4460,6 +4472,8 @@  run_scc_vn (vn_lookup_kind default_vn_wa
       if (!name)
 	continue;
       info = VN_INFO (name);
+      if (!info->visited)
+	info->valnum = name;
       if (info->valnum == name
 	  || info->valnum == VN_TOP)
 	info->value_id = get_next_value_id ();
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c	(revision 226777)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c	(working copy)
@@ -21,8 +21,8 @@  L10:
   goto L10;
 }
 
-/* We should remove 15 dead loads, fully propagating their replacements
-   with exactly 4 loads and 4 stores from/to E remaining.  */
+/* We should remove 15 dead loads and some related stmts, fully propagating
+   their replacements with exactly 4 loads and 4 stores from/to E remaining.  */
 
-/* { dg-final { scan-tree-dump-times "Removing dead stmt" 15 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Removing dead stmt" 19 "fre1" } } */
 /* { dg-final { scan-tree-dump-not "Not changing value number" "fre1" } } */