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: [PATCH] S390: Refactor ifunc handling


On 12/06/2018 09:47 PM, Joseph Myers wrote:
On Thu, 6 Dec 2018, Adhemerval Zanella wrote:

builds with loader selecting the path depending of the hwcap value). I really
would like we we move to deprecate and remove the --with-cpu option, so we
have basically just two variants (enable and disable multiarch).

I'd like to deprecate and remove --with-cpu - but replace it with the
default CPU being automatically determined by how the compiler behaves
(see <https://sourceware.org/ml/libc-alpha/2017-02/msg00154.html>).
The current approach on s390 is not to use submachine but to have configure checks for each needed CPU which are responsible for setting macro defines in config.h. Those checks are e.g. using an inline assembly with a vector instruction to determine if z13 vector instructions are supported as default. E.g. gcc -march=z13 -msoft-float would lead to frecord-gcc-switches-output:
.ascii	"-march=z13"
...
.ascii	"-msoft-float"
But the assembler fails with "Error: Unrecognized opcode <vector-instruction>" as the vector instructions are implicitly disabled by -msoft-float.


Avoiding building in lots of function variants for CPUs older than the
minimum supported still seems appropriate to me.  What I don't know is if
there is a good way to design things with the following properties:

* IFUNC function variants are handled the same way for all architectures.
I assume all are using the __ifunc macros from include/libc-symbols.h.

Some archs are using an ifunc'ed __GI_* symbol which jumps over plt-stub. Some archs like s390-32 can't do that as the plt-stub needs a setuped GOT pointer in r12. But r12 does not need to be setuped for usual internal calls. Thus the __GI_* symbol is equivalent to the oldest available ifunc variant.

Unfortunately defining the __GI_* symbol needs to be done in the compile unit of the used ifunc variant or the ifunc'ed symbol itself. Therefore this logic is spread over multiple places instead of one common place (perhaps within the __ifunc macro).


* A function is automatically not an IFUNC if the minimum supported CPU
implies one particular version would always be used.

* If more than one function might be used based on the minimum supported
CPU, all those that wouldn't ever be used automatically get compiled out.

* A single optimal version (choice based on the compiler's code
generation) is automatically selected in the non-multiarch case.

My patches are introducing ifunc-*.h files which decides if ifunc is needed for a specific function depending on no-/multiarch, libc/ldso and the minimum supported CPU. At the end there is one macro HAVE_<FUNCTION>_IFUNC with the value 0 or 1.

Afterwards there is a decision which ifunc variants will be available depending on the minimum supported CPU and if we have ifunc or not. Older variants than the minimum supported CPU won't be available. At the end there are multiple macros HAVE_<FUNCTION>_<VARIANT> with value 0 or 1. E.g. if multiarch is not available there is only one macro per function with 1 and all others are 0.

The ifunc-*.h files are included in several files and those macros are used to:
-compile or not compile a specific variant
-generating ifunc-resolver expressions which only choose between the available ifunc variants and generating the ifunc-symbol or just an alias to the one available variant.
-using the minimum available ifunc variant as the "__GI_* symbol".
-if ifunc is needed, the available ifunc variants are added in ifunc-impl-list.

As it depends on the used gcc/binutils which parts (variants, ifunc-resolver, ...) will be needed, either all the stuff needs to be in one file like sysdeps/arch/function.x or there will be multiple files specified as sysdep_routines in the Makefile.

As you can't mix a function implementation (in an assembler file) and the __ifunc macro (c-code) you'll automatically need multiple files.

The multiarch subdirectory cannot be used to distinguish "default"- vs "enhanced"-ifunc-variants. There is not the one "default"-variant as this depends on the used gcc/binutils. Thus all files are moved to sysdeps/s390/ and will always be build. But depending on the needed parts some resulting object-files can be empty.


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