Add free inline summary pass after pass_early_local_passes
authorH.J. Lu <hongjiu.lu@intel.com>
Thu, 2 Aug 2012 16:58:33 +0000 (16:58 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Thu, 2 Aug 2012 16:58:33 +0000 (09:58 -0700)
PR middle-end/53321
PR middle-end/53865
* ipa-inline-analysis.c (inline_free_summary): Return if
inline_edge_summary_vec is NULL.

* ipa-split.c (execute_split_functions): Check if a function
is inlinable only if inline_edge_summary_vec != NULL.

* ipa.c (symtab_remove_unreachable_nodes): Restore
cgraph_propagate_frequency call when something was changed.
(free_inline_summary): New function.
(pass_ipa_free_inline_summary): New pass.

* passes.c (init_optimization_passes): Add
pass_ipa_free_inline_summary before pass_ipa_tree_profile.

* timevar.def (TV_IPA_FREE_INLINE_SUMMARY): New.

* tree-pass.h (pass_ipa_free_inline_summary): New.

From-SVN: r190090

gcc/ChangeLog
gcc/ipa-inline-analysis.c
gcc/ipa-split.c
gcc/ipa.c
gcc/passes.c
gcc/timevar.def
gcc/tree-pass.h

index 578b0a05485416f2f361be7f314c3ea284b8ba52..6839fda90ce2c41bf06cb34c9bd0298d0f8fb31b 100644 (file)
@@ -1,3 +1,25 @@
+2012-08-02  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR middle-end/53321
+       PR middle-end/53865
+       * ipa-inline-analysis.c (inline_free_summary): Return if
+       inline_edge_summary_vec is NULL.
+
+       * ipa-split.c (execute_split_functions): Check if a function
+       is inlinable only if inline_edge_summary_vec != NULL.
+
+       * ipa.c (symtab_remove_unreachable_nodes): Restore
+       cgraph_propagate_frequency call when something was changed.
+       (free_inline_summary): New function.
+       (pass_ipa_free_inline_summary): New pass.
+
+       * passes.c (init_optimization_passes): Add
+       pass_ipa_free_inline_summary before pass_ipa_tree_profile.
+
+       * timevar.def (TV_IPA_FREE_INLINE_SUMMARY): New.
+
+       * tree-pass.h (pass_ipa_free_inline_summary): New.
+
 2012-08-02  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.c (arm_gen_constant): Use UBFX for some AND operations when
index ae321318f143c55fdd7ea924a30160a0c0d09b94..970be1ebca2a817c4b6f3513cd2e91ab9dd80623 100644 (file)
@@ -3242,6 +3242,8 @@ void
 inline_free_summary (void)
 {
   struct cgraph_node *node;
+  if (inline_edge_summary_vec == NULL)
+    return;
   FOR_EACH_DEFINED_FUNCTION (node)
     reset_inline_summary (node);
   if (function_insertion_hook_holder)
index d6aad8977e9e7f4b4b68d313fb20949082c0a982..7155f9965a76c8ced554a64d6ca38e9638c30e53 100644 (file)
@@ -1397,7 +1397,7 @@ execute_split_functions (void)
     }
   /* This can be relaxed; function might become inlinable after splitting
      away the uninlinable part.  */
-  if (!inline_summary (node)->inlinable)
+  if (inline_edge_summary_vec && !inline_summary (node)->inlinable)
     {
       if (dump_file)
        fprintf (dump_file, "Not splitting: not inlinable.\n");
index 9329d9b2375acca470f4505d6f031a48b42d9658..e270591807711f7cde661500867695c67cbc8d9d 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -448,6 +448,11 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
   verify_symtab ();
 #endif
 
+  /* If we removed something, perhaps profile could be improved.  */
+  if (changed && optimize && inline_edge_summary_vec)
+    FOR_EACH_DEFINED_FUNCTION (node)
+      cgraph_propagate_frequency (node);
+
   return changed;
 }
 
@@ -960,6 +965,34 @@ struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
  }
 };
 
+/* Free inline summary.  */
+
+static unsigned
+free_inline_summary (void)
+{
+  inline_free_summary ();
+  return 0;
+}
+
+struct simple_ipa_opt_pass pass_ipa_free_inline_summary =
+{
+ {
+  SIMPLE_IPA_PASS,
+  "*free_inline_summary",              /* name */
+  NULL,                                        /* gate */
+  free_inline_summary,                 /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_IPA_FREE_INLINE_SUMMARY,          /* tv_id */
+  0,                                   /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_ggc_collect                     /* todo_flags_finish */
+ }
+};
+
 /* Do not re-run on ltrans stage.  */
 
 static bool
index 877a768515afa97e41aea77613772b09d0aa89f9..31e1f25a67d400ffc6e729c80787f9b36bcc8228 100644 (file)
@@ -1323,6 +1323,7 @@ init_optimization_passes (void)
       NEXT_PASS (pass_rebuild_cgraph_edges);
       NEXT_PASS (pass_inline_parameters);
     }
+  NEXT_PASS (pass_ipa_free_inline_summary);
   NEXT_PASS (pass_ipa_tree_profile);
     {
       struct opt_pass **p = &pass_ipa_tree_profile.pass.sub;
index 18d419daa47a66e4f904e30ab7941a757d65521c..8fa1a2bf4aa925f202009cce3a86485e6c033315 100644 (file)
@@ -89,6 +89,7 @@ DEFTIMEVAR (TV_IPA_PURE_CONST        , "ipa pure const")
 DEFTIMEVAR (TV_IPA_PTA               , "ipa points-to")
 DEFTIMEVAR (TV_IPA_SRA               , "ipa SRA")
 DEFTIMEVAR (TV_IPA_FREE_LANG_DATA    , "ipa free lang data")
+DEFTIMEVAR (TV_IPA_FREE_INLINE_SUMMARY, "ipa free inline summary")
 /* Time spent by constructing CFG.  */
 DEFTIMEVAR (TV_CFG                   , "cfg construction")
 /* Time spent by cleaning up CFG.  */
index 80ff51302eda2fc3d8b62d5eb00ff0d07dc18d11..4be92f491af921b61f54452a05a4360e2c38507d 100644 (file)
@@ -375,6 +375,7 @@ extern struct simple_ipa_opt_pass pass_ipa_increase_alignment;
 extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
 extern struct ipa_opt_pass_d pass_ipa_inline;
 extern struct simple_ipa_opt_pass pass_ipa_free_lang_data;
+extern struct simple_ipa_opt_pass pass_ipa_free_inline_summary;
 extern struct ipa_opt_pass_d pass_ipa_cp;
 extern struct ipa_opt_pass_d pass_ipa_reference;
 extern struct ipa_opt_pass_d pass_ipa_pure_const;