This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH?] Implement exp and log builtins as x86 intrinsics
- From: Roger Sayle <roger at eyesopen dot com>
- To: Fergus Henderson <fjh at cs dot mu dot oz dot au>
- Cc: Richard Henderson <rth at twiddle dot net>, <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 4 Aug 2002 17:07:00 -0600 (MDT)
- Subject: Re: [PATCH?] Implement exp and log builtins as x86 intrinsics
Hi Fergus,
> > The main point was that the code would get inlined, as is done by
> > Microsoft's MSVC and Intel's compilers, for example.
>
> It will already get inlined with GCC currently, if the library defines
> it appropriately, as is done by the GNU C library.
This is a property of the system headers and not the compiler. Yes,
glibc defines "exp" and "log" as __asm__ for GCC on Linux, but this
doesn't help for newlib based system's such as cygwin or for Microsoft
Windows. As I mentioned above both Microsoft's and Intel's compilers
can inline "exp" and "log" without help from <math.h>.
There's also the issue that glibc's use of __asm__ can generate worse
code in some cases. Firstly, GCC's handling of builtins already can
specify their function attributes, such as "const" or "pure". So with
"-ffast-math" the expression, "sqrt(x)+sqrt(x)" will generate the
code "tmp=sqrt(x),tmp+tmp", i.e. one call to sqrt when using builtins
but two nicely inlined "fsqrt" instructions when using glibc's macros.
Secondly, overriding GCC's macros removes some of the constant
folding transformations that may be achieved at compile time.
Number one on my wish list is evaluation of math functions with
arbitrary constant arguments, but alas that would require emulator
support. But there are also the following transformations:
sqrt(0) = 0
sqrt(1) = 1
log(1) = 0
exp(0) = 1
fabs(sqrt(x)) = sqrt(x)
fabs(exp(x)) = exp(x)
sqrt(x)*sqrt(y) = sqrt(x*y)
exp(x)*exp(y) = exp(x+y)
a*sqrt(b*x) = sqrt(a*a*b*x)
exp(log(x)) = x
log(exp(x)) = x
x/exp(y) = x*exp(-y)
sqrt(exp(x)) = exp(0.5*x)
log(sqrt(x)) = 0.5*log(x)
You'll be pleased to hear that I've been working on a patch
to implement many of the above, including the classic
"whetstone optimization". Unfortunately, not expanding libm
functions as __asm__ macros may give non-linux platforms a
performance advantage due to glibc's current headers.
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833