This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Improving math function wrappers
- From: Joseph Myers <joseph at codesourcery dot com>
- To: Wilco Dijkstra <Wilco dot Dijkstra at arm dot com>
- Cc: Szabolcs Nagy <Szabolcs dot Nagy at arm dot com>, "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>, nd <nd at arm dot com>
- Date: Thu, 16 Mar 2017 14:29:11 +0000
- Subject: Re: Improving math function wrappers
- Authentication-results: sourceware.org; auth=none
- References: <AM5PR0802MB2610AA7EDC518B39F6D7152683260@AM5PR0802MB2610.eurprd08.prod.outlook.com> <AM5PR0802MB261064538EBF55E8B7CF1F7783260@AM5PR0802MB2610.eurprd08.prod.outlook.com>
On Thu, 16 Mar 2017, Wilco Dijkstra wrote:
> Given other languages don't even have the concept of errno, C99 doesn't
> require it, and no application ever reads errno, it is inefficient to
> force the use of the wrappers in almost all cases.
C99 not requiring it was an incompatible quiet change from C90.
> Another possibility would be to merge the wrappers into their respective
> math functions. This is feasible since the IEEE versions must check for
> the same exceptional cases anyway. While this would increase complexity
> of math functions, it shouldn't affect the critical path for the common
> cases. However it would mean errno is sometimes set when it otherwise
> wouldn't be (with Ofast or when an IEEE math function is called
> internally). Also on some odd systems it might even result in extra
> messages being printed by __kernel_standard (can we obsolete that???).
My view is that merging errno-setting into the main implementations of the
various functions is reasonable - but it also involves a significant
amount of architecture-specific work where architecture-specific
implementations of those functions are involved, and it's quite likely the
code to set the TLS errno might vary depending on PIC versus non-PIC, with
the non-PIC case then not being well-tested. The case for it is a lot
more straightforward where there aren't any assembly implementations for
particular architectures. Adding *_noerrno exports for selected
functions, based on performance evidence, would also be reasonable (GCC 5
and above define __NO_MATH_ERRNO__ for -fno-math-errno, which can be used
to select such variants; of course for non-C-family languages the compiler
would need to know about such function variants).
(There may be cases where errno setting in the main implementations will
require adding checks there not currently present, if e.g. the function
does "return x - x;" in the non-finite argument case to return NaN and
also raise "invalid" for Inf arguments - but such cases should not
generally be significant for performance; the performance relevant cases
are those involving finite arguments and results, not error cases or NaNs
as arguments.)
As for __kernel_standard obsoletion, there are several useful steps that
can be done towards that:
* We now have the new wrappers that avoid checking _LIB_VERSION or calling
__kernel_standard, used for float128 to avoid matherr / _LIB_VERSION
support ever being part of the ABI for new types.
* The next step would be to make _LIB_VERSION, matherr and the ia64
variants matherrf, matherrl into compat symbols, so that new programs
cannot use that functionality. Documentation for matherr error handling
would be removed. libieee.a would no longer be installed. Something
would need to be done about the test for matherr support. Things would be
arranged so that new architectures no longer get exported symbols (even
compat symbols) for _LIB_VERSION or matherr (although some related code
might still be present internally).
* The next step after that would be to ensure that the new wrappers are
used in static libm, and in shared libm when the minimum symbol version
postdates the making of _LIB_VERSION into a compat symbol. New
architectures, and static libm would no longer have any __kernel_standard
code or code related to _LIB_VERSION / matherr.
* An optional step would be to use the new wrappers also on existing
architectures as new symbol versions for existing symbols that have
_LIB_VERSION / matherr support at their old symbol versions.
* If a function is changed to set errno directly in all its
implementations, so it no longer needs a wrapper except for legacy
_LIB_VERSION / matherr support, of course in the above for "new wrappers"
you can read "direct export of the main implementation without a wrapper"
(and the compat symbols for _LIB_VERSION / matherr support would just end
up setting errno redundantly in both the main implementation and the
wrapper).
* Given the different structure of ia64 libm, it seems plausible that
while the making into compat symbols of _LIB_VERSION etc. should be done
globally (to keep the API exported the same everywhere), some of the
subsequent steps might only be applied to non-ia64 architectures.
--
Joseph S. Myers
joseph@codesourcery.com