gpt4 book ai didi

c - 与一般内联相比,为什么 gnu_inline 属性对代码生成的影响如此之大?

转载 作者:太空宇宙 更新时间:2023-11-04 03:11:33 25 4
gpt4 key购买 nike

为什么在 static inline 上使用 extern inline __attribute__((gnu_inline)) 会如此影响 GCC 8.3 代码生成?

The example code基于 glibc bsearch 代码(使用 -O3 构建):

#include <stddef.h>

extern inline __attribute__((gnu_inline))
void *bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size,
int (*__compar)(const void *, const void *))
{
size_t __l, __u, __idx;
const void *__p;
int __comparison;

__l = 0;
__u = __nmemb;
while (__l < __u) {
__idx = (__l + __u) / 2;
__p = (void *) (((const char *) __base) + (__idx * __size));
__comparison = (*__compar) (__key, __p);
if (__comparison < 0)
__u = __idx;
else if (__comparison > 0)
__l = __idx + 1;
else
return (void *) __p;
}

return NULL;
}

static int comp_int(const void *a, const void *b)
{
int l = *(const int *) a, r = *(const int *) b;
if (l > r) return 1;
else if (l < r) return -1;
else return 0;
}

int *bsearch_int(int key, const int *data, size_t num)
{
return bsearch(&key, data, num, sizeof(int), &comp_int);
}

bsearch_int 函数生成的代码是:

bsearch_int:
test rdx, rdx
je .L6
xor r8d, r8d
.L5:
lea rcx, [rdx+r8]
shr rcx
lea rax, [rsi+rcx*4]
cmp DWORD PTR [rax], edi
jl .L3
jg .L10
ret
.L10:
mov rdx, rcx
.L4:
cmp rdx, r8
ja .L5
.L6:
xor eax, eax
ret
.L3:
lea r8, [rcx+1]
jmp .L4

如果我使用 static inline 而不是 extern inline __attribute__((gnu_inline)) 我会得到更大的代码:

bsearch_int:
xor r8d, r8d
test rdx, rdx
je .L11
.L2:
lea rcx, [r8+rdx]
shr rcx
lea rax, [rsi+rcx*4]
cmp edi, DWORD PTR [rax]
jg .L7
jl .L17
.L1:
ret
.L17:
cmp r8, rcx
jnb .L11
lea rdx, [r8+rcx]
shr rdx
lea rax, [rsi+rdx*4]
cmp edi, DWORD PTR [rax]
jg .L12
jge .L1
cmp r8, rdx
jnb .L11
.L6:
lea rcx, [r8+rdx]
shr rcx
lea rax, [rsi+rcx*4]
cmp DWORD PTR [rax], edi
jl .L7
jle .L1
mov rdx, rcx
cmp r8, rdx
jb .L6
.L11:
xor eax, eax
.L18:
ret
.L12:
mov rax, rcx
mov rcx, rdx
mov rdx, rax
.L7:
lea r8, [rcx+1]
cmp r8, rdx
jb .L2
xor eax, eax
jmp .L18

是什么让 GCC 在第一种情况下生成如此短的代码?

注意事项:

  • Clang 似乎不受此影响。

最佳答案

它只能编译,因为您没有使用任何优化并且内联未激活。例如,尝试使用 -O1,您的代码将根本无法编译。

代码是不同的,因为当您使用 static 时,编译器不必关心调用约定,因为该函数对其他编译单元不可见。

关于c - 与一般内联相比,为什么 gnu_inline 属性对代码生成的影响如此之大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55884502/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com