LLVM最初设计时,主要做优化方面的研究,所以当时的全称叫Low Level Virtual Machine。后来因为成为了编译器,官方放弃了这个称呼,但保留了LLVM的简称。
官网:
http://llvm.org/
代码:
https://github.com/llvm/llvm-project
LLVM的主要作者是Chris Lattner。
他的个人主页:
http://nondot.org/sabre/
Chris Lattner,1978年生,美国人。University of Portland本科(2000)+UIUC博士(2005)。LLVM、Swift、MLIR的作者。先后任职于Apple、Tesla、Google、SiFive。
架构设计:
http://www.aosabook.org/en/llvm.html
顺便提一下,这个网站本身就是个宝库。
架构设计中文版:
https://zhuanlan.zhihu.com/p/446800631
https://getting-started-with-llvm-core-libraries-zh-cn.readthedocs.io/zh-cn/latest/index.html
Getting Started with LLVM Core Libraries(中文版)
LLVM主要专注于后端的代码生成。Chris Lattner还开发了前端项目clang。LLVM早期使用GCC作为前端,目前已经改为clang。
https://zhuanlan.zhihu.com/p/357803433
详解三大编译器:gcc、llvm和clang
mkdir build && cd build
cmake -G Ninja ../llvm \
-DCMAKE_INSTALL_PREFIX=/mlir-tutorial/install \
-DLLVM_ENABLE_PROJECTS=mlir \
-DLLVM_BUILD_EXAMPLES=ON \
-DLLVM_TARGETS_TO_BUILD="Native;NVPTX;AMDGPU" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=ON
ninja -j 0
https://inside-compiler.github.io/2023/12/14/Build-LLVM/
Build LLVM
官方教程:
https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/index.html
教程代码在:
llvm/examples/Kaleidoscope
教程中文版+MLIR的专栏:
https://www.zhihu.com/column/c_1416415517393981440
Kaleidoscope示例的可执行文件路径:
build/examples/Kaleidoscope
参考:
https://zhuanlan.zhihu.com/p/407854583
使用LLVM实现一个简单编译器(一)
https://zhuanlan.zhihu.com/p/409749393
使用LLVM实现一个简单编译器(二)
C源码转换为LLVM IR:
clang -emit-llvm -S test.c -o test.ll
LLVM IR转换为LLVM字节码:
llvm-as test.ll -o test.bc
链接LLVM字节码文件:
llvm-link test1.bc test2.bc -o output.bc
LLVM字节码转换为机器汇编码:
llc test.bc -o test.s
优化器opt,优化LLVM IR:
opt --passname input.ll -o output.ll
JIT执行字节码:
lli hello.bc
反汇编:
llvm-dis < hello.bc
.c –frontend–> AST –frontend–> LLVM IR –LLVM opt–> LLVM IR –LLVM llc–> .s Assembly –OS Assembler–> .o –OS Linker–> executable
https://zhuanlan.zhihu.com/p/161626997
LLVM架构简介
https://blog.csdn.net/weixin_46222091/article/details/104501879
llvm常用工具的使用详解
https://llvmflow.kc-ml2.com/
一个LLVM的可视化工具
ADT(Abstract Data Type)是LLVM定义的一套高级数据类型。
https://inside-compiler.github.io/2024/02/02/ADT-Overview/
ADT-概述
LLVM tablegen,文件名后缀为.td
。
(`reset` $reset^)?
,其中(...)?
表示分组,^
表示判断依据。只有对应的Optional
或UnitAttr
存在的时候,才会输出这个分组。
https://zhuanlan.zhihu.com/p/447318642
TableGen_Overview
https://zhuanlan.zhihu.com/p/447728683
TableGen Language Reference
https://blog.llvm.org/posts/2023-12-07-tools-for-learning-llvm-tablegen/
Tools for Learning LLVM TableGen
https://zhuanlan.zhihu.com/p/141265959
有关于TableGen的简单介绍
FileCheck用于校验输出结果中是否包含期望的信息。
https://blog.csdn.net/weixin_46222091/article/details/104527715
LLVM中FileCheck开发者工具 1–命令介绍
https://blog.csdn.net/weixin_46222091/article/details/104528256
LLVM中FileCheck开发者工具 2–入门教程
与其他系统不同,LLVM并不坚持一种错误的观念,即一套优化适用于所有语言和所有情况。LLVM允许编译器实现者完全决定使用哪些优化、以何种顺序以及在什么情况下使用。
https://llvm.org/docs/Passes.html
常用pass列表
Pass主要分为三类:
Transform Pass:用于变换IR。
Analysis Pass:分析IR给Transform Pass使用。
Utility Pass:辅助调试的Pass,例如打印CFG。
Pass的管理由相应的PassManager负责,例如FunctionPassManager。
PassBuilder用于注册Transform Passes所使用的Analysis Pass:
TheMAM = std::make_unique<ModuleAnalysisManager>();
PassBuilder PB;
PB.registerModuleAnalyses(*TheMAM);
所谓的intrinsic function,是属于编译器开洞魔法的范畴,这些函数的实现是直接写死在编译器的代码生成部分的,在最终得到的二进制里面不会存在这些函数的符号和实现。
https://zhuanlan.zhihu.com/p/348365662
C++标准库开洞史
https://www.zhihu.com/question/569519423
C++标准库中是否有需要依赖编译器魔法才能实现的功能?
https://www.zhihu.com/question/582148351
C/C++函数“必须声明但禁止定义”才能使用,函数地址也不存在,是什么神奇的操作?
llvm IR能跨ISA,但不能跨OS。
https://www.zhihu.com/question/663199568
为什么llvm的字节码没作为一种跨平台手段流行起来?
https://mp.weixin.qq.com/s/FSlJKnC0y51nsLDp1B3tXg
Swift编译器Crash—Segmentation fault解决方案
https://zhuanlan.zhihu.com/p/392381317
LLVM IR的第一个Pass:上手官方文档Hello Pass
https://csstormq.github.io/
一个LLVM、TVM、NEON的专栏
https://www.zhihu.com/question/484069566
LLVM怎么表达硬件相关的特性?
https://mp.weixin.qq.com/s/-IjJJG5huL6p3KjhO70s7Q
编译器中的图论算法
https://zhuanlan.zhihu.com/p/140462815
LLVM基本概念入门
https://zhuanlan.zhihu.com/p/502828729
LLVM创始人Chris Lattner回顾展望编译器
https://zhuanlan.zhihu.com/p/626085010
使用Flex、Bison和LLVM编写自己的Toy Compiler
https://zhuanlan.zhihu.com/p/66793637
A Tour to LLVM IR(上)
https://zhuanlan.zhihu.com/p/66909226
A Tour to LLVM IR(下)
Multi-Level IR
代码:
llvm/mlir
教程:
llvm/mlir/docs/Tutorials/Toy
Affine Dialect:这种Dialect使用来自多面体编译的技术使依赖分析和循环转换高效可靠。
GPU Dialect:MLIR中的GPU Dialect模拟了类似于CUDA或OpenCL的通用GPU编程范式。它的目标是提供抽象来模拟GPU特定的操作和属性。它在很大程度上意味着与供应商无关。
Tensor Operator Set Architecture (TOSA) Dialect
Vector Dialect:对SIMD或者SIMT模型的抽象。
SCF(Structured Control Flow) Dialect:比控制流图CFG更高层的抽象,比如并行的for和while循环以及条件判断。
Async Dialect:通常用来表示异步操作模型。
Control Flow Graph, CFG
Operation Definition Specification, ODS
文档:
https://mlir.llvm.org/docs/Dialects/
参考:
https://discourse.llvm.org/t/codegen-dialect-overview/2723
Codegen Dialect Overview
Transform Dialect:dialect之间的调度变换都可以使用transform dialect中相关的语句来实现了,最终写成一个transform.sequence。相较于完整的Pipeline,transform.sequence实现的调度变换十分灵活。
官方文档:
https://mlir.llvm.org/docs/Tutorials/transform/
参考:
https://zhuanlan.zhihu.com/p/624827690
transform dialect
ONNX MLIR:
http://onnx.ai/onnx-mlir
Torch-MLIR
https://github.com/llvm/torch-mlir
TorchScript–>TorchDialect–>Linalg-on-Tensors
https://blog.csdn.net/HaoBBNuanMM/article/details/124385542
Torch-MLIR技术详解
MLIR是树形结构,每个节点是Operation,Op可以组成Block,Block组成Region,而Region又可以嵌套在Op内部。
Operation指单个运算,运算内可以嵌套Region。
Block指基本块,基本块包含一个或多个Operation。
Region指区域,类似于循环体或函数体,包含若干Block。Region类似于C语言的作用域,Region内可定义局部变量。
#map = affine_map<(m, n, k) -> (m, k)>
#map1 = affine_map<(m, n, k) -> (k, n)>
#map2 = affine_map<(m, n, k) -> (m, n)>
module {
func.func @main(%arg0: tensor<10x64xf32>, %arg1: tensor<64x16xf32>) -> tensor<10x16xf32> {
%0 = tensor.empty() : tensor<10x16xf32>
%1 = linalg.generic {indexing_maps = [#map, #map1, #map2], iterator_types = ["parallel", "parallel", "reduction"]} ins(%arg0, %arg1 : tensor<10x64xf32>, tensor<64x16xf32>) outs(%0 : tensor<10x16xf32>) {
^bb0(%in: f32, %in_0: f32, %out: f32):
%2 = arith.mulf %in, %in_0 : f32
%3 = arith.addf %out, %2 : f32
linalg.yield %3 : f32
} -> tensor<10x16xf32>
return %1 : tensor<10x16xf32>
}
}
上例是一个matmul算子的MLIR,linalg.generic
表示了该指令属于linalg dialect。
Basic block指的是没有分支的代码序列,它使用^
作为开头。
使用LLDB调试:
https://mlir.llvm.org/getting_started/Debugging/
插件:
https://github.com/llvm/llvm-project/blob/main/llvm/utils/lldbDataFormatters.py
https://github.com/llvm/llvm-project/blob/main/mlir/utils/lldb-scripts/mlirDataFormatters.py
您的打赏,是对我的鼓励