This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Out-of-order inlining and --param values
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 07 Nov 2002 12:50:58 +0000
- Subject: Out-of-order inlining and --param values
Sigh. I have the feeling I'm being really dense here, but...
If you compile something like this with -finline-functions:
void foo () { ... bar (); ... }
void bar () { ... }
is it expected that bar() will only be inlined into foo()
if foo() has less than --param max-inline-insns-single
instructions? (I think it used to be max-inline-insns/2,
before Kurt's patch). I couldn't find any mention of it
in the archives.
If the order is reversed, a small bar() can be always be
inlined into foo(), regardless of how big foo() is.
But in the out-of-order case, both the caller and callee
seem to be limited by the same parameter, which isn't
what I was expecting.
On the face of it, it seems quite easy to make out-of-order
inlining use the same heuristics as in-order. So how
intentional is the current set-up?
I was thinking of something like the patch below, which survives
a bootstrap and regression test on i686-pc-linux-gnu (mainline),
although 990508-1.c needs a noinline attribute to pass.
I tried running a benchmark that has large main-like functions
followed by small inlinable functions, and the smaller functions
are now inlined as expected.
BTW, part of the patch reverts:
2001-11-21 Jakub Jelinek <jakub@redhat.com>
* c-decl.c (c_expand_deferred_function): Only call c_expand_body
if fndecl is still DECL_INLINE and has DECL_RESULT.
but I checked that the test cases added there still pass, as does
the original glibc test case. I haven't yet tracked down why.
Richard
* c-decl.c (c_expand_deferred_function): Expand all functions.
(c_expand_body): Defer non-inlinable functions for -finline-functions.
testsuite/
* gcc.c-torture/execute/990208-1.c (bar): Add a noinline attribute.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.352
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.352 c-decl.c
*** c-decl.c 19 Oct 2002 03:14:08 -0000 1.352
--- c-decl.c 7 Nov 2002 11:28:56 -0000
*************** void
*** 6402,6414 ****
c_expand_deferred_function (fndecl)
tree fndecl;
{
! /* DECL_INLINE or DECL_RESULT might got cleared after the inline
! function was deferred, e.g. in duplicate_decls. */
! if (DECL_INLINE (fndecl) && DECL_RESULT (fndecl))
! {
! c_expand_body (fndecl, 0, 0);
! current_function_decl = NULL;
! }
}
/* Generate the RTL for the body of FNDECL. If NESTED_P is nonzero,
--- 6402,6409 ----
c_expand_deferred_function (fndecl)
tree fndecl;
{
! c_expand_body (fndecl, 0, 0);
! current_function_decl = NULL;
}
/* Generate the RTL for the body of FNDECL. If NESTED_P is nonzero,
*************** c_expand_body (fndecl, nested_p, can_def
*** 6436,6442 ****
timevar_push (TV_INTEGRATION);
uninlinable = ! tree_inlinable_function_p (fndecl);
! if (! uninlinable && can_defer_p
/* Save function tree for inlining. Should return 0 if the
language does not support function deferring or the
function could not be deferred. */
--- 6431,6438 ----
timevar_push (TV_INTEGRATION);
uninlinable = ! tree_inlinable_function_p (fndecl);
! if ((!uninlinable || flag_inline_trees == 2)
! && can_defer_p
/* Save function tree for inlining. Should return 0 if the
language does not support function deferring or the
function could not be deferred. */
Index: testsuite/gcc.c-torture/execute/990208-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/990208-1.c,v
retrieving revision 1.3
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.3 990208-1.c
*** testsuite/gcc.c-torture/execute/990208-1.c 12 May 2000 16:51:20 -0000 1.3
--- testsuite/gcc.c-torture/execute/990208-1.c 7 Nov 2002 11:28:57 -0000
*************** #endif
*** 40,46 ****
exit (0);
}
! void bar(void) { }
#else /* NO_LABEL_VALUES */
int main() { exit(0); }
--- 40,46 ----
exit (0);
}
! void __attribute__((noinline)) bar(void) { }
#else /* NO_LABEL_VALUES */
int main() { exit(0); }