aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-09-06 17:02:03 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-09-06 15:02:03 +0000
commita81b0a3dbb7fa136464e2ce2d1e6702856791f9d (patch)
tree2aa9d9f0740c50c4ce621530f1171f0ea5625b08 /gcc
parent68e4ca7e493804a8426d78094ca4e146e0b8828e (diff)
downloadgcc-a81b0a3dbb7fa136464e2ce2d1e6702856791f9d.zip
gcc-a81b0a3dbb7fa136464e2ce2d1e6702856791f9d.tar.gz
gcc-a81b0a3dbb7fa136464e2ce2d1e6702856791f9d.tar.bz2
re PR middle-end/58094 (IPA devirt testsuite errors)
PR middle-end/58094 * ipa-inline.c (has_caller_p): New function. (want_inline_function_to_all_callers_p): Use it. (sum_callers, inline_to_all_callers): Break out from ... (ipa_inline): ... here. From-SVN: r202337
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-inline.c103
2 files changed, 77 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b9d8589..21c36b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2013-09-06 Jan Hubicka <jh@suse.cz>
+ PR middle-end/58094
+ * ipa-inline.c (has_caller_p): New function.
+ (want_inline_function_to_all_callers_p): Use it.
+ (sum_callers, inline_to_all_callers): Break out from ...
+ (ipa_inline): ... here.
+
+2013-09-06 Jan Hubicka <jh@suse.cz>
+
* i386.c (ix86_hard_regno_mode_ok): AVX modes are valid only when
AVX is enabled.
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 9a9408e..1e22d6e 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -750,6 +750,15 @@ check_caller_edge (struct cgraph_node *node, void *edge)
&& node->callers != edge);
}
+/* If NODE has a caller, return true. */
+
+static bool
+has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+{
+ if (node->callers)
+ return true;
+ return false;
+}
/* Decide if inlining NODE would reduce unit size by eliminating
the offline copy of function.
@@ -763,7 +772,7 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
bool has_hot_call = false;
/* Does it have callers? */
- if (!node->callers)
+ if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true))
return false;
/* Already inlined? */
if (function->global.inlined_to)
@@ -1892,6 +1901,60 @@ flatten_function (struct cgraph_node *node, bool early)
inline_update_overall_summary (node);
}
+/* Count number of callers of NODE and store it into DATA (that
+ points to int. Worker for cgraph_for_node_and_aliases. */
+
+static bool
+sum_callers (struct cgraph_node *node, void *data)
+{
+ struct cgraph_edge *e;
+ int *num_calls = (int *)data;
+
+ for (e = node->callers; e; e = e->next_caller)
+ (*num_calls)++;
+ return false;
+}
+
+/* Inline NODE to all callers. Worker for cgraph_for_node_and_aliases.
+ DATA points to number of calls originally found so we avoid infinite
+ recursion. */
+
+static bool
+inline_to_all_callers (struct cgraph_node *node, void *data)
+{
+ int *num_calls = (int *)data;
+ while (node->callers && !node->global.inlined_to)
+ {
+ struct cgraph_node *caller = node->callers->caller;
+
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ "\nInlining %s size %i.\n",
+ cgraph_node_name (node),
+ inline_summary (node)->size);
+ fprintf (dump_file,
+ " Called once from %s %i insns.\n",
+ cgraph_node_name (node->callers->caller),
+ inline_summary (node->callers->caller)->size);
+ }
+
+ inline_call (node->callers, true, NULL, NULL, true);
+ if (dump_file)
+ fprintf (dump_file,
+ " Inlined into %s which now has %i size\n",
+ cgraph_node_name (caller),
+ inline_summary (caller)->size);
+ if (!(*num_calls)--)
+ {
+ if (dump_file)
+ fprintf (dump_file, "New calls found; giving up.\n");
+ break;
+ }
+ }
+ return false;
+}
+
/* Decide on the inlining. We do so in the topological order to avoid
expenses on updating data structures. */
@@ -2003,39 +2066,11 @@ ipa_inline (void)
&& want_inline_function_to_all_callers_p (node, cold))
{
int num_calls = 0;
- struct cgraph_edge *e;
- for (e = node->callers; e; e = e->next_caller)
- num_calls++;
- while (node->callers && !node->global.inlined_to)
- {
- struct cgraph_node *caller = node->callers->caller;
-
- if (dump_file)
- {
- fprintf (dump_file,
- "\nInlining %s size %i.\n",
- cgraph_node_name (node),
- inline_summary (node)->size);
- fprintf (dump_file,
- " Called once from %s %i insns.\n",
- cgraph_node_name (node->callers->caller),
- inline_summary (node->callers->caller)->size);
- }
-
- inline_call (node->callers, true, NULL, NULL, true);
- remove_functions = true;
- if (dump_file)
- fprintf (dump_file,
- " Inlined into %s which now has %i size\n",
- cgraph_node_name (caller),
- inline_summary (caller)->size);
- if (!num_calls--)
- {
- if (dump_file)
- fprintf (dump_file, "New calls found; giving up.\n");
- break;
- }
- }
+ cgraph_for_node_and_aliases (node, sum_callers,
+ &num_calls, true);
+ cgraph_for_node_and_aliases (node, inline_to_all_callers,
+ &num_calls, true);
+ remove_functions = true;
}
}
}