Remove first_pass_instance from pass_ccp

2015-11-15  Tom de Vries  <tom@codesourcery.com>

	* passes.def: Add arg to pass_ccp pass instantiation.
	* tree-ssa-ccp.c (ccp_finalize): Add param nonzero_p.  Use nonzero_p
	instead of first_pass_instance.
	(do_ssa_ccp): Add and handle param nonzero_p.
	(pass_ccp::pass_ccp): Initialize nonzero_p.
	(pass_ccp::set_pass_param): New member function.  Set nonzero_p.
	(pass_ccp::execute): Call do_ssa_ccp with extra arg.
	(pass_ccp::nonzero_p): New private member.

---
 gcc/passes.def     | 10 ++++++----
 gcc/tree-ssa-ccp.c | 27 +++++++++++++++++----------
 2 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/gcc/passes.def b/gcc/passes.def
index 64883a7..17027786 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -78,7 +78,9 @@ along with GCC; see the file COPYING3.  If not see
       PUSH_INSERT_PASSES_WITHIN (pass_all_early_optimizations)
 	  NEXT_PASS (pass_remove_cgraph_callee_edges);
 	  NEXT_PASS (pass_object_sizes, true /* insert_min_max_p */);
-	  NEXT_PASS (pass_ccp);
+	  /* Don't record nonzero bits before IPA to avoid
+	     using too much memory.  */
+	  NEXT_PASS (pass_ccp, false /* nonzero_p */);
 	  /* After CCP we rewrite no longer addressed locals into SSA
 	     form if possible.  */
 	  NEXT_PASS (pass_forwprop);
@@ -157,7 +159,7 @@ along with GCC; see the file COPYING3.  If not see
       /* Initial scalar cleanups before alias computation.
 	 They ensure memory accesses are not indirect wherever possible.  */
       NEXT_PASS (pass_strip_predict_hints);
-      NEXT_PASS (pass_ccp);
+      NEXT_PASS (pass_ccp, true /* nonzero_p */);
       /* After CCP we rewrite no longer addressed locals into SSA
 	 form if possible.  */
       NEXT_PASS (pass_complete_unrolli);
@@ -209,7 +211,7 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_dce);
       NEXT_PASS (pass_forwprop);
       NEXT_PASS (pass_phiopt);
-      NEXT_PASS (pass_ccp);
+      NEXT_PASS (pass_ccp, true /* nonzero_p */);
       /* After CCP we rewrite no longer addressed locals into SSA
 	 form if possible.  */
       NEXT_PASS (pass_cse_sincos);
@@ -319,7 +321,7 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_lower_complex);
       NEXT_PASS (pass_lower_vector_ssa);
       /* Perform simple scalar cleanup which is constant/copy propagation.  */
-      NEXT_PASS (pass_ccp);
+      NEXT_PASS (pass_ccp, true /* nonzero_p */);
       NEXT_PASS (pass_object_sizes);
       /* Fold remaining builtins.  */
       NEXT_PASS (pass_fold_builtins);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index d09fab1..b845a7b 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -886,12 +886,12 @@ do_dbg_cnt (void)
 
 
 /* Do final substitution of propagated values, cleanup the flowgraph and
-   free allocated storage.
+   free allocated storage.  If NONZERO_P, record nonzero bits.
 
    Return TRUE when something was optimized.  */
 
 static bool
-ccp_finalize (void)
+ccp_finalize (bool nonzero_p)
 {
   bool something_changed;
   unsigned i;
@@ -910,9 +910,7 @@ ccp_finalize (void)
       if (!name
 	  || (!POINTER_TYPE_P (TREE_TYPE (name))
 	      && (!INTEGRAL_TYPE_P (TREE_TYPE (name))
-		  /* Don't record nonzero bits before IPA to avoid
-		     using too much memory.  */
-		  || first_pass_instance)))
+		  || !nonzero_p)))
 	continue;
 
       val = get_value (name);
@@ -2394,16 +2392,17 @@ ccp_visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
 }
 
 
-/* Main entry point for SSA Conditional Constant Propagation.  */
+/* Main entry point for SSA Conditional Constant Propagation.  If NONZERO_P,
+   record nonzero bits.  */
 
 static unsigned int
-do_ssa_ccp (void)
+do_ssa_ccp (bool nonzero_p)
 {
   unsigned int todo = 0;
   calculate_dominance_info (CDI_DOMINATORS);
   ccp_initialize ();
   ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node);
-  if (ccp_finalize ())
+  if (ccp_finalize (nonzero_p))
     todo = (TODO_cleanup_cfg | TODO_update_ssa);
   free_dominance_info (CDI_DOMINATORS);
   return todo;
@@ -2429,14 +2428,22 @@ class pass_ccp : public gimple_opt_pass
 {
 public:
   pass_ccp (gcc::context *ctxt)
-    : gimple_opt_pass (pass_data_ccp, ctxt)
+    : gimple_opt_pass (pass_data_ccp, ctxt), nonzero_p (false)
   {}
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_ccp (m_ctxt); }
+  void set_pass_param (unsigned int n, bool param)
+    {
+      gcc_assert (n == 0);
+      nonzero_p = param;
+    }
   virtual bool gate (function *) { return flag_tree_ccp != 0; }
-  virtual unsigned int execute (function *) { return do_ssa_ccp (); }
+  virtual unsigned int execute (function *) { return do_ssa_ccp (nonzero_p); }
 
+ private:
+  /* Determines whether the pass instance records nonzero bits.  */
+  bool nonzero_p;
 }; // class pass_ccp
 
 } // anon namespace
