> >The patch also hits a bug in i386's ix86_set_current_function. It is
> >responsible
> >for initializing backend and it does so lazily remembering the previous
> >options
> >backend was initialized for. Pragma parsing however clears the cache
> >that leads
> >to wrong settings being used for subsetquent functions.
> >
> >Bootstrapped/regtested x86_64-linux, will commit it tomorrow after bit
> >of more testing.
> 
> But for example for IPA pta this means we apply all IPA transforms without 
> any garbage collection run?

The original loop also did not contain ggc_collect calls.  Can we call 
ggc_collect from ipa-pta's
data collection loop?

(in general I think -fipa-pta is kind of -fplease-explode-on-large-programs :))

Honza
> 
> Richard.
> 
> >Index: gcc/cgraphclones.c
> >===================================================================
> >--- gcc/cgraphclones.c       (revision 217612)
> >+++ gcc/cgraphclones.c       (working copy)
> >@@ -307,7 +307,7 @@ duplicate_thunk_for_node (cgraph_node *t
> >     node = duplicate_thunk_for_node (thunk_of, node);
> > 
> >   if (!DECL_ARGUMENTS (thunk->decl))
> >-    thunk->get_body ();
> >+    thunk->get_untransformed_body ();
> > 
> >   cgraph_edge *cs;
> >   for (cs = node->callers; cs; cs = cs->next_caller)
> >@@ -1067,7 +1067,7 @@ symbol_table::materialize_all_clones (vo
> >           && !gimple_has_body_p (node->decl))
> >         {
> >           if (!node->clone_of->clone_of)
> >-            node->clone_of->get_body ();
> >+            node->clone_of->get_untransformed_body ();
> >           if (gimple_has_body_p (node->clone_of->decl))
> >             {
> >               if (symtab->dump_file)
> >Index: gcc/ipa-icf.c
> >===================================================================
> >--- gcc/ipa-icf.c    (revision 217612)
> >+++ gcc/ipa-icf.c    (working copy)
> >@@ -706,7 +706,7 @@ void
> > sem_function::init (void)
> > {
> >   if (in_lto_p)
> >-    get_node ()->get_body ();
> >+    get_node ()->get_untransformed_body ();
> > 
> >   tree fndecl = node->decl;
> >   function *func = DECL_STRUCT_FUNCTION (fndecl);
> >Index: gcc/passes.c
> >===================================================================
> >--- gcc/passes.c     (revision 217612)
> >+++ gcc/passes.c     (working copy)
> >@@ -2214,36 +2214,6 @@ execute_one_pass (opt_pass *pass)
> >      executed.  */
> >   invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
> > 
> >-  /* SIPLE IPA passes do not handle callgraphs with IPA transforms in
> >it.
> >-     Apply all trnasforms first.  */
> >-  if (pass->type == SIMPLE_IPA_PASS)
> >-    {
> >-      struct cgraph_node *node;
> >-      bool applied = false;
> >-      FOR_EACH_DEFINED_FUNCTION (node)
> >-    if (node->analyzed
> >-        && node->has_gimple_body_p ()
> >-        && (!node->clone_of || node->decl != node->clone_of->decl))
> >-      {
> >-        if (!node->global.inlined_to
> >-            && node->ipa_transforms_to_apply.exists ())
> >-          {
> >-            node->get_body ();
> >-            push_cfun (DECL_STRUCT_FUNCTION (node->decl));
> >-            execute_all_ipa_transforms ();
> >-            cgraph_edge::rebuild_edges ();
> >-            free_dominance_info (CDI_DOMINATORS);
> >-            free_dominance_info (CDI_POST_DOMINATORS);
> >-            pop_cfun ();
> >-            applied = true;
> >-          }
> >-      }
> >-      if (applied)
> >-    symtab->remove_unreachable_nodes (false, dump_file);
> >-      /* Restore current_pass.  */
> >-      current_pass = pass;
> >-    }
> >-
> >   if (!quiet_flag && !cfun)
> >     fprintf (stderr, " <%s>", pass->name ? pass->name : "");
> > 
> >Index: gcc/cgraphunit.c
> >===================================================================
> >--- gcc/cgraphunit.c (revision 217612)
> >+++ gcc/cgraphunit.c (working copy)
> >@@ -197,7 +197,6 @@ along with GCC; see the file COPYING3.
> > #include "target.h"
> > #include "diagnostic.h"
> > #include "params.h"
> >-#include "fibheap.h"
> > #include "intl.h"
> > #include "hash-map.h"
> > #include "plugin-api.h"
> >@@ -1469,7 +1468,7 @@ cgraph_node::expand_thunk (bool output_a
> >     }
> > 
> >       if (in_lto_p)
> >-    get_body ();
> >+    get_untransformed_body ();
> >       a = DECL_ARGUMENTS (thunk_fndecl);
> >       
> >       current_function_decl = thunk_fndecl;
> >@@ -1522,7 +1521,7 @@ cgraph_node::expand_thunk (bool output_a
> >       gimple ret;
> > 
> >       if (in_lto_p)
> >-    get_body ();
> >+    get_untransformed_body ();
> >       a = DECL_ARGUMENTS (thunk_fndecl);
> > 
> >       current_function_decl = thunk_fndecl;
> >@@ -1744,7 +1743,7 @@ cgraph_node::expand (void)
> >   announce_function (decl);
> >   process = 0;
> >   gcc_assert (lowered);
> >-  get_body ();
> >+  get_untransformed_body ();
> > 
> >   /* Generate RTL for the body of DECL.  */
> > 
> >Index: gcc/cgraph.c
> >===================================================================
> >--- gcc/cgraph.c     (revision 217612)
> >+++ gcc/cgraph.c     (working copy)
> >@@ -1664,29 +1664,33 @@ release_function_body (tree decl)
> > {
> >   if (DECL_STRUCT_FUNCTION (decl))
> >     {
> >-      push_cfun (DECL_STRUCT_FUNCTION (decl));
> >-      if (cfun->cfg
> >-      && current_loops)
> >-    {
> >-      cfun->curr_properties &= ~PROP_loops;
> >-      loop_optimizer_finalize ();
> >-    }
> >-      if (cfun->gimple_df)
> >+      if (DECL_STRUCT_FUNCTION (decl)->cfg
> >+      || DECL_STRUCT_FUNCTION (decl)->gimple_df)
> >     {
> >-      delete_tree_ssa ();
> >-      delete_tree_cfg_annotations ();
> >-      cfun->eh = NULL;
> >-    }
> >-      if (cfun->cfg)
> >-    {
> >-      gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
> >-      gcc_assert (!dom_info_available_p (CDI_POST_DOMINATORS));
> >-      clear_edges ();
> >-      cfun->cfg = NULL;
> >+      push_cfun (DECL_STRUCT_FUNCTION (decl));
> >+      if (cfun->cfg
> >+          && current_loops)
> >+        {
> >+          cfun->curr_properties &= ~PROP_loops;
> >+          loop_optimizer_finalize ();
> >+        }
> >+      if (cfun->gimple_df)
> >+        {
> >+          delete_tree_ssa ();
> >+          delete_tree_cfg_annotations ();
> >+          cfun->eh = NULL;
> >+        }
> >+      if (cfun->cfg)
> >+        {
> >+          gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
> >+          gcc_assert (!dom_info_available_p (CDI_POST_DOMINATORS));
> >+          clear_edges ();
> >+          cfun->cfg = NULL;
> >+        }
> >+      if (cfun->value_histograms)
> >+        free_histograms ();
> >+      pop_cfun ();
> >     }
> >-      if (cfun->value_histograms)
> >-    free_histograms ();
> >-      pop_cfun ();
> >       gimple_set_body (decl, NULL);
> >    /* Struct function hangs a lot of data that would leak if we didn't
> >          removed all pointers to it.   */
> >@@ -3138,7 +3142,7 @@ cgraph_node::function_symbol (enum avail
> >    present.  */
> > 
> > bool
> >-cgraph_node::get_body (void)
> >+cgraph_node::get_untransformed_body (void)
> > {
> >   lto_file_decl_data *file_data;
> >   const char *data, *name;
> >@@ -3178,6 +3182,44 @@ cgraph_node::get_body (void)
> >   return true;
> > }
> > 
> >+/* Prepare function body.  When doing LTO, read cgraph_node's body
> >from disk 
> >+   if it is not already present.  When some IPA transformations are
> >scheduled,
> >+   apply them.  */
> >+
> >+bool
> >+cgraph_node::get_body (void)
> >+{
> >+  bool updated;
> >+
> >+  updated = get_untransformed_body ();
> >+
> >+  /* Getting transformed body makes no sense for inline clones;
> >+     we should never use this on real clones becuase they are
> >materialized
> >+     early.
> >+     TODO: Materializing clones here will likely lead to smaller
> >LTRANS
> >+     footprint. */
> >+  gcc_assert (!global.inlined_to && !clone_of);
> >+  if (ipa_transforms_to_apply.exists ())
> >+    {
> >+      opt_pass *saved_current_pass = current_pass;
> >+      FILE *saved_dump_file = dump_file;
> >+      int saved_dump_flags = dump_flags;
> >+
> >+      push_cfun (DECL_STRUCT_FUNCTION (decl));
> >+      execute_all_ipa_transforms ();
> >+      cgraph_edge::rebuild_edges ();
> >+      free_dominance_info (CDI_DOMINATORS);
> >+      free_dominance_info (CDI_POST_DOMINATORS);
> >+      pop_cfun ();
> >+      updated = true;
> >+
> >+      current_pass = saved_current_pass;
> >+      dump_file = saved_dump_file;
> >+      dump_flags = saved_dump_flags;
> >+    }
> >+  return updated;
> >+}
> >+
> > /* Return the DECL_STRUCT_FUNCTION of the function.  */
> > 
> > struct function *
> >Index: gcc/cgraph.h
> >===================================================================
> >--- gcc/cgraph.h     (revision 217612)
> >+++ gcc/cgraph.h     (working copy)
> >@@ -933,6 +933,11 @@ public:
> > 
> >/* When doing LTO, read cgraph_node's body from disk if it is not
> >already
> >      present.  */
> >+  bool get_untransformed_body (void);
> >+
> >+  /* Prepare function body.  When doing LTO, read cgraph_node's body
> >from disk 
> >+     if it is not already present.  When some IPA transformations are
> >scheduled,
> >+     apply them.  */
> >   bool get_body (void);
> > 
> >   /* Release memory used to represent body of function.
> >Index: gcc/config/i386/i386.c
> >===================================================================
> >--- gcc/config/i386/i386.c   (revision 217612)
> >+++ gcc/config/i386/i386.c   (working copy)
> >@@ -5029,10 +5029,35 @@ ix86_can_inline_p (tree caller, tree cal
> > /* Remember the last target of ix86_set_current_function.  */
> > static GTY(()) tree ix86_previous_fndecl;
> > 
> >+/* Set target globals to default.  */
> >+
> >+static void
> >+ix86_reset_to_default_globals (void)
> >+{
> >+  tree old_tree = (ix86_previous_fndecl
> >+               ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl)
> >+               : NULL_TREE);
> >+
> >+  if (old_tree)
> >+    {
> >+      tree new_tree = target_option_current_node;
> >+      cl_target_option_restore (&global_options,
> >+                            TREE_TARGET_OPTION (new_tree));
> >+      if (TREE_TARGET_GLOBALS (new_tree))
> >+    restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
> >+      else if (new_tree == target_option_default_node)
> >+    restore_target_globals (&default_target_globals);
> >+      else
> >+    TREE_TARGET_GLOBALS (new_tree)
> >+      = save_target_globals_default_opts ();
> >+    }
> >+}
> >+
> > /* Invalidate ix86_previous_fndecl cache.  */
> > void
> > ix86_reset_previous_fndecl (void)
> > {
> >+  ix86_reset_to_default_globals ();
> >   ix86_previous_fndecl = NULL_TREE;
> > }
> > 
> >@@ -5071,18 +5096,7 @@ ix86_set_current_function (tree fndecl)
> >     }
> > 
> >       else if (old_tree)
> >-    {
> >-      new_tree = target_option_current_node;
> >-      cl_target_option_restore (&global_options,
> >-                                TREE_TARGET_OPTION (new_tree));
> >-      if (TREE_TARGET_GLOBALS (new_tree))
> >-        restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
> >-      else if (new_tree == target_option_default_node)
> >-        restore_target_globals (&default_target_globals);
> >-      else
> >-        TREE_TARGET_GLOBALS (new_tree)
> >-          = save_target_globals_default_opts ();
> >-    }
> >+    ix86_reset_to_default_globals ();
> >     }
> > }
> > 
> >@@ -50972,7 +50986,7 @@ ix86_simd_clone_adjust (struct cgraph_no
> >   bool ok = ix86_valid_target_attribute_p (node->decl, NULL, args, 0);
> >   gcc_assert (ok);
> >   pop_cfun ();
> >-  ix86_previous_fndecl = NULL_TREE;
> >+  ix86_reset_previous_fndecl ();
> >   ix86_set_current_function (node->decl);
> > }
> > 
> >Index: gcc/tree-inline.c
> >===================================================================
> >--- gcc/tree-inline.c        (revision 217612)
> >+++ gcc/tree-inline.c        (working copy)
> >@@ -4338,7 +4338,7 @@ expand_call_inline (basic_block bb, gimp
> >       goto egress;
> >     }
> >   fn = cg_edge->callee->decl;
> >-  cg_edge->callee->get_body ();
> >+  cg_edge->callee->get_untransformed_body ();
> > 
> > #ifdef ENABLE_CHECKING
> >   if (cg_edge->callee->decl != id->dst_node->decl)
> >Index: gcc/tree-ssa-structalias.c
> >===================================================================
> >--- gcc/tree-ssa-structalias.c       (revision 217612)
> >+++ gcc/tree-ssa-structalias.c       (working copy)
> >@@ -7086,7 +7086,7 @@ ipa_pta_execute (void)
> >       /* Nodes without a body are not interesting.  Especially do not
> >          visit clones at this point for now - we get duplicate decls
> >      there for inline clones at least.  */
> >-      if (!node->has_gimple_body_p () || node->clone_of)
> >+      if (!node->has_gimple_body_p () || node->global.inlined_to)
> >     continue;
> >       node->get_body ();
> > 
> 

Reply via email to