LLVM IR 中的 `declare` 如何工作
How does `declare` in LLVM IR works
例如
@.str = private unnamed_addr constant [13 x i8] c"hello world[=10=]A[=10=]"
declare i32 @puts(i8* nocapture) nounwind
define i32 @main() {
%cast210 = getelementptr [13 x i8], [13 x i8]* @.str, i64 0, i64 0
call i32 @puts(i8* %cast210)
ret i32 0
}
我不明白函数puts
是从哪里来的。好像是stdio.h
中的C函数,但这跟LLVM有什么关系呢?它的实现在哪里?
用C/C++术语来说,每个翻译单元都可以引用外部符号。对于编译器来说,只要你有一个声明,符号在哪里实际定义并不重要。
编译 .c
文件后,您会得到一些需要链接在一起的东西(对象文件 .o
或 LLVM IR .ll
/.bc
)。在链接阶段,所有符号定义都被解析(以不同的方式)。
在您的示例中,puts
函数通常位于系统 libc
中,默认情况下会自动链接。你不会找到这个函数的 LLVM IR 代码,除非你以某种方式将整个 libc
编译成 LLVM IR。
阅读一些关于“编译和链接”主题的一般教程。
例如
@.str = private unnamed_addr constant [13 x i8] c"hello world[=10=]A[=10=]"
declare i32 @puts(i8* nocapture) nounwind
define i32 @main() {
%cast210 = getelementptr [13 x i8], [13 x i8]* @.str, i64 0, i64 0
call i32 @puts(i8* %cast210)
ret i32 0
}
我不明白函数puts
是从哪里来的。好像是stdio.h
中的C函数,但这跟LLVM有什么关系呢?它的实现在哪里?
用C/C++术语来说,每个翻译单元都可以引用外部符号。对于编译器来说,只要你有一个声明,符号在哪里实际定义并不重要。
编译 .c
文件后,您会得到一些需要链接在一起的东西(对象文件 .o
或 LLVM IR .ll
/.bc
)。在链接阶段,所有符号定义都被解析(以不同的方式)。
在您的示例中,puts
函数通常位于系统 libc
中,默认情况下会自动链接。你不会找到这个函数的 LLVM IR 代码,除非你以某种方式将整个 libc
编译成 LLVM IR。
阅读一些关于“编译和链接”主题的一般教程。