Re: C: inline without forcing?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, May 31, 2021 at 2:04 AM Xi Ruoyao <xry111@xxxxxxxxxxxxxxxx> wrote:
>
> On Sun, 2021-05-30 at 20:34 -0400, Danielle Church via Gcc-help wrote:
> >
> > On the other hand, if I concatenate these files and compile them as a
> > single translation unit, I'll still end up with two functions in my
> > library, but if foo() is simple enough, the bar() implementation will
> > probably inline it rather than emitting a call instruction. Better!
>
> Negative.  In this case ELF spec mandates to call foo() via PLT.  The
> compiler can't inline it since the inlining will break semantic
> interposition, unless -fno-semantic-interposition is explicitly used.

Apologies; I should have specified that foo() and bar() in this case
are not public symbols. Let's just assume that
-fno-semantic-interposition is being used for all compilation here,
because I care much less about the linking mechanics (which may or may
not be ELF, since this is intended to be a portable library) than I do
about the compilation and optimization GCC performs.

> > What I'd really like to do is make some subset of foo.c's
> > function definitions available to bar.c in case GCC decides it's
> > worthwhile to inline them, but not compile any of these as
> > standalone. C99 provides *almost* the exact semantics
> > I'm looking for:
> >
> > ===foo.c is unchanged, or:===
> > extern inline int foo(int x) { return x * 2; }
> >
> > ===bar.c===
> > inline int foo(int x) { return x * 2; }
> > int bar(int x) { return foo(x + 1); }
> >
> > The only problem is that GCC is now significantly more likely to
> > inline foo(), regardless of whether it's a good idea or not. I'm not
> > trying to "force" the optimizer to do the inlining, or even
> > "suggest" it.
>
> The problem here is the compiler doesn't know the two definitions of
> "foo" are same, so it can do nothing; the linker doesn't know there is
> nobody taking the two foo's addresses, so it can not merge them (C99
> mandates the address of two different functions different).

I'm fairly certain that's incorrect, by the C99 standard? As per C99
6.7.4, a function declared as "inline" but neither "static" nor
"extern" is an "inline definition" in that TU, which "provides an
alternative to an external definition" that the compiler may or may
not use during any calls to that function. So yes, GCC should be
assuming that the inline definition (in bar.c) and the external
definition (in foo.c) do in fact represent the same function, and it
may choose to emit either the inline or the external call without
change of semantics.

> I think the only rational way is using -fno-semantic-interposition, and
> put the definition of foo & bar into the same TU (or using -flto).

Unfortunately, -flto seems to give me *worse* performance than
standard compilation. Not sure what's up with that; perhaps it
interacts badly with PGO? I don't know.

In any case; does this mean that the only way to put a function
definition into a file without GCC emitting standalone code for it is
to use the C99 inline keyword, which alters the behavior of the
optimizer? Is there no way to get the code-emit behavior (inline the
function or emit a TU-external reference, don't emit standalone
definition) without the optimizer changes (more likely to inline the
function, even if it's a bad idea)?

-Danielle Church



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux