Commit d6ea70a0 by Jakub Jelinek Committed by Jakub Jelinek

re PR ipa/82801 (Internal compiler error with Eigen and __attribute__((always_inline, flatten)))

	PR ipa/82801
	PR ipa/83346
	* ipa-inline.c (flatten_remove_node_hook): New function.
	(ipa_inline): Keep only nodes with flatten attribute at the end of
	the array in the order from ipa_reverse_postorder, only walk that
	portion of array for flattening, if there is more than one such
	node, temporarily register a removal hook and ignore removed nodes.

	* g++.dg/ipa/pr82801.C: New test.

From-SVN: r255805
parent 497742ef
2017-12-19 Jakub Jelinek <jakub@redhat.com> 2017-12-19 Jakub Jelinek <jakub@redhat.com>
PR ipa/82801
PR ipa/83346
* ipa-inline.c (flatten_remove_node_hook): New function.
(ipa_inline): Keep only nodes with flatten attribute at the end of
the array in the order from ipa_reverse_postorder, only walk that
portion of array for flattening, if there is more than one such
node, temporarily register a removal hook and ignore removed nodes.
PR tree-optimization/80631 PR tree-optimization/80631
* tree-vect-loop.c (vect_create_epilog_for_reduction): Compare * tree-vect-loop.c (vect_create_epilog_for_reduction): Compare
induc_code against MAX_EXPR or MIN_EXPR instead of reduc_fn against induc_code against MAX_EXPR or MIN_EXPR instead of reduc_fn against
...@@ -2338,6 +2338,19 @@ dump_inline_stats (void) ...@@ -2338,6 +2338,19 @@ dump_inline_stats (void)
(int) reason[i][1], reason_freq[i].to_double (), reason[i][0]); (int) reason[i][1], reason_freq[i].to_double (), reason[i][0]);
} }
/* Called when node is removed. */
static void
flatten_remove_node_hook (struct cgraph_node *node, void *data)
{
if (lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) == NULL)
return;
hash_set<struct cgraph_node *> *removed
= (hash_set<struct cgraph_node *> *) data;
removed->add (node);
}
/* Decide on the inlining. We do so in the topological order to avoid /* Decide on the inlining. We do so in the topological order to avoid
expenses on updating data structures. */ expenses on updating data structures. */
...@@ -2347,7 +2360,7 @@ ipa_inline (void) ...@@ -2347,7 +2360,7 @@ ipa_inline (void)
struct cgraph_node *node; struct cgraph_node *node;
int nnodes; int nnodes;
struct cgraph_node **order; struct cgraph_node **order;
int i; int i, j;
int cold; int cold;
bool remove_functions = false; bool remove_functions = false;
...@@ -2380,26 +2393,56 @@ ipa_inline (void) ...@@ -2380,26 +2393,56 @@ ipa_inline (void)
if (dump_file) if (dump_file)
fprintf (dump_file, "\nFlattening functions:\n"); fprintf (dump_file, "\nFlattening functions:\n");
/* First shrink order array, so that it only contains nodes with
flatten attribute. */
for (i = nnodes - 1, j = i; i >= 0; i--)
{
node = order[i];
if (lookup_attribute ("flatten",
DECL_ATTRIBUTES (node->decl)) != NULL)
order[j--] = order[i];
}
/* After the above loop, order[j + 1] ... order[nnodes - 1] contain
nodes with flatten attribute. If there is more than one such
node, we need to register a node removal hook, as flatten_function
could remove other nodes with flatten attribute. See PR82801. */
struct cgraph_node_hook_list *node_removal_hook_holder = NULL;
hash_set<struct cgraph_node *> *flatten_removed_nodes = NULL;
if (j < nnodes - 2)
{
flatten_removed_nodes = new hash_set<struct cgraph_node *>;
node_removal_hook_holder
= symtab->add_cgraph_removal_hook (&flatten_remove_node_hook,
flatten_removed_nodes);
}
/* In the first pass handle functions to be flattened. Do this with /* In the first pass handle functions to be flattened. Do this with
a priority so none of our later choices will make this impossible. */ a priority so none of our later choices will make this impossible. */
for (i = nnodes - 1; i >= 0; i--) for (i = nnodes - 1; i > j; i--)
{ {
node = order[i]; node = order[i];
if (flatten_removed_nodes
&& flatten_removed_nodes->contains (node))
continue;
/* Handle nodes to be flattened. /* Handle nodes to be flattened.
Ideally when processing callees we stop inlining at the Ideally when processing callees we stop inlining at the
entry of cycles, possibly cloning that entry point and entry of cycles, possibly cloning that entry point and
try to flatten itself turning it into a self-recursive try to flatten itself turning it into a self-recursive
function. */ function. */
if (lookup_attribute ("flatten", if (dump_file)
DECL_ATTRIBUTES (node->decl)) != NULL) fprintf (dump_file, "Flattening %s\n", node->name ());
{ flatten_function (node, false);
if (dump_file) }
fprintf (dump_file,
"Flattening %s\n", node->name ()); if (j < nnodes - 2)
flatten_function (node, false); {
} symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
delete flatten_removed_nodes;
} }
free (order);
if (dump_file) if (dump_file)
dump_overall_stats (); dump_overall_stats ();
...@@ -2411,7 +2454,6 @@ ipa_inline (void) ...@@ -2411,7 +2454,6 @@ ipa_inline (void)
inline functions and virtual functions so we really know what is called inline functions and virtual functions so we really know what is called
once. */ once. */
symtab->remove_unreachable_nodes (dump_file); symtab->remove_unreachable_nodes (dump_file);
free (order);
/* Inline functions with a property that after inlining into all callers the /* Inline functions with a property that after inlining into all callers the
code size will shrink because the out-of-line copy is eliminated. code size will shrink because the out-of-line copy is eliminated.
......
2017-12-19 Jakub Jelinek <jakub@redhat.com>
PR ipa/82801
PR ipa/83346
* g++.dg/ipa/pr82801.C: New test.
2017-12-18 Martin Sebor <msebor@redhat.com> 2017-12-18 Martin Sebor <msebor@redhat.com>
PR middle-end/83373 PR middle-end/83373
......
// PR ipa/82801
// { dg-do compile }
// { dg-options "-O2 -Wno-attributes" }
template<int>
struct A { A () {} };
struct B { double foo () const; };
__attribute__((always_inline, flatten))
double B::foo () const
{
A<1> v;
return 0.0;
}
int
main ()
{
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment