为什么gcc使用jmp来调用优化版本中的函数

Met*_*est 5 c linux x86 gcc

当我组装我的程序时,我看到gcc在使用-O3编译时使用jmp进行第二次pthread_wait_barrier调用.为什么会这样?

使用jmp而不是call会有什么好处.编译器在这里玩什么技巧?我猜它在这里执行尾调用优化.

顺便说一下,我在这里使用静态链接.

__attribute__ ((noinline)) void my_pthread_barrier_wait( 
    volatile int tid, pthread_barrier_t *pbar ) 
{
    pthread_barrier_wait( pbar );
    if ( tid == 0 )
    {
        if ( !rollbacked )
        {
            take_checkpoint_or_rollback( ++iter == 4 );
        }
    }
    //getcontext( &context[tid] );
    SETJMP( tid );
    asm("addr2jmp:"); 
    pthread_barrier_wait( pbar );
    // My suspicion was right, gcc was performing tail call optimization, 
    // which was messing up with my SETJMP/LONGJMP implementation, so here I
    // put a dummy function to avoid that.
    dummy_var = dummy_func();
}
Run Code Online (Sandbox Code Playgroud)

glg*_*lgl 12

由于您没有显示示例,我只能猜测:被调用的函数与调用函数具有相同的返回类型,这就像

return func2(...)
Run Code Online (Sandbox Code Playgroud)

或根本没有返回类型(void).

在这种情况下,"我们"在堆栈上留下"我们的"返回地址,留给"他们"使用它来返回"我们的"调用者.


Bas*_*tch 6

也许这是一个尾递归的电话.GCC有一些传递做尾递归优化.

但你为什么要打扰?如果被调用的函数是一个extern函数,那么它是公共的,GCC应该遵循ABI约定来调用它(这意味着它遵循调用约定).

您不应该关心函数是否由jmp调用.

它也可能是对动态库函数的调用(即使用PLT进行动态链接)