gpt4 book ai didi

clang - 为什么 LLVM 语言中有一些内在函数?

转载 作者:行者123 更新时间:2023-12-02 09:39:55 46 4
gpt4 key购买 nike

我发现LLVM中有一些内在函数例如llvm.memcpyllvm.va_start

但是我不知道为什么它们存在而其他人不存在。例如,由于 memcpy 的原型(prototype)位于 string.h 内部,为什么其他函数(如 strcpy)不被视为内在函数?

我注意到前端在某些情况下可能会生成特殊的内部函数调用。对于一个简单的情况:

#include<string.h>

int foo(void){
char str[10] = "str";
return 0;
}

由 clang 生成的 foo 的 llvm IR 为:

define i32 @foo() #0 {
entry:
%str = alloca [10 x i8], align 1
%0 = bitcast [10 x i8]* %str to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* getelementptr inbounds ([10 x i8]* @foo.str, i32 0, i32 0), i64 10, i32 1, i1 false)
ret i32 0
}

llvm.memcpy 在 IR 中被调用,但不在源代码中。但是如果没有这个内在函数,前端可以生成 LLVM IR 吗?

我还发现了一份关于 a much earlier version of llvm language reference 的文档发现LLVM指令中包含了一些特殊函数,如mallocfree(显然它们已经不存在了)。

那么llvm指令这样设计有什么深意呢?

最佳答案

当然,您可以在没有 memcpy 的情况下执行示例所示的操作 - 只是有点困难(好吧,也许不仅仅使用 4 个字节,这可以通过四个单字节移动完成,并不比 memcpy 难多少 - 另一方面,如果初始化 str 的字符串是 128 个字节[并且 str 足够长以容纳它],则 128 个单字节移动的序列将相当尴尬,并且生成循环也有点困难笨拙)。

但是,内部函数的要点是允许编译器(后端)“理解发生了什么”,因为它将能够确定[至少对于常量]副本的大小,例如,生成两个 32 位移动,将 "str" 值存储到 str 变量中。或者,如果数量很大,请调用真正的 memcpy,或针对中间大小进行循环。

最后,简单的答案是“因为编译器可以生成比替代解决方案更好的代码”。

我猜,没有 strcpy 的原因是 strcpy 可以用 memcpy 替换(更有效)以获取常量字符串,如果字符串不是常量,strcpy 无论如何都会比 memcpy 复杂一点,因此对于进行内联优化没有那么有利。

理论上,所有类型的功能都可以成为内在的,但必须进行“成本/ yield ”分析 - 您可以获得多少 yield ,以及编写代码来实现这一点需要多长时间。

[当然,我只是根据我使用 LLVM 的经验推断出这一点,我不知道从在 LLVM 中实现内部函数的人那里知道这一点]

关于clang - 为什么 LLVM 语言中有一些内在函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25302796/

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