From 80f94d490de08005958f372930d7683690e9fc63 Mon Sep 17 00:00:00 2001
From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sat, 16 Dec 2006 18:10:08 +0000
Subject: [PATCH] 	* omp-low.c (expand_omp_parallel): Set function
 properties. 	* function.h (struct function): Add curr_properties and
 last_verified. 	* passes.c (register_dump_files): Do not set
 TODO_set_props for the 	first pass 	(init_optimization_passes):
 Set it here; reorder initialization so the 	dump files appear in more
 logical order. 	(last_verified, curr_properties): Kill. 
 (do_per_function): New function. 	(execute_function_todo): Break out
 from ... 	(execute_todo): ... here; handle per-function flags. 
 (clear_last_verified, verify_curr_properties, 	update_properties_after_pass):
 New functions. 	(execute_one_pass): Handle per-function properties. 
 (execute_ipa_pass_list): Use do_per_function; sanity check that cfun 	and
 current_function_decls are cleared out. 	* ipa-cp.c
 (constant_val_insert): Clear cfun/current_function_decl 	after use.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119966 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog  |  20 +++++++
 gcc/function.h |   4 ++
 gcc/ipa-cp.c   |   2 +
 gcc/omp-low.c  |   2 +
 gcc/passes.c   | 152 +++++++++++++++++++++++++++++++++----------------
 5 files changed, 131 insertions(+), 49 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b17a039c26ad..b667dd1d74dd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+2006-12-16  Jan Hubicka  <jh@suse.cz>
+
+	* omp-low.c (expand_omp_parallel): Set function properties.
+	* function.h (struct function): Add curr_properties and last_verified.
+	* passes.c (register_dump_files): Do not set TODO_set_props for the
+	first pass
+	(init_optimization_passes): Set it here; reorder initialization so the
+	dump files appear in more logical order.
+	(last_verified, curr_properties): Kill.
+	(do_per_function): New function.
+	(execute_function_todo): Break out from ...
+	(execute_todo): ... here; handle per-function flags.
+	(clear_last_verified, verify_curr_properties,
+	update_properties_after_pass): New functions.
+	(execute_one_pass): Handle per-function properties.
+	(execute_ipa_pass_list): Use do_per_function; sanity check that cfun
+	and current_function_decls are cleared out.
+	* ipa-cp.c (constant_val_insert): Clear cfun/current_function_decl
+	after use.
+
 2006-12-16  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
 	PR middle-end/7651
diff --git a/gcc/function.h b/gcc/function.h
index 27e5c02cbba8..e8039a711a18 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -373,6 +373,10 @@ struct function GTY(())
      Used for detecting stack clobbers.  */
   tree stack_protect_guard;
 
+  /* Properties used by the pass manager.  */
+  unsigned int curr_properties;
+  unsigned int last_verified;
+
   /* Collected bit flags.  */
 
   /* Nonzero if function being compiled needs to be given an address
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 305b1a5f4e27..0451667917c0 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -453,6 +453,8 @@ constant_val_insert (tree fn, tree parm1, tree val)
   if (ENTRY_BLOCK_PTR_FOR_FUNCTION (func)->succs)
     FOR_EACH_EDGE (e_step, ei, ENTRY_BLOCK_PTR_FOR_FUNCTION (func)->succs)
       bsi_insert_on_edge_immediate (e_step, init_stmt);
+  current_function_decl = NULL;
+  cfun = NULL;
 }
 
 /* build INTEGER_CST tree with type TREE_TYPE and 
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index ca6aa3afc927..e744a244fe37 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2531,6 +2531,8 @@ expand_omp_parallel (struct omp_region *region)
       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
       if (exit_bb)
 	single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
+      DECL_STRUCT_FUNCTION (child_fn)->curr_properties
+	= cfun->curr_properties;
       cgraph_add_new_function (child_fn);
 
       /* Convert OMP_RETURN into a RETURN_EXPR.  */
diff --git a/gcc/passes.c b/gcc/passes.c
index 8bacb08d5117..e4bac7a844b8 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -371,7 +371,6 @@ static void
 register_dump_files (struct tree_opt_pass *pass, bool ipa, int properties)
 {
   pass->properties_required |= properties;
-  pass->todo_flags_start |= TODO_set_props;
   register_dump_files_1 (pass, ipa, properties);
 }
 
