diff mbox series

Rip out SCEV cprop

Message ID alpine.LSU.2.20.1811051206090.1827@zhemvz.fhfr.qr
State New
Headers show
Series Rip out SCEV cprop | expand

Commit Message

Richard Biener Nov. 5, 2018, 11:10 a.m. UTC
This rips out SCEV constant propagation, keeping only final value
replacement in the scev_cprop pass.  There's not a single testcase
that shows "SCEV" constant propagation is doing sth useful.

This takes us one step closer of removing the pass completely,
doing final value replacement only when it helps another transform
like DCE (remove an otherwise empty loop) or vectorization
(removing a reduction).

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

Richard.

2018-11-05  Richard Biener  <rguenther@suse.de>

	* tree-scalar-evolution.h (final_value_replacement_loop): Update
	prototype.
	* tree-scalar-evolution.c (final_value_replacement_loop): Return
	whether anything was done.
	(scev_const_prop): Remove constant propagation part, fold
	remains into ...
	* tree-ssa-loop.c (pass_scev_cprop::execute): ... here.
	(pass_data_scev_cprop): TODO_cleanup_cfg is now done
	conditionally.

	* gcc.dg/pr41488.c: Scan ivcanon dump instead of sccp one.
	* gcc.dg/tree-ssa/scev-7.c: Likewise.
diff mbox series

Patch

Index: gcc/testsuite/gcc.dg/pr41488.c
===================================================================
--- gcc/testsuite/gcc.dg/pr41488.c	(revision 265791)
+++ gcc/testsuite/gcc.dg/pr41488.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-sccp-scev" } */
+/* { dg-options "-O2 -fdump-tree-ivcanon-scev" } */
 
 struct struct_t
 {
@@ -14,4 +14,4 @@  void foo (struct struct_t* sp, int start
     sp->data[i+start] = 0;
 }
 
-/* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "sccp" } } */
+/* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "ivcanon" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/scev-7.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/scev-7.c	(revision 265791)
+++ gcc/testsuite/gcc.dg/tree-ssa/scev-7.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-sccp-scev" } */
+/* { dg-options "-O2 -fdump-tree-ivcanon-scev" } */
 
 struct struct_t
 {
@@ -14,4 +14,4 @@  void foo (struct struct_t* sp, int start
     sp->data[i+start] = 0;
 }
 
-/* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "sccp" } } */
+/* { dg-final { scan-tree-dump-times "Simplify PEELED_CHREC into POLYNOMIAL_CHREC" 1 "ivcanon" } } */
Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c	(revision 265791)
+++ gcc/tree-scalar-evolution.c	(working copy)
@@ -3537,20 +3537,20 @@  expression_expensive_p (tree expr)
     }
 }
 
-/* Do final value replacement for LOOP.  */
+/* Do final value replacement for LOOP, return true if we did anything.  */
 
-void
+bool
 final_value_replacement_loop (struct loop *loop)
 {
   /* If we do not know exact number of iterations of the loop, we cannot
      replace the final value.  */
   edge exit = single_exit (loop);
   if (!exit)
-    return;
+    return false;
 
   tree niter = number_of_latch_executions (loop);
   if (niter == chrec_dont_know)
-    return;
+    return false;
 
   /* Ensure that it is possible to insert new statements somewhere.  */
   if (!single_pred_p (exit->dest))
@@ -3563,6 +3563,7 @@  final_value_replacement_loop (struct loo
     = superloop_at_depth (loop,
 			  loop_depth (exit->dest->loop_father) + 1);
 
+  bool any = false;
   gphi_iterator psi;
   for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); )
     {
@@ -3620,6 +3621,7 @@  final_value_replacement_loop (struct loo
 	  fprintf (dump_file, " with expr: ");
 	  print_generic_expr (dump_file, def);
 	}
+      any = true;
       def = unshare_expr (def);
       remove_phi_node (&psi, false);
 
@@ -3662,100 +3664,8 @@  final_value_replacement_loop (struct loo
 	  fprintf (dump_file, "\n");
 	}
     }
