gpt4 book ai didi

c - 分配器的 LLVM/Clang 特例

转载 作者:太空狗 更新时间:2023-10-29 17:03:50 26 4
gpt4 key购买 nike

如果你在“alloc.c”中有如下代码:

typedef __typeof__(sizeof(int)) size_t;

extern void *calloc (size_t __nmemb, size_t __size)
__attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) ;
extern void free (void *__ptr) __attribute__ ((__nothrow__ ));

struct _astruct {
int l;
};


int main() {
struct _astruct *f = (struct _astruct*)calloc(1, sizeof(struct _astruct));
f->l = 99;
int x = f->l;
free(f);
return x;
}

(我知道这不是声明 calloc/free 的首选方式,但这是为了简化下面的输出。)

然后你用 Clang/LLVM 3.3 运行“clang -O3 -S -emit-llvm alloc.c”,你会得到:

; ModuleID = 'alloc.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nounwind readnone uwtable
define i32 @main() #0 {
entry:
ret i32 99
}

attributes #0 = { nounwind readnone uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }

您可以看到它完全消除了对 calloc 的调用。惊人的。不过,一般来说,编译器无法消除对它没有源代码的函数的调用(可能会有副作用)。所以看起来 Clang 有 calloc/free 的特例代码。如果您将代码中所有出现的“calloc”更改为“_calloc”,则“分配”会返回,这一事实支持了这一点。

所以我的问题是,是否有任何方式告诉 Clang/LLVM 某个特定函数是“仅分配”函数?也许我可以在我自己的函数之一的定义上加上一些注释,这将允许 LLVM 优化分配,就像它可以为 calloc/malloc 一样。

最佳答案

is there any way to tell Clang/LLVM that a particular function is an "allocation only" function?

没有。正如您正确指出的那样,在一般情况下,只有在编译器可以访问其实现* 时才有可能消除调用。对 calloc 的支持在 LLVM 中进行了硬编码(请参阅 LLVM 的“MemoryBuiltins”和“TargetLibraryInfo”类),这就是在您的示例中消除调用的方式。

没有任何属性可以向编译器发出某个函数将尝试分配内存的信号。


*:好吧,如果该函数被标记为绝对没有可能的副作用,则可能是可行的,但目前无法在 LLVM 中标记类似的东西,请参阅 this related discussion ;在任何情况下,分配内存的函数肯定会产生副作用。

关于c - 分配器的 LLVM/Clang 特例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19351423/

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