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:
Jan Hubicka 2007-02-04 14:01:13 +01:00 committed by Jan Hubicka
parent 3075a4cd08
commit 22ad64b60c
2 changed files with 140 additions and 36 deletions

View File

@ -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,

View File

@ -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)
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;
}
/* Otherwise it is time to give up. */ /* Otherwise it is time to give up. */
else else
{ {
@ -1170,7 +1179,8 @@ 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));
} }
cgraph_mark_inline (e); if (e->inline_failed)
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
recurse here, since the inlined functions might not be processed by recurse here, since the inlined functions might not be processed by
@ -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)
fprintf (dump_file, " Flattening %s\n", cgraph_node_name (node)); {
indent_to (dump_file, depth);
fprintf (dump_file, "Flattening %s\n", cgraph_node_name (node));
}
mode = INLINE_ALL; mode = INLINE_ALL;
} }
@ -1216,49 +1230,130 @@ 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
it in order to fully flatten the leaves. */
if (!e->inline_failed && mode == INLINE_ALL)
{ {
fprintf (dump_file, " Ignoring %s: SSA form not computed yet.\n", 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)); cgraph_node_name (e->callee));
} }
if ((e->callee->local.disregard_inline_limits if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed))
|| (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); 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 if (!e->callee->local.inlinable
&& !e->callee->local.disregard_inline_limits || !e->inline_failed
&& !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed) || e->callee->local.disregard_inline_limits)
&& (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl)) continue;
== gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl))) if (dump_file)
&& (mode != INLINE_SIZE fprintf (dump_file, "Considering inline candidate %s.\n",
|| (cgraph_estimate_size_after_inlining (1, e->caller, e->callee) cgraph_node_name (e->callee));
<= e->caller->global.insns)) if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed))
&& cgraph_check_inline_limits (node, e->callee, &e->inline_failed, {
false) if (dump_file)
&& (DECL_SAVED_TREE (e->callee->decl) || e->callee->inline_decl)) {
{ indent_to (dump_file, depth);
if (cgraph_default_inline_p (e->callee, &failed_reason)) fprintf (dump_file, "Not inlining: recursive call.\n");
inlined |= try_inline (e, mode, depth); }
else if (!flag_unit_at_a_time) continue;
e->inline_failed = failed_reason; }
} 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))
inlined |= try_inline (e, mode, depth);
else if (!flag_unit_at_a_time)
e->inline_failed = failed_reason;
}
node->aux = (void *)(size_t) old_mode; node->aux = (void *)(size_t) old_mode;
return inlined; return inlined;
} }