-}
-
-/* Replace ssa names for that scev can prove they are constant by the
-   appropriate constants.  Also perform final value replacement in loops,
-   in case the replacement expressions are cheap.
-
-   We only consider SSA names defined by phi nodes; rest is left to the
-   ordinary constant propagation pass.  */
-
-unsigned int
-scev_const_prop (void)
-{
-  basic_block bb;
-  tree name, type, ev;
-  gphi *phi;
-  struct loop *loop;
-  bitmap ssa_names_to_remove = NULL;
-  unsigned i;
-  gphi_iterator psi;
-
-  if (number_of_loops (cfun) <= 1)
-    return 0;
-
-  FOR_EACH_BB_FN (bb, cfun)
-    {
-      loop = bb->loop_father;
-
-      for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
-	{
-	  phi = psi.phi ();
-	  name = PHI_RESULT (phi);
-
-	  if (virtual_operand_p (name))
-	    continue;
-
-	  type = TREE_TYPE (name);
-
-	  if (!POINTER_TYPE_P (type)
-	      && !INTEGRAL_TYPE_P (type))
-	    continue;
-
-	  ev = resolve_mixers (loop, analyze_scalar_evolution (loop, name),
-			       NULL);
-	  if (!is_gimple_min_invariant (ev)
-	      || !may_propagate_copy (name, ev))
-	    continue;
-
-	  /* Replace the uses of the name.  */
-	  if (name != ev)
-	    {
-	      if (dump_file && (dump_flags & TDF_DETAILS))
-		{
-		  fprintf (dump_file, "Replacing uses of: ");
-		  print_generic_expr (dump_file, name);
-		  fprintf (dump_file, " with: ");
-		  print_generic_expr (dump_file, ev);
-		  fprintf (dump_file, "\n");
-		}
-	      replace_uses_by (name, ev);
-	    }
-
-	  if (!ssa_names_to_remove)
-	    ssa_names_to_remove = BITMAP_ALLOC (NULL);
-	  bitmap_set_bit (ssa_names_to_remove, SSA_NAME_VERSION (name));
-	}
-    }
-
-  /* Remove the ssa names that were replaced by constants.  We do not
-     remove them directly in the previous cycle, since this
-     invalidates scev cache.  */
-  if (ssa_names_to_remove)
-    {
-      bitmap_iterator bi;
-
-      EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
-	{
-	  gimple_stmt_iterator psi;
-	  name = ssa_name (i);
-	  phi = as_a <gphi *> (SSA_NAME_DEF_STMT (name));
-
-	  gcc_assert (gimple_code (phi) == GIMPLE_PHI);
-	  psi = gsi_for_stmt (phi);
-	  remove_phi_node (&psi, true);
-	}
-
-      BITMAP_FREE (ssa_names_to_remove);
-      scev_reset ();
-    }
-
-  /* Now the regular final value replacement.  */
-  FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
-    final_value_replacement_loop (loop);
 
-  return 0;
+  return any;
 }
 
 #include "gt-tree-scalar-evolution.h"
Index: gcc/tree-scalar-evolution.h
===================================================================
--- gcc/tree-scalar-evolution.h	(revision 265791)
+++ gcc/tree-scalar-evolution.h	(working copy)
@@ -33,7 +33,7 @@  extern tree analyze_scalar_evolution (st
 extern tree instantiate_scev (edge, struct loop *, tree);
 extern tree resolve_mixers (struct loop *, tree, bool *);
 extern void gather_stats_on_scev_database (void);
-extern void final_value_replacement_loop (struct loop *);
+extern bool final_value_replacement_loop (struct loop *);
 extern unsigned int scev_const_prop (void);
 extern bool expression_expensive_p (tree);
 extern bool simple_iv_with_niters (struct loop *, struct loop *, tree,
Index: gcc/tree-ssa-loop.c
===================================================================
--- gcc/tree-ssa-loop.c	(revision 265791)
+++ gcc/tree-ssa-loop.c	(working copy)
@@ -436,8 +436,7 @@  const pass_data pass_data_scev_cprop =
   0, /* properties_provided */
   0, /* properties_destroyed */
   0, /* todo_flags_start */
-  ( TODO_cleanup_cfg
-    | TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
+  0, /* todo_flags_finish */
 };
 
 class pass_scev_cprop : public gimple_opt_pass
@@ -449,10 +448,24 @@  public:
 
   /* opt_pass methods: */
   virtual bool gate (function *) { return flag_tree_scev_cprop; }
-  virtual unsigned int execute (function *) { return scev_const_prop (); }
+  virtual unsigned int execute (function *);
 
 }; // class pass_scev_cprop
 
+unsigned
+pass_scev_cprop::execute (function *)
+{
+  struct loop *loop;
+  bool any = false;
+
+  /* Perform final value replacement in loops, in case the replacement
+     expressions are cheap.  */
+  FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
+    any |= final_value_replacement_loop (loop);
+
+  return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
+}
+
 } // anon namespace
 
 gimple_opt_pass *