[cfe-dev] Using IFUNC with template functions

Fāng-ruì Sòng via cfe-dev cfe-dev at lists.llvm.org
Wed Nov 18 09:52:07 PST 2020


On Wed, Nov 18, 2020 at 9:42 AM Amrita H S via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
>
> Hi All,
>
> I want to have a template function as an ifunc. Find below my test program.
>
> // Test Program
> #include <iostream>
>
> int glob_t = 2;
> typedef void (*VOID_FUNC_P)(void);
>
> template <typename T>
> T add_isa1(T x, T y) {
>    std::cout << "ISA1 implementation" << std::endl;
>    return x + y;
> }
>
> template <typename T>
> T add_isa2(T x, T y) {
>    std::cout << "ISA2 implementation" << std::endl;
>    return x + y;
> }
>
> template <typename T>
> static VOID_FUNC_P add_resolver(void) {
>    T (*T_p)(T,T) = NULL;
>    switch (glob_t) {
>       case 1:
>               T_p = add_isa1;
>               break;
>       case 2:
>               T_p = add_isa2;
>               break;
>    }
>    return reinterpret_cast<VOID_FUNC_P>(T_p);
> }
>
> template VOID_FUNC_P add_resolver<int>(void);
> template VOID_FUNC_P add_resolver<double>(void);
>
> // explicit/manual instantiation of possibilities
> int add(int, int) __attribute((ifunc("_Z12add_resolverIiEPFvvEv")));
> double add(double, double) __attribute((ifunc("_Z12add_resolverIdEPFvvEv")));
>
> int main()
> {
>    //int res = add(1,68);
>    double res = add(1.68,68.01);
>    std::cout << "Res = " << res << std::endl;
>    return 0;
> }
>
>
> I have to explicitly declare the ifunc resolver function for all possible combinations of template arguments. In reality, I think it would be impractical for programmers to do this kind of manual/explicit instantiation.
> I am interested to know if there any other better way to use ifuncs with template functions. If there is none, is it worth suggesting to the C++ standards?
>
>
> Thanks and Regards,
> Amrita H S

A GNU indirect function is very similar to a function pointer. For a
function pointer, the compiler produces code that loads the address
and does an indirect jump.
For an ifunc call, the compiler produces code that does a normal
function call and the PLT entry loads the address and does an indirect
jump. This is convenient in few cases because the caller does not need
to know whether it is a function/ifunc.

For your use cases, can you just use a function pointer?


More information about the cfe-dev mailing list