LLVM IR 基本概念#
参考:LLVM IR 基本概念
编译器常见的作用是将源高级语言的代码编译到某种中间表示(Intermediate Representation,一般称为 IR),然后再将 IR 翻译为目标体系结构(具体硬件比如 MIPS 或 X86)的汇编语言或者硬件指令。 LLVM IR 提供了一种抽象层,使程序员可以更灵活地控制程序的编译和优化过程,同时保留了与硬件无关的特性。通过使用 LLVM IR,开发人员可以更好地理解程序的行为,提高代码的可移植性和性能优化的可能性。
LLVM IR 示例与语法#
编写简单的 C 语言程序,并将其编译为 LLVM IR。
temp_dir = ".temp"
!mkdir -p $temp_dir
%%file $temp_dir/test.c
#include <stdio.h>
void test(int a, int b)
{
int c = a + b;
}
int main(void)
{
int a = 10;
int b = 20;
test(a, b);
return 0;
}
Writing .temp/test.c
使用 Clang 编译器将 C 语言源文件 test.c
编译成 LLVM 格式的中间代码。具体参数的含义如下:
clang
:Clang 编译器-S
:生成汇编代码而非目标文件-emit-llvm
:生成 LLVM IR 中间代码test.c
:要编译的 C 语言源文件
!clang -S -emit-llvm $temp_dir/test.c -o $temp_dir/test.ll
在 LLVM IR 中,所生成的 .ll
文件的基本语法为:
指令以分号
;
开头表示注释全局表示以
@
开头,局部变量以%
开头使用
define
关键字定义函数,在本例中定义了两个函数:@test
和@main
alloca
指令用于在堆栈上分配内存,类似于 C 语言中的变量声明store
指令用于将值存储到指定地址load
指令用于加载指定地址的值add
指令用于对两个操作数进行加法运算i32
32 位 4 个字节的意思align
字节对齐ret
指令用于从函数返回