ipa-inline.c (try_inline): Improve debug output; work on already inline edges too.
* ipa-inline.c (try_inline): Improve debug output; work on already inline edges too. (cgraph_decide_inlining_incrementally): Indent; improve debug output; call try_inline for already inlined edges too when flattening; inline also functions that make callee growth but overall unit size reduce. From-SVN: r121570
This commit is contained in:
parent
3075a4cd08
commit
22ad64b60c
|
@ -1,3 +1,12 @@
|
||||||
|
2007-02-04 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
* ipa-inline.c (try_inline): Improve debug output; work on already
|
||||||
|
inline edges too.
|
||||||
|
(cgraph_decide_inlining_incrementally): Indent; improve debug output;
|
||||||
|
call try_inline for already inlined edges too when flattening;
|
||||||
|
inline also functions that make callee growth but overall unit size
|
||||||
|
reduce.
|
||||||
|
|
||||||
2007-02-04 Kazu Hirata <kazu@codesourcery.com>
|
2007-02-04 Kazu Hirata <kazu@codesourcery.com>
|
||||||
|
|
||||||
* config/m32c/bitops.md, config/m32c/jump.md,
|
* config/m32c/bitops.md, config/m32c/jump.md,
|
||||||
|
|
153
gcc/ipa-inline.c
153
gcc/ipa-inline.c
|
@ -1144,7 +1144,16 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth)
|
||||||
/* It is first time we see it and we are not in ALWAY_INLINE only
|
/* It is first time we see it and we are not in ALWAY_INLINE only
|
||||||
mode yet. and the function in question is always_inline. */
|
mode yet. and the function in question is always_inline. */
|
||||||
if (always_inline && mode != INLINE_ALWAYS_INLINE)
|
if (always_inline && mode != INLINE_ALWAYS_INLINE)
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Hit cycle in %s, switching to always inline only.\n",
|
||||||
|
cgraph_node_name (callee));
|
||||||
|
}
|
||||||
mode = INLINE_ALWAYS_INLINE;
|
mode = INLINE_ALWAYS_INLINE;
|
||||||
|
}
|
||||||
/* Otherwise it is time to give up. */
|
/* Otherwise it is time to give up. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1170,6 +1179,7 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth)
|
||||||
cgraph_node_name (e->callee),
|
cgraph_node_name (e->callee),
|
||||||
cgraph_node_name (e->caller));
|
cgraph_node_name (e->caller));
|
||||||
}
|
}
|
||||||
|
if (e->inline_failed)
|
||||||
cgraph_mark_inline (e);
|
cgraph_mark_inline (e);
|
||||||
|
|
||||||
/* In order to fully inline always_inline functions at -O0, we need to
|
/* In order to fully inline always_inline functions at -O0, we need to
|
||||||
|
@ -1189,7 +1199,8 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth)
|
||||||
DEPTH is depth of recursion, used only for debug output. */
|
DEPTH is depth of recursion, used only for debug output. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
cgraph_decide_inlining_incrementally (struct cgraph_node *node, enum inlining_mode mode,
|
cgraph_decide_inlining_incrementally (struct cgraph_node *node,
|
||||||
|
enum inlining_mode mode,
|
||||||
int depth)
|
int depth)
|
||||||
{
|
{
|
||||||
struct cgraph_edge *e;
|
struct cgraph_edge *e;
|
||||||
|
@ -1207,7 +1218,10 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, enum inlining_mo
|
||||||
&& lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) != NULL)
|
&& lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) != NULL)
|
||||||
{
|
{
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
fprintf (dump_file, "Flattening %s\n", cgraph_node_name (node));
|
fprintf (dump_file, "Flattening %s\n", cgraph_node_name (node));
|
||||||
|
}
|
||||||
mode = INLINE_ALL;
|
mode = INLINE_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,44 +1230,125 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, enum inlining_mo
|
||||||
/* First of all look for always inline functions. */
|
/* First of all look for always inline functions. */
|
||||||
for (e = node->callees; e; e = e->next_callee)
|
for (e = node->callees; e; e = e->next_callee)
|
||||||
{
|
{
|
||||||
if (dump_file && e->callee->local.inlinable
|
if (!e->callee->local.disregard_inline_limits
|
||||||
&& (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
|
&& (mode != INLINE_ALL || !e->callee->local.inlinable))
|
||||||
!= gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl))))
|
continue;
|
||||||
{
|
/* When the edge is already inlined, we just need to recurse into
|
||||||
fprintf (dump_file, " Ignoring %s: SSA form not computed yet.\n",
|
it in order to fully flatten the leaves. */
|
||||||
cgraph_node_name (e->callee));
|
if (!e->inline_failed && mode == INLINE_ALL)
|
||||||
}
|
|
||||||
if ((e->callee->local.disregard_inline_limits
|
|
||||||
|| (mode == INLINE_ALL && e->callee->local.inlinable))
|
|
||||||
&& e->inline_failed
|
|
||||||
&& (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
|
|
||||||
== gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl)))
|
|
||||||
&& !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
|
|
||||||
/* ??? It is possible that renaming variable removed the function body
|
|
||||||
in duplicate_decls. See gcc.c-torture/compile/20011119-2.c */
|
|
||||||
&& (DECL_SAVED_TREE (e->callee->decl) || e->callee->inline_decl))
|
|
||||||
{
|
{
|
||||||
inlined |= try_inline (e, mode, depth);
|
inlined |= try_inline (e, mode, depth);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Considering to always inline inline candidate %s.\n",
|
||||||
|
cgraph_node_name (e->callee));
|
||||||
|
}
|
||||||
|
if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed))
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file, "Not inlining: recursive call.\n");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
|
||||||
|
!= gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl)))
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file, "Not inlining: SSA form does not match.\n");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!DECL_SAVED_TREE (e->callee->decl) && !e->callee->inline_decl)
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Not inlining: Function body no longer available.\n");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
inlined |= try_inline (e, mode, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now do the automatic inlining. */
|
/* Now do the automatic inlining. */
|
||||||
if (!flag_really_no_inline && mode != INLINE_ALL
|
if (!flag_really_no_inline && mode != INLINE_ALL
|
||||||
&& mode != INLINE_ALWAYS_INLINE)
|
&& mode != INLINE_ALWAYS_INLINE)
|
||||||
for (e = node->callees; e; e = e->next_callee)
|
for (e = node->callees; e; e = e->next_callee)
|
||||||
if (e->callee->local.inlinable
|
|
||||||
&& e->inline_failed
|
|
||||||
&& !e->callee->local.disregard_inline_limits
|
|
||||||
&& !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
|
|
||||||
&& (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
|
|
||||||
== gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl)))
|
|
||||||
&& (mode != INLINE_SIZE
|
|
||||||
|| (cgraph_estimate_size_after_inlining (1, e->caller, e->callee)
|
|
||||||
<= e->caller->global.insns))
|
|
||||||
&& cgraph_check_inline_limits (node, e->callee, &e->inline_failed,
|
|
||||||
false)
|
|
||||||
&& (DECL_SAVED_TREE (e->callee->decl) || e->callee->inline_decl))
|
|
||||||
{
|
{
|
||||||
|
if (!e->callee->local.inlinable
|
||||||
|
|| !e->inline_failed
|
||||||
|
|| e->callee->local.disregard_inline_limits)
|
||||||
|
continue;
|
||||||
|
if (dump_file)
|
||||||
|
fprintf (dump_file, "Considering inline candidate %s.\n",
|
||||||
|
cgraph_node_name (e->callee));
|
||||||
|
if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed))
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file, "Not inlining: recursive call.\n");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
|
||||||
|
!= gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl)))
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file, "Not inlining: SSA form does not match.\n");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* When the function body would grow and inlining the function won't
|
||||||
|
elliminate the need for offline copy of the function, don't inline.
|
||||||
|
*/
|
||||||
|
if (mode == INLINE_SIZE
|
||||||
|
&& (cgraph_estimate_size_after_inlining (1, e->caller, e->callee)
|
||||||
|
> e->caller->global.insns)
|
||||||
|
&& cgraph_estimate_growth (e->callee) > 0)
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Not inlining: code size would grow by %i insns.\n",
|
||||||
|
cgraph_estimate_size_after_inlining (1, e->caller,
|
||||||
|
e->callee)
|
||||||
|
- e->caller->global.insns);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed,
|
||||||
|
false))
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file, "Not inlining: %s.\n", e->inline_failed);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!DECL_SAVED_TREE (e->callee->decl) && !e->callee->inline_decl)
|
||||||
|
{
|
||||||
|
if (dump_file)
|
||||||
|
{
|
||||||
|
indent_to (dump_file, depth);
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Not inlining: Function body no longer available.\n");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (cgraph_default_inline_p (e->callee, &failed_reason))
|
if (cgraph_default_inline_p (e->callee, &failed_reason))
|
||||||
inlined |= try_inline (e, mode, depth);
|
inlined |= try_inline (e, mode, depth);
|
||||||
else if (!flag_unit_at_a_time)
|
else if (!flag_unit_at_a_time)
|
||||||
|
|
Loading…
Reference in New Issue