llvm是一个底层编译器,它最大的优点是将后端和前端分开,所以广义的llvm指的是一个llvm前端,llvm中端和llvm后端。所以如果需要支持一种新语言,只需要实现一个新的前端;如果需要支持一个新的目标架构,只需要实现一个后端。前端和后端的纽带就是LLVM IR。
前端:将一个源程序转成一个LLVM IR的编译器过程:要经过语法分析器,词法分析器,语义分析器,LLVM IR生成器等,clang执行了与前端有关的一些步骤。
后端:用于汇编码和机器码的生成。将LLVM IR转换成目标架构的汇编代码或者二进制代码。
LLVM IR:中间表示,llvm优化器会对IR做优化。
llvm IR的中间表示有三种形式(1).ll(文本可读);(2).bc(二进制文件)(3)内存代码
.ll文件结构;
(1)Module(模板):是llvm IR的顶级容器,包含目标机器信息等信息。
(2)function(函数):包含很多基本快。
(3)basicblock(基本块):包含很多指令,基本块最后的指令会指向跳转的基本块。
(4)instruction(指令):llvm ir中最小的可执行单位,没个指令占一行。
.ll文件中的标识符:
@为前缀的是全局变量;%为前缀的是局部变量。
标识符以前缀为开头的两个原因:
(1)为了避免于保留关键字发生冲突,如果以后需要将关键字进行扩展,就不会产生麻烦。
(2)如果有没有命名的变量,可以直接命名,而不用担心与字符表发生冲突。
局部变量的分类:
(1)按照是否命名来分类;
命名类:如%a;
非命名类:编译器会自动按照阿拉伯数字生成,如%1;
(2)按照分配方式分类:
寄存器分配的局部变量;%1 = some value;
栈分配的局部变量:%a = alloca value ;栈分配的局部变量,访问和存储只能用load和store。