@@ -695,29 +694,52 @@ init_optimization_passes (void)
 #undef NEXT_PASS
 
   /* Register the passes with the tree dump code.  */
+  register_dump_files (all_lowering_passes, false, PROP_gimple_any);
+  all_lowering_passes->todo_flags_start |= TODO_set_props;
   register_dump_files (all_ipa_passes, true,
 		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
 		       | PROP_cfg);
-  register_dump_files (all_lowering_passes, false, PROP_gimple_any);
   register_dump_files (all_passes, false,
 		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
 		       | PROP_cfg);
 }
 
-static unsigned int last_verified;
-static unsigned int curr_properties;
+/* If we are in IPA mode (i.e., current_function_decl is NULL), call
+   function CALLBACK for every function in the call graph.  Otherwise,
+   call CALLBACK on the current function.  */ 
 
 static void
-execute_todo (unsigned int flags)
+do_per_function (void (*callback) (void *data), void *data)
 {
-#if defined ENABLE_CHECKING
-  if (need_ssa_update_p ())
-    gcc_assert (flags & TODO_update_ssa_any);
-#endif
+  if (current_function_decl)
+    callback (data);
+  else
+    {
+      struct cgraph_node *node;
+      for (node = cgraph_nodes; node; node = node->next)
+	if (node->analyzed)
+	  {
+	    push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+	    current_function_decl = node->decl;
+	    callback (data);
+	    free_dominance_info (CDI_DOMINATORS);
+	    free_dominance_info (CDI_POST_DOMINATORS);
+	    current_function_decl = NULL;
+	    pop_cfun ();
+	    ggc_collect ();
+	  }
+    }
+}
+
+/* Perform all TODO actions that ought to be done on each function.  */
 
