LLVM简介 https://zhuanlan.zhihu.com/p/488188552

前端:前端讲计算机程序语言(如C、C++和OC)转换为LLVM IR的编译步骤。它包括词法分析器、语法分析器、语义分析器和LLVM IR代码生成器。Clang项目提供了一个插件接口和一个单独的静态分析工具用于进行深度分析。
IR:LLVM IR既有用户可读的表示形式,也有二进制编码的表示形式。相应的工具和库提供了IR构建、组装和拆卸的接口。LLVM优化器还可以处理IR,以应用大多数优化。
后端:这是负责生成代码的步骤。后端讲LLVM IR转换为特定目标的汇编代码或目标代码二进制文件。寄存器分配、循环转换、窥视孔优化器以及特定于目标的优化转换属于后端。

LLVM基本概念入门 https://zhuanlan.zhihu.com/p/140462815

gcc的编译器,输入是源代码,输出是汇编代码,相当于是LLVM中Clang一级加上IR linker再加上LLVM compiler中的生成汇编代码部分(Clang输出可执行文件的一条龙过程,不会生成汇编文件,内部全部走中间表示,生成汇编码和生成目标文件是并列的)。
gcc的汇编器,输入是汇编代码,输出是目标文件,相当于是LLVM中的llvm-mc(这是另一个工具,Clang一条龙默认不走这个工具,但会调用相同的库来做汇编指令的下降和发射)。
gcc的链接器,输入是目标文件,输出是最终可执行文件,相当于LLVM中的Linker,现在LLVM Linker还在开发中(已释出,叫lld,但仍然不成熟),所以Clang驱动程序调起来的链接器还是系统链接器,可以选择使用gcc的ld(这块会很快变,LLVM社区必然会在lld成熟后默认换上去,大家可以自行验证)。

clang,是现在LLVM项目中一个很重要的前端工具。clang能够调用起来整个编译器的流程,也就是上边其他工具调用的库,它很多都同样会调用。clang通过指定-emit-llvm参数,可以配合-S或-c生成.ll或.bc文件,这样我们就能把clang的部分和LLVM的后端分离开来独立运行,对于观察编译器流程来说,很实用。

clang -emit-llvm -c main.c -o main.bc
clang -emit-llvm -S main.c -o main.ll

LLVM IR简介 https://zhuanlan.zhihu.com/p/200613850

LLVM IR(Intermediate Representation,中间表示)连接着编译器前端和编译器后端。IR的设计很大程度体现着LLVM插件化、模块化的设计哲学,LLVM的各种pass其实都是作用在LLVM IR上的。同时IR也是一个编译器组件接口。通常情况下,设计一门新的编程语言只需要完成能够生成LLVM IR的编译器前端即可,然后就可以轻松使用LLVM的各种编译优化、JIT支持、目标代码生成等功能。

内存中的IR模型
内存中IR模型其实就是对应LLVM实现中的OO模型,更直白的就是一些cpp的class定义。
Module类,Module可以理解为一个完整的编译单元。一般来说,这个编译单元就是一个源码文件,如一个后缀为cpp的源文件。
Function类,这个类顾名思义就是对应于一个函数单元。Function可以描述两种情况,分别是函数定义和函数声明。
BasicBlock类,这个类表示一个基本代码块,“基本代码块”就是一段没有控制流逻辑的基本流程,相当于程序流程图中的基本过程(矩形表示)。
Instruction类,指令类就是LLVM中定义的基本操作,比如加减乘除这种算数指令、函数调用指令、跳转指令、返回指令等等。

LLVM IR入门指南 https://www.zhihu.com/column/c_1267851596689457152

LLVM IR入门指南(1)——LLVM架构简介
LLVM IR入门指南(2)——Hello world
LLVM IR入门指南(3)——数据表示
LLVM IR入门指南(4)——类型系统
LLVM IR入门指南(5)——控制语句
LLVM IR入门指南(6)——函数
LLVM IR入门指南(7)——异常处理

LLVM中的JIT https://zhuanlan.zhihu.com/p/60936932

JIT(just-in-time)即时编译技术是在运行时(runtime)将调用的函数或程序段编译成机器码载入内存,以加快程序的执行。所以,JIT是一种提高程序时间和空间有效性的方法。 程序运行时编译和执行的概念最早出自John McCarthy在1960年发表的论文《Recursive functions of symbolic expressions and their computation by machine》,James Gosling在1993年在关于Java的论文中使用了”JIT”这个术语。JIT可以分为两个阶段:在运行时生成机器码和在运行时执行机器码。其中,第一个阶段的生成机器码方式与静态编译并无本质不同,只不过生成的机器码被保存在内存中,而静态编译是在程序运行前将整个程序完全编译为机器码保存在二进制文件中。运行时 JIT 缓存编译后的机器码,当再次遇到该函数时,则直接从缓存中执行已编译好的机器。因此,从理论上来说,JIT编译技术的性能会越来越接近静态编译技术。