re PR ipa/87706 (Inlined functions trigger invalid -Wmissing-profile warning)
authorJan Hubicka <hubicka@ucw.cz>
Tue, 20 Nov 2018 13:25:04 +0000 (14:25 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 20 Nov 2018 13:25:04 +0000 (13:25 +0000)
PR ipa/87706
* ipa-fnsummary.c (pass_ipa_fnsummary): Do not remove functions
* ipa.c (possible_inline_candidate_p): Break out from ..
(process_references): ... here ; drop before_inlining_p;
cleanup handling of alises.
(walk_polymorphic_call_targets): Likewise.
(symbol_table::remove_unreachable_nodes): Likewise.
* passes.c (pass_data_ipa_remove_symbols): New structure.
(pass_ipa_remove_symbols): New pass.
(make_pass_ipa_remove_symbols): New functoin.
* passes.def (pass_ipa_remove_symbols): Schedule after early passes.

From-SVN: r266315

gcc/ChangeLog
gcc/ipa-fnsummary.c
gcc/ipa.c
gcc/passes.c
gcc/passes.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c

index 5a18ba9d54342779c3b9864e2d251750a4506d70..44ca2cefb3e268ab1d9dd2ae9a586b82857ec4c4 100644 (file)
@@ -1,3 +1,17 @@
+2018-11-20  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/87706
+       * ipa-fnsummary.c (pass_ipa_fnsummary): Do not remove functions
+       * ipa.c (possible_inline_candidate_p): Break out from ..
+       (process_references): ... here ; drop before_inlining_p;
+       cleanup handling of alises.
+       (walk_polymorphic_call_targets): Likewise.
+       (symbol_table::remove_unreachable_nodes): Likewise.
+       * passes.c (pass_data_ipa_remove_symbols): New structure.
+       (pass_ipa_remove_symbols): New pass.
+       (make_pass_ipa_remove_symbols): New functoin.
+       * passes.def (pass_ipa_remove_symbols): Schedule after early passes.
+
 2018-11-20  Richard Biener  <rguenther@suse.de>
 
        * tree-vect-stmts.c (vectorizable_condition): Do not get
index 9cb7d41ccc5a06bba8b4b1c9e580bcf93a862310..23b7821dcc1af167d59c682ab5bb44708532f6ba 100644 (file)
@@ -3563,10 +3563,7 @@ public:
   virtual unsigned int execute (function *)
     {
       ipa_free_fn_summary ();
-      /* Early optimizations may make function unreachable.  We can not
-        remove unreachable functions as part of the early opts pass because
-        TODOs are run before subpasses.  Do it here.  */
-      return small_p ? TODO_remove_functions | TODO_dump_symtab : 0;
+      return 0;
     }
 
 private:
index 22c21354f7521e6e1346baf682657732bd1894ba..89fb1da50fd42fd0e3e926c530ec699822efbaa1 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -101,12 +101,32 @@ enqueue_node (symtab_node *node, symtab_node **first,
   *first = node;
 }
 
+/* Return true if NODE may get inlined later.
+   This is used to keep DECL_EXTERNAL function bodies around long enough
+   so inliner can proces them.  */
+
+static bool
+possible_inline_candidate_p (symtab_node *node)
+{
+  if (symtab->state >= IPA_SSA_AFTER_INLINING)
+    return false;
+  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+  if (!cnode)
+    return false;
+  if (DECL_UNINLINABLE (cnode->decl))
+    return false;
+  if (opt_for_fn (cnode->decl, optimize))
+    return true;
+  if (symtab->state >= IPA_SSA)
+    return false;
+  return lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl));
+}
+
 /* Process references.  */
 
 static void
 process_references (symtab_node *snode,
                    symtab_node **first,
-                   bool before_inlining_p,
                    hash_set<symtab_node *> *reachable)
 {
   int i;
@@ -118,14 +138,7 @@ process_references (symtab_node *snode,
 
       if (node->definition && !node->in_other_partition
          && ((!DECL_EXTERNAL (node->decl) || node->alias)
-             || (((before_inlining_p
-                   && (TREE_CODE (node->decl) != FUNCTION_DECL
-                       || (TREE_CODE (node->decl) == FUNCTION_DECL
-                           && opt_for_fn (body->decl, optimize))
-                       || (symtab->state < IPA_SSA
-                           && lookup_attribute
-                                ("always_inline",
-                                 DECL_ATTRIBUTES (body->decl))))))
+             || (possible_inline_candidate_p (node)
                  /* We use variable constructors during late compilation for
                     constant folding.  Keep references alive so partitioning
                     knows about potential references.  */
@@ -140,7 +153,7 @@ process_references (symtab_node *snode,
             body.  */
          if (DECL_EXTERNAL (node->decl)
              && node->alias
-             && before_inlining_p)
+             && symtab->state < IPA_SSA_AFTER_INLINING)
            reachable->add (body);
          reachable->add (node);
        }
@@ -160,8 +173,7 @@ static void
 walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
                               struct cgraph_edge *edge,
                               symtab_node **first,
-                              hash_set<symtab_node *> *reachable,
-                              bool before_inlining_p)
+                              hash_set<symtab_node *> *reachable)
 {
   unsigned int i;
   void *cache_token;
@@ -190,15 +202,14 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
          /* Prior inlining, keep alive bodies of possible targets for
             devirtualization.  */
          if (n->definition
-             && (before_inlining_p
-                 && opt_for_fn (body->decl, optimize)
+             && (possible_inline_candidate_p (body)
                  && opt_for_fn (body->decl, flag_devirtualize)))
             {
                /* Be sure that we will not optimize out alias target
                   body.  */
                if (DECL_EXTERNAL (n->decl)
                    && n->alias
-                   && before_inlining_p)
+                   && symtab->state < IPA_SSA_AFTER_INLINING)
                  reachable->add (body);
               reachable->add (n);
             }
@@ -303,8 +314,6 @@ symbol_table::remove_unreachable_nodes (FILE *file)
   hash_set<symtab_node *> reachable;
   hash_set<tree> body_needed_for_clonning;
   hash_set<void *> reachable_call_targets;
-  bool before_inlining_p = symtab->state < (!optimize && !in_lto_p ? IPA_SSA
-                                           : IPA_SSA_AFTER_INLINING);
 
   timevar_push (TV_IPA_UNREACHABLE);
   build_type_inheritance_graph ();
@@ -396,7 +405,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
                  enqueue_node (next, &first, &reachable);
            }
          /* Mark references as reachable.  */
-         process_references (node, &first, before_inlining_p, &reachable);
+         process_references (node, &first, &reachable);
        }
 
       if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
@@ -416,8 +425,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
                      next = e->next_callee;
                      if (e->indirect_info->polymorphic)
                        walk_polymorphic_call_targets (&reachable_call_targets,
-                                                      e, &first, &reachable,
-                                                      before_inlining_p);
+                                                      e, &first, &reachable);
                    }
                }
              for (e = cnode->callees; e; e = e->next_callee)
