summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/ipa-fnsummary.c5
-rw-r--r--gcc/ipa.c59
-rw-r--r--gcc/passes.c35
-rw-r--r--gcc/passes.def1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c4
7 files changed, 89 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a18ba9d543..44ca2cefb3e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 9cb7d41ccc5..23b7821dcc1 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -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:
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 22c21354f75..89fb1da50fd 100644
--- 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)))
{
diff --git a/gcc/passes.c b/gcc/passes.c
index 5d2372bac24..85aa47d5c81 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -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 =
diff --git a/gcc/passes.def b/gcc/passes.def
index 24f212c8e31..82ad9404b9e 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 32c0f3d6381..4ec625f1768 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c b/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c
index 264ca3f0349..b1f4f8545a1 100644
--- a/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ctor-empty-1.c
@@ -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" } } */