mirror of https://github.com/madler/zlib.git
Optimized functions for Power will make use of GNU indirect functions, an extension to support different implementations of the same function, which can be selected during runtime. This will be used to provide optimized functions for different processor versions. Since this is a GNU extension, we placed the definition of the Z_IFUNC macro under `contrib/gcc`. This can be reused by other archs as well. Author: Matheus Castanho <msc@linux.ibm.com> Author: Rogerio Alves <rcardoso@linux.ibm.com>pull/459/head
parent
ec3df00224
commit
4ec46f57bd
5 changed files with 205 additions and 0 deletions
@ -0,0 +1,60 @@ |
||||
/* Copyright (C) 2019 Matheus Castanho <msc@linux.ibm.com>, IBM
|
||||
* 2019 Rogerio Alves <rogerio.alves@ibm.com>, IBM |
||||
* For conditions of distribution and use, see copyright notice in zlib.h |
||||
*/ |
||||
|
||||
#ifndef Z_IFUNC_H_ |
||||
#define Z_IFUNC_H_ |
||||
|
||||
/* Helpers for arch optimizations */ |
||||
|
||||
#define Z_IFUNC(fname) \ |
||||
typeof(fname) fname __attribute__ ((ifunc (#fname "_resolver"))); \
|
||||
local typeof(fname) *fname##_resolver(void) |
||||
/* This is a helper macro to declare a resolver for an indirect function
|
||||
* (ifunc). Let's say you have function |
||||
* |
||||
* int foo (int a); |
||||
* |
||||
* for which you want to provide different implementations, for example: |
||||
* |
||||
* int foo_clever (int a) { |
||||
* ... clever things ... |
||||
* } |
||||
* |
||||
* int foo_smart (int a) { |
||||
* ... smart things ... |
||||
* } |
||||
* |
||||
* You will have to declare foo() as an indirect function and also provide a |
||||
* resolver for it, to choose between foo_clever() and foo_smart() based on |
||||
* some criteria you define (e.g. processor features). |
||||
* |
||||
* Since most likely foo() has a default implementation somewhere in zlib, you |
||||
* may have to rename it so the 'foo' symbol can be used by the ifunc without |
||||
* conflicts. |
||||
* |
||||
* #define foo foo_default |
||||
* int foo (int a) { |
||||
* ... |
||||
* } |
||||
* #undef foo |
||||
* |
||||
* Now you just have to provide a resolver function to choose which function |
||||
* should be used (decided at runtime on the first call to foo()): |
||||
* |
||||
* Z_IFUNC(foo) { |
||||
* if (... some condition ...) |
||||
* return foo_clever; |
||||
* |
||||
* if (... other condition ...) |
||||
* return foo_smart; |
||||
* |
||||
* return foo_default; |
||||
* } |
||||
* |
||||
* All calls to foo() throughout the code can remain untouched, all the magic |
||||
* will be done by the linker using the resolver function. |
||||
*/ |
||||
|
||||
#endif /* Z_IFUNC_H_ */ |
@ -0,0 +1,4 @@ |
||||
/* Copyright (C) 2019 Matheus Castanho <msc@linux.ibm.com>, IBM
|
||||
* 2019 Rogerio Alves <rogerio.alves@ibm.com>, IBM |
||||
* For conditions of distribution and use, see copyright notice in zlib.h |
||||
*/ |
Loading…
Reference in new issue