The upcomming gcc 3.4 has a new inlining algorithm which sometimes
fails to inline some "dumb" inlines in the kernel. This sometimes leads
to undefined symbols while linking.
To make the kernel compile again this patch drops the always inline
for gcc 3.4. The new algorithm should be good enough to do the right
thing on its own.
-Andi
diff -u linux-34/include/linux/compiler-gcc3.h-o linux-34/include/linux/compiler-gcc3.h
--- linux-34/include/linux/compiler-gcc3.h-o 2003-09-28 10:53:23.000000000 +0200
+++ linux-34/include/linux/compiler-gcc3.h 2004-01-13 22:36:22.000000000 +0100
@@ -3,7 +3,9 @@
/* These definitions are for GCC v3.x. */
#include <linux/compiler-gcc.h>
-#if __GNUC_MINOR__ >= 1
+/* gcc 3.4 has a new inlining algorithm and always_inline seems to
+ do more harm than good now. */
+#if __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 4
# define inline __inline__ __attribute__((always_inline))
# define __inline__ __inline__ __attribute__((always_inline))
# define __inline __inline__ __attribute__((always_inline))
Andi Kleen <[email protected]> wrote:
>
>
> The upcomming gcc 3.4 has a new inlining algorithm which sometimes
> fails to inline some "dumb" inlines in the kernel. This sometimes leads
> to undefined symbols while linking.
That's a compiler bug, surely.
> To make the kernel compile again this patch drops the always inline
> for gcc 3.4. The new algorithm should be good enough to do the right
> thing on its own.
Are you sure? Without the always_inline stuff we were seeing 100 different
copies of __constant_c_and_count_memset and friends in the vmlinux symbol
table. It was really silly.
After applying this patch and building with gcc-3.4, how does `size
vmlinux' compare with the same kernel built with gcc-3.3, minus the patch?
On Wed, Jan 14, 2004 at 09:37:00AM +0100, Andi Kleen wrote:
>
> The upcomming gcc 3.4 has a new inlining algorithm which sometimes
> fails to inline some "dumb" inlines in the kernel. This sometimes leads
> to undefined symbols while linking.
It fails to inline routines with always_inline attribute?
That sounds like a gcc bug. always_inline should mean inline always,
and issue error if for some reason it is impossible.
Jakub
On Wed, Jan 14, 2004 at 03:47:22AM -0500, Jakub Jelinek wrote:
> On Wed, Jan 14, 2004 at 09:37:00AM +0100, Andi Kleen wrote:
> >
> > The upcomming gcc 3.4 has a new inlining algorithm which sometimes
> > fails to inline some "dumb" inlines in the kernel. This sometimes leads
> > to undefined symbols while linking.
>
> It fails to inline routines with always_inline attribute?
> That sounds like a gcc bug. always_inline should mean inline always,
> and issue error if for some reason it is impossible.
The problem is that there are some functions that are declared
inline in header files, but there is no body available. When they are
called this ends with an hard error in gcc. I started with fixing
them but eventually gave up because there were so many of them.
In addition you get tons of ugly warnings.
-Andi
On Wed, Jan 14, 2004 at 12:49:44AM -0800, Andrew Morton wrote:
> Andi Kleen <[email protected]> wrote:
> >
> >
> > The upcomming gcc 3.4 has a new inlining algorithm which sometimes
> > fails to inline some "dumb" inlines in the kernel. This sometimes leads
> > to undefined symbols while linking.
>
> That's a compiler bug, surely.
See my mail to Jakub.
>
> > To make the kernel compile again this patch drops the always inline
> > for gcc 3.4. The new algorithm should be good enough to do the right
> > thing on its own.
>
> Are you sure? Without the always_inline stuff we were seeing 100 different
> copies of __constant_c_and_count_memset and friends in the vmlinux symbol
> table. It was really silly.
>
That was with the old inliner. The new one is completely different
and should do better, especially with -funit-at-a-time. In fact there were
still a few no inlines for __builtin_constant_p stuff, but Jan fixed them
now (it was one small left over buglet in the inlining
heuristics). Should be fixed soon in gcc mainline.
I have another patch to compile with -Winline (submitted shortly)
which catches all these issues easily.
> After applying this patch and building with gcc-3.4, how does `size
> vmlinux' compare with the same kernel built with gcc-3.3, minus the patch?
I can only compare to a 3.3-hammer branch compiler, which is a kind
of mixture between 3.3 and 3.4 and already has an older version of the
inliner.
Better is to use -Winline. You get a warning then
There was only one warning for copy_*_user stuff somewhere in XFS because
it bloated an ioctl function considerably. There are many other
inlining warnings too, but these seemed to be mostly kernel bugs
(stuff declared inline in headers without bodies etc.)
I think fixing copy_*_user with extern inline would be better so that a
out of line copy_from_user is used in this case (I can prepare a patch for
that if you're interested)
-Andi
> On Wed, Jan 14, 2004 at 03:47:22AM -0500, Jakub Jelinek wrote:
> > On Wed, Jan 14, 2004 at 09:37:00AM +0100, Andi Kleen wrote:
> > >
> > > The upcomming gcc 3.4 has a new inlining algorithm which sometimes
> > > fails to inline some "dumb" inlines in the kernel. This sometimes leads
> > > to undefined symbols while linking.
> >
> > It fails to inline routines with always_inline attribute?
> > That sounds like a gcc bug. always_inline should mean inline always,
> > and issue error if for some reason it is impossible.
>
> The problem is that there are some functions that are declared
> inline in header files, but there is no body available. When they are
> called this ends with an hard error in gcc. I started with fixing
> them but eventually gave up because there were so many of them.
>
> In addition you get tons of ugly warnings.
Yes, this is not really bug, but the simple fact that if compler never
see the function body, it can not inline it. Old compilers accepted
this by mystake, as always_inline is supposed to cause hard error each
time function failes to be inlined.
I made testing with equivalent of Andi's patch and with my last fixes to
GCC code size estimate, there are 50 calls in the whole kernel where GCC
concludes that inlining is not good idea. I plan to investigate these
too, but there is simple --param knob you may want to use if you really
think these are sane.
For a record, I made patch that fixes all the cases for my default
configuration. You may consider it applying together with Andi's patch,
so -Winline output does not contain unnecesary complains.
I am also attaching the list of warnings I get during build. The
parameter inlie-unit-growth is specifying the maximal growth (in
percent) number of instruction can increase within single source file by
inlining. As Kernel does a lot of inlining and has small sources,
perhaps adjusting up from 50% makes sense. Perhaps I will do this
default in GCC too.
Honza