This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Improving math function wrappers


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]