MLIR多层中间表示——用MLIR构建编译器(下)
方言下译到LLVM!
走向CodeGen
让Toy可执行!
MLIR没有目标程序集的代码生成器。。。
幸运的是,LLVM做到了!在MLIR中有一种LLVM方言。
方言、下译、转换框架
I / O
Toy Lang->Toy AST
以下是在本教程中构建的系统的完整端到端图片。
蓝色的盒子和箭头是具体建造的。
绿框和箭头已经存在于MLIR中,刚刚连接到它们。
方言、下译、转换框架
以下是在本教程中构建的系统的完整端到端图片。
蓝色的盒子和箭头是具体建造的。
绿框和箭头已经存在于MLIR中,刚刚连接到它们。
方言、下译、转换框架
以下是在构建的系统的完整端到端图片。
蓝色的盒子和箭头是具体建造的。
绿框和箭头已经存在于MLIR中,刚刚连接到它们。
方言、下译、转换框架
以下是在本教程中构建的系统的完整端到端图片。
蓝色的盒子和箭头是具体建造的。
绿框和箭头已经存在于MLIR中,刚刚连接到它们。
方言、下译、转换框架
以下是在构建的系统的完整端到端图片。
蓝色的盒子和箭头是具体建造的。
绿框和箭头已经存在于MLIR中,刚刚连接到它们。
方言、下译、转换框架
以下是在构建的系统的完整端到端图片。
蓝色的盒子和箭头是具体建造的。
绿框和箭头已经存在于MLIR中,刚刚连接到它们。
方言转换中的降格
● 将一组源方言转换为一个或多个合法目标方言
○ 目标方言可能是源方言的子集
● 三个主要组成部分:
○ 转换目标:
■ 说明哪些运算是合法的以及在什么情况下
○ 运算转换:
■ Dag-Dag模式指定如何将非法运算转化为合法运算
○ 类型转换:
■ 如何将非法类型转换为合法类型的规范
● 两种模式:
○ 部分:并非所有输入运算都必须对目标合法化
○ 完整:所有输入运算都必须对目标合法化
Dialect Conversion: ConversionTarget
//首先要定义的是转换目标。这将确定此次下降的最终目标。
mlir::ConversionTarget target(getContext());
Dialect Conversion: ConversionTarget
Dialect Conversion: ConversionTarget
方言转换:运算转换
方言转换:运算转换
方言转换:运算转换
方言转换:运算转换
https://mlir.llvm.org/docs/Tutorials/Toy/Ch-5/#partial-lowering
● 模式是通过OwningRewritePatternList收集的
现在已经定义了转换目标,只需要提供一组下译Toy运算的模式。
mlir::OwningRewritePatternList patterns;
patterns.insert<..., TransposeOpLowering>(&getContext());
方言转换:运算转换
● 如果不是明确非法的,现有运算可能无法合法化
● 允许在不了解整个IR的情况下转换已知非法运算的子集
void ToyToAffineLoweringPass::runOnFunction() {
...
// 定义了目标模式和重写模式后,现在可以尝试转换。如果任何非法运算未成功转换,则转换将发出失败信号。
FuncOp function = getFunction();
if (mlir::failed(mlir::applyPartialConversion(
function, target, patterns)))
signalPassFailure();
}
方言转换:运算转换
func @main() {
%0 = toy.constant() { value: dense<tensor<4xf64>, [1., 2., 3., 4.]> }
: () -> tensor<4xf64>
%1 = toy.transpose(%0) : (tensor<2x2xf64>) -> tensor<2x2xf64>
%2 = toy.mul(%1, %1) : (tensor<2x2xf64>, tensor<2x2xf64>) -> tensor<2x2xf64>
toy.print(%0) : (tensor<2x2xf64>) -> ()
toy.return() : () -> ()
}
部分降与仿射优化
https://mlir.llvm.org/docs/Tutorials/Toy/Ch-5/#taking-advantage-of-affine-optimization
将MLIR LLVM方言导出为LLVM IR
https://mlir.llvm.org/docs/Tutorials/Toy/Ch-6/
从LLVM方言到LLVM IR的映射:
auto llvmModule = mlir::translateModuleToLLVMIR(module);
LLVM方言:
%223 = llvm.mlir.constant(2 : index) : !llvm.i64
%224 = llvm.mul %214, %223 : !llvm.i64
LLVM IR:
%104 = mul i64 %96, 2
参考文献链接
https://llvm.org/devmtg/2020-09/slides/MLIR_Tutorial.pdf