Date: Sat, 28 Feb 2009 18:43:54 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Alexander Kabaev <kabaev@gmail.com> Cc: Ed Schouten <ed@80386.nl>, Roman Divacky <rdivacky@freebsd.org>, FreeBSD@freebsd.org, Andriy Gapon <avg@icyb.net.ua>, Arch <freebsd-arch@freebsd.org> Subject: Re: Making LLVM happy: memmove() in the kernel Message-ID: <20090228175724.D14305@delplex.bde.org> In-Reply-To: <20090227132242.4ef6a633@kan.dnsalias.net> References: <20090227131155.GE19161@hoeg.nl> <20090227131221.GA60215@freebsd.org> <49A80F4D.8000406@icyb.net.ua> <20090227132242.4ef6a633@kan.dnsalias.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 27 Feb 2009, Alexander Kabaev wrote: > On Fri, 27 Feb 2009 18:05:33 +0200 > Andriy Gapon <avg@icyb.net.ua> wrote: > >> on 27/02/2009 15:12 Roman Divacky said the following: >>> On Fri, Feb 27, 2009 at 02:11:55PM +0100, Ed Schouten wrote: >>>> Hi all, >>>> >>>> The FreeBSD+LLVM folks* noticed Clang generates calls to memmove() >>>> by itself. I have yet to confirm this, but I assume this is done >>>> when performing copies of structs greater than a certain size. In Why would Clang be that broken? Structs cannot overlap, so they can be copied by memcpy() which should be faster. (However, in the FreeBSD kernel, use of memcpy() is only approved for fixed-sized copies small enough to be inlined, so memcpy() is only a placeholder for the non-inlined case and for abuse, and extensive optimizations are only applied to bcopy() and bcopy() might be faster; however2, the optimizations don't work for any current hardware so memcpy() should be faster than bcopy() because it is simpler. The inlining also fails in all cases since _all_ gcc builtins were turned off many years as a side effect of using -ffreestanding (see below for more details). The loss was so insignficant that no one noticed it. Even now, with the placeholders for memcpy() and memset() abused a lot, fixing their inlining makes no significant difference.) >>>> our kernel, we don't have a memmove() function, but we do have a >>>> bcopy(). >>> >>> also.. quoting from >>> (http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Standards.html): >>> >>> Most of the compiler support routines used by GCC are present in >>> libgcc, but there are a few exceptions. GCC requires the >>> freestanding environment provide memcpy, memmove, memset and memcmp. >>> >>> we were just lucky to not run into this Since this is a bug in gcc, we were unlucky to run into it. These functions are in the application namespace in freestanding environments. Compiler support functions must be named something like __memmove(). FreeBSD started using -ffreestanding mainly to avoid related bugs. The gcc builtin for printf() sometimes translates printf() to use puts() and perhaps any function in stdio. FreeBSD has printf() but not puts() in the kernel so linkage started failing when gcc implemented builtin printf (similarly for a couple of other standard library functions). The problem was fixed by compiling all FreeBSD kernels with -ffreestanding, which was implemented in gcc at about the same time that builtin printf was implemented. -ffreestanding must kill all standard library functions. But them it necessarily kills all builtins for such functions and thus prevents automatic inlining of everything in <string.h>. >> Some people actually were not that lucky and had to use similar >> workarounds. > > I think we should use this opportunity and make sure we have external > symbols for all of the above mem* functions, not just memmove. Please :) How do you make them fully external so that they are only used by broken external software? Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090228175724.D14305>