LLVM
- LLVM
- MLIR
-
- Tutorial
-
- [T1 Toy语言和对应的AST](#T1 Toy语言和对应的AST)
- [T2 产生基础的MLIR](#T2 产生基础的MLIR)
- [T3 高级语言特定分析和变换](#T3 高级语言特定分析和变换)
- [T4 用接口使用通用变换](#T4 用接口使用通用变换)
- [T5 部分下降低级方言的优化](#T5 部分下降低级方言的优化)
- [T6 下降到LLVM和CodeGeneration](#T6 下降到LLVM和CodeGeneration)
- [T7 给Toy增加复合类型](#T7 给Toy增加复合类型)
LLVM
LLVM官方的下载在github上,下载速度很缓慢,可以用tuna提供的二进制下载位置 。其中包括很多工具,比如格式检查工具clang-format,可以配置到VsCode里的LSP工具llvm-lsp。
windows
Debug
MLIR
Tutorial
官方提供了Tutorial代码,位于mlir的文件夹中,因此第一步需要跟随Get Started编译llvm项目。
T1 Toy语言和对应的AST
教程提供了使用递归下降算法实现的编译器,产生对应的AST。
T2 产生基础的MLIR
- 定义
Toy Operation,使用 CRTP风格继承mlir::Op - Op和Operation均和操作相关
Operation是不透明的op是Operation*的智能指针语法糖,可以通过LLVM的casting基础设施来得到llvm::dyn_cast<ConstantOp>(operation)
- 操作定义规格(ODS)框架
Toy_Op基础类型,可以把CRTP风格放入Toy_Op的模板中,后续的Op直接继承Toy_Op
T3 高级语言特定分析和变换
- 有两种方式可以实现 模式-对应的变换
- 命令式:使用C++
- 声明式:使用 声明重写规则(DRR),但是要和ODS搭配使用。
- 当前
clang无法优化临时数组,比如教程里举的两个transpose的叠加 - 在
Canonicalizationpass 中可以按照贪心递归的方式应用变换 - 命令式:使用
transpose作为例子- 需要在
include/toy/Ops.td文件中设置hasCanonicalizer=1,代表::getCanonicalizationPatterns()必须要被定义;[Pure]特性trait可以去除死代码; ::getCanonicalizationPatterns()函数中注册新的patter到Canonicaliztionpass中- 在PassManager中的Func层级增加优化pipeline:
pm.addNestedPass<mlir::toy::FuncOp>(mlir::createCanonicalizerPass())
- 需要在
- 声明式:使用
reshape- 在
mlir/ToyCombine.td定义 - 编译后产生
ToyCombine.inc - 可以增加条件判断
Constraint<>,调用c++函数NativeCodeCall
- 在
T4 用接口使用通用变换
上一节中使用的注册方式扩展性不好,接口可以提供更通用的方式。这一节介绍通过内联和形状传播进行形状推导。
- 内联:把所有操作放在一个函数内,为下一步的过程内形状传播做准备
- 用
operation interface来标记操作call-like或者callable-like。toy.generic_call是调用toy.func是函数. FuncOp的traits包含了FucntionOpInterface,继承自CallableOpInterface;GenericCallOp包含DeclareOpInterfaceMethods<CallOpInterface>pm.addPass(mlir::creawteInlinePass())
- 用
- 过程内(intraprocedural)形状传播
- 使用ODS框架定义
ShaperInferenceOpInterface - 继承了
ShpaeInferenceOpInterface的Op均需要定义ShapeInferenceOpInterface里定义的函数inferShapes - 构造
ShapeInferencePass并定义runOnOperation - 注册Pass
pm.addPass
- 使用ODS框架定义