@@ -428,18 +436,13 @@ symbol_table::remove_unreachable_nodes (FILE *file)
                      && (!e->inline_failed
                          || !DECL_EXTERNAL (e->callee->decl)
                          || e->callee->alias
-                         || (before_inlining_p
-                             && (opt_for_fn (body->decl, optimize)
-                                 || (symtab->state < IPA_SSA
-                                     && lookup_attribute
-                                         ("always_inline",
-                                          DECL_ATTRIBUTES (body->decl)))))))
+                         || possible_inline_candidate_p (e->callee)))
                    {
                      /* Be sure that we will not optimize out alias target
                         body.  */
                      if (DECL_EXTERNAL (e->callee->decl)
                          && e->callee->alias
-                         && before_inlining_p)
+                         && symtab->state < IPA_SSA_AFTER_INLINING)
                        reachable.add (body);
                      reachable.add (e->callee);
                    }
@@ -654,7 +657,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
                   of possible later devirtualization.  Do not mark them as
                   local too early so we won't optimize them out before
                   we are done with polymorphic call analysis.  */
-               && (!before_inlining_p
+               && (symtab->state >= IPA_SSA_AFTER_INLINING
                    || !node->call_for_symbol_and_aliases
                       (is_indirect_call_target_p, NULL, true)))
              {
index 5d2372bac24408d9d1abf1085bcbe35ef82ef829..85aa47d5c81e5719e638bc4b5f60b4df6b1ab592 100644 (file)
@@ -459,6 +459,35 @@ public:
 
 }; // class pass_local_optimization_passes
 
+const pass_data pass_data_ipa_remove_symbols =
+{
+  SIMPLE_IPA_PASS, /* type */
+  "remove_symbols", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_NONE, /* tv_id */
+  0, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  TODO_remove_functions | TODO_dump_symtab, /* todo_flags_finish */
+};
+
+class pass_ipa_remove_symbols : public simple_ipa_opt_pass
+{
+public:
+  pass_ipa_remove_symbols (gcc::context *ctxt)
+    : simple_ipa_opt_pass (pass_data_ipa_remove_symbols, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual bool gate (function *)
+    {
+      /* Don't bother doing anything if the program has errors.  */
+      return (!seen_error () && !in_lto_p);
+    }
+
+}; // class pass_local_optimization_passes
+
 } // anon namespace
 
 simple_ipa_opt_pass *
@@ -473,6 +502,12 @@ make_pass_local_optimization_passes (gcc::context *ctxt)
   return new pass_local_optimization_passes (ctxt);
 }
 
+simple_ipa_opt_pass *
+make_pass_ipa_remove_symbols (gcc::context *ctxt)
+{
+  return new pass_ipa_remove_symbols (ctxt);
+}
+
 namespace {
 
 const pass_data pass_data_all_early_optimizations =
index 24f212c8e31b3def4948838f87824fd10fa3ca31..82ad9404b9e27f24f41bf4cfda4c30730507f96e 100644 (file)
@@ -106,6 +106,7 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_local_fn_summary);
   POP_INSERT_PASSES ()
 
+  NEXT_PASS (pass_ipa_remove_symbols);
   NEXT_PASS (pass_ipa_oacc);
   PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc)
       NEXT_PASS (pass_ipa_pta);
index 32c0f3d638107dcd2236b15fcb419a31b7542f3e..4ec625f17689efeca84dc4d2b7919ee30c5e3b2e 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-20  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/87706
+       * gcc.dg/ipa/ctor-empty-1.c: Update template.
+
 2018-11-20  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/88074
index 264ca3f0349c776fc2b5cf8eca6ccaf1b199d06d..b1f4f8545a17ca2bf6cc56aa6c1fbe4abd9c3197 100644 (file)
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -c -fdump-ipa-free-fnsummary1"  } */
+/* { dg-options "-O3 -c -fdump-ipa-remove_symbols"  } */
 static __attribute__((constructor))
 void empty_constructor()
 {
 }
-/* { dg-final { scan-ipa-dump "Reclaiming functions: empty_constructor"  "free-fnsummary1"  } } */
+/* { dg-final { scan-ipa-dump "Reclaiming functions: empty_constructor"  "remove_symbols"  } } */