-  if (curr_properties & PROP_ssa)
+static void
+execute_function_todo (void *data)
+{
+  unsigned int flags = (size_t)data;
+  if (cfun->curr_properties & PROP_ssa)
     flags |= TODO_verify_ssa;
-  flags &= ~last_verified;
+  flags &= ~cfun->last_verified;
   if (!flags)
     return;
   
@@ -743,7 +765,7 @@ execute_todo (unsigned int flags)
     {
       unsigned update_flags = flags & TODO_update_ssa_any;
       update_ssa (update_flags);
-      last_verified &= ~TODO_verify_ssa;
+      cfun->last_verified &= ~TODO_verify_ssa;
     }
 
   if (flags & TODO_remove_unused_locals)
@@ -752,19 +774,20 @@ execute_todo (unsigned int flags)
   if ((flags & TODO_dump_func)
       && dump_file && current_function_decl)
     {
-      if (curr_properties & PROP_trees)
+      if (cfun->curr_properties & PROP_trees)
         dump_function_to_file (current_function_decl,
                                dump_file, dump_flags);
       else
 	{
 	  if (dump_flags & TDF_SLIM)
 	    print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
-	  else if ((curr_properties & PROP_cfg) && (dump_flags & TDF_BLOCKS))
+	  else if ((cfun->curr_properties & PROP_cfg)
+		   && (dump_flags & TDF_BLOCKS))
 	    print_rtl_with_bb (dump_file, get_insns ());
           else
 	    print_rtl (dump_file, get_insns ());
 
-	  if (curr_properties & PROP_cfg
+	  if (cfun->curr_properties & PROP_cfg
 	      && graph_dump_format != no_graph
 	      && (dump_flags & TDF_GRAPH))
 	    print_rtl_graph_with_bb (dump_file_name, get_insns ());
@@ -774,6 +797,32 @@ execute_todo (unsigned int flags)
 	 close the file before aborting.  */
       fflush (dump_file);
     }
+
+#if defined ENABLE_CHECKING
+  if (flags & TODO_verify_ssa)
+    verify_ssa (true);
+  if (flags & TODO_verify_flow)
+    verify_flow_info ();
+  if (flags & TODO_verify_stmts)
+    verify_stmts ();
+  if (flags & TODO_verify_loops)
+    verify_loop_closed_ssa ();
+#endif
+
+  cfun->last_verified = flags & TODO_verify_all;
+}
+
+/* Perform all TODO actions.  */
+static void
+execute_todo (unsigned int flags)
+{
+#if defined ENABLE_CHECKING
+  if (need_ssa_update_p ())
+    gcc_assert (flags & TODO_update_ssa_any);
+#endif
+
+  do_per_function (execute_function_todo, (void *)(size_t) flags);
+
   if ((flags & TODO_dump_cgraph)
       && dump_file && !current_function_decl)
     {
@@ -787,19 +836,34 @@ execute_todo (unsigned int flags)
     {
       ggc_collect ();
     }
+}
 
-#if defined ENABLE_CHECKING
-  if (flags & TODO_verify_ssa)
-    verify_ssa (true);
-  if (flags & TODO_verify_flow)
-    verify_flow_info ();
-  if (flags & TODO_verify_stmts)
-    verify_stmts ();
-  if (flags & TODO_verify_loops)
-    verify_loop_closed_ssa ();
-#endif
+/* Clear the last verified flag.  */
+
+static void
+clear_last_verified (void *data ATTRIBUTE_UNUSED)
+{
+  cfun->last_verified = 0;
+}
+
+/* Helper function. Verify that the properties has been turn into the
+   properties expected by the pass.  */
 
-  last_verified = flags & TODO_verify_all;
+static void
+verify_curr_properties (void *data)
+{
+  unsigned int props = (size_t)data;
+  gcc_assert ((cfun->curr_properties & props) == props);
+}
+
+/* After executing the pass, apply expected changes to the function
+   properties. */
+static void
+update_properties_after_pass (void *data)
+{
+  struct tree_opt_pass *pass = data;
+  cfun->curr_properties = (cfun->curr_properties | pass->properties_provided)
+		           & ~pass->properties_destroyed;
 }
 
 static bool
@@ -813,17 +877,19 @@ execute_one_pass (struct tree_opt_pass *pass)
     return false;
 
   if (pass->todo_flags_start & TODO_set_props)
-    curr_properties = pass->properties_required;
+    cfun->curr_properties = pass->properties_required;
 
   /* Note that the folders should only create gimple expressions.
      This is a hack until the new folder is ready.  */
-  in_gimple_form = (curr_properties & PROP_trees) != 0;
+  in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;
 
   /* Run pre-pass verification.  */
   execute_todo (pass->todo_flags_start);
 
-  gcc_assert ((curr_properties & pass->properties_required)
-	      == pass->properties_required);
+#ifdef ENABLE_CHECKING
+  do_per_function (verify_curr_properties,
+		   (void *)(size_t)pass->properties_required);
+#endif
 
   /* If a dump file name is present, open it if enabled.  */
   if (pass->static_pass_number != -1)
@@ -856,20 +922,20 @@ execute_one_pass (struct tree_opt_pass *pass)
   if (pass->execute)
     {
       todo_after = pass->execute ();
-      last_verified = 0;
+      do_per_function (clear_last_verified, NULL);
     }
 
   /* Stop timevar.  */
   if (pass->tv_id)
     timevar_pop (pass->tv_id);
 
-  curr_properties = (curr_properties | pass->properties_provided)
-		    & ~pass->properties_destroyed;
+  do_per_function (update_properties_after_pass, pass);
 
   if (initializing_dump
       && dump_file
       && graph_dump_format != no_graph
-      && (curr_properties & (PROP_cfg | PROP_rtl)) == (PROP_cfg | PROP_rtl))
+      && (cfun->curr_properties & (PROP_cfg | PROP_rtl))
+	  == (PROP_cfg | PROP_rtl))
     {
       get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH;
       dump_flags |= TDF_GRAPH;
@@ -914,22 +980,10 @@ execute_ipa_pass_list (struct tree_opt_pass *pass)
 {
   do
     {
+      gcc_assert (!current_function_decl);
+      gcc_assert (!cfun);
       if (execute_one_pass (pass) && pass->sub)
-	{
-	  struct cgraph_node *node;
-	  for (node = cgraph_nodes; node; node = node->next)
-	    if (node->analyzed)
-	      {
-		push_cfun (DECL_STRUCT_FUNCTION (node->decl));
-		current_function_decl = node->decl;
-		execute_pass_list (pass->sub);
-		free_dominance_info (CDI_DOMINATORS);
-		free_dominance_info (CDI_POST_DOMINATORS);
-		current_function_decl = NULL;
-		pop_cfun ();
-		ggc_collect ();
-	      }
-	}
+	do_per_function ((void (*)(void *))execute_pass_list, pass->sub);
       pass = pass->next;
     }
   while (pass);
-- 
